Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSCE 431 Software Engineering

Similar presentations


Presentation on theme: "CSCE 431 Software Engineering"— Presentation transcript:

1 CSCE 431 Software Engineering
Philip Ritchey slides generously gifted by Jeff Huang

2 Software as a Service (Engineering Software as a Service §1.2)
Very popular topics Rent like using doing your laundry in a service (Engineering Software as a Service §1.2)

3 A Few Years Ago

4 Software Targets Traditional SW: binary code installed and runs wholly on client device, which users must upgrade repeatedly Must work with many versions of hardware, OS New versions must go through extensive release cycle to ensure compatibility Alternative: develop SW that only needs to work on one HW & OS platform?  Quicker release cycle, no user upgrades?

5 Software as a Service: SaaS
SaaS delivers SW & data as service over Internet via thin program (e.g., browser) running on client device Search, social networking, video Now also SaaS version of traditional SW E.g., Microsoft Office 365, TurboTax Online Instructors think SaaS is revolutionary, the future of virtually all software May change SW industry by end of decade, switch of leaders and followers

6 6 Reasons for SaaS No install worries about HW, OS
No worries about data loss (data is remote) Easy for groups to interact with same data If data is large or changes frequently, simpler to keep 1 copy at central site 1 copy of SW, single HW/OS environment => no compatibility hassles for developers => beta test new features on 1% of users 1 copy => simplifies upgrades for developers and no user upgrade requests Is laptop backed up? Lose my cellphone? 6 means SW changes all the time with more features Continuosly being asked to upgrade my software on my laptop

7 SaaS Loves Rails Many frameworks/languages for SaaS
Django/Python, Zend/PHP, Spring/Java We use Ruby on Rails (“Rails”) Rails popular programming framework that uses Ruby – e.g., Twitter Ruby, a modern scripting language: object oriented, functional, automatic memory management, dynamic types, reuse via mix-ins & closures, synthesis via metaprogramming Dozens of options, Why Rails designer picked Ruby

8 Why Take Time for Ruby/Rails?
14 weeks to learn: SaaS, Agile, Pair Programming, Behavior Driven Design, LoFi UI, Storyboards, User Stories, Test Driven Development, Enhance Legacy Code, Scrum, Velocity, JavaScript, Design Patterns, Deployment, Security You only work part-time on this class Only hope is highly productive language, tools, framework: Rails currently the best See “Crossing the Software Education Chasm,” A. Fox, D. Patterson, Comm. ACM, May 2012 3 weeks full time SW Engineer – lifelong learning

9 Overview & Intro to Ruby
(Engineering Software as a Service §3.1)

10 Ruby is... Interpreted Object-oriented
Everything is an object Every operation is a method call on some object Dynamically typed: objects have types, but variables don’t Dynamic add, modify code at runtime (metaprogramming) ask objects about themselves (reflection) in a sense all programming is metaprogramming reflection and metaprogramming often used together it's always runtime, so ALL programming is metaprogramming – even loading a class causes code to be executed.

11 Where Ruby Fits Dynamically Typed Statically Typed Functional
JavaScript/Racket SML/Haskell Object-Oriented (OOP) Ruby Java/C++ Dynamically typed OOP helps identify OOP's essence by not having to discuss types

12 Online Materials Ruby Documentation Ruby Learning Tutorial
ruby-doc.org Ruby in twenty minutes: Ruby Learning Tutorial Try Ruby Online

13

14

15 Methods Everything (except fixnums) is pass-by-reference
def foo(x,y) return [x,y+1] end def foo(x,y=0) # y is optional, 0 if omitted [x,y+1] # last exp returned as result def foo(x,y=0) ; [x,y+1] ; end Call with: a,b = foo(x,y) or a,b = foo(x) when optional arg used Fixnum – integer values small enough to fit into a machine word, always passed by value

16 Naming Conventions ClassNames use UpperCamelCase
class FriendFinder ... end methods & variables use snake_case def learn_conventions end def faculty_member? end def charge_credit_card! end CONSTANTS (scoped) & $GLOBALS (not scoped) TEST_MODE = true $TEST_MODE = true symbols: like immutable string whose value is itself favorite_framework = :rails :rails.to_s() == "rails" "rails".to_sym() == :rails :rails == "rails" # => false Symbols usually connote "specialness". One use is like an Enum in Java. Symbols – performance benefits Variables starting with $ are global, variables are instance variables, means class variables

17 Ruby Style Guide https://github.com/bbatsov/ruby-style-guide …
Use two spaces per indentation level (aka soft tabs). No hard tabs. Don't use ; to separate statements and expressions. As a corollary - use one expression per line. Use spaces around operators, after commas, colons and semicolons, around { and before }. The only exception, regarding operators, is the exponent operator (e = M * c**2) No spaces after (, [ or before ], ).

18

19 (Almost) Everything is an Object; Everything is a Method Call
Even lowly integers and nil are true objects: 57.methods 57.heinz_varieties nil.respond_to?(:to_s) Rewrite each of these as calls to send: Example: my_str.length => my_str.send(:length) 1 + 2 my_array[4] my_array[3] = "foo" if (x == 3) .... my_func(z) In particular, things like “implicit conversion” on comparison is not in the type system, but in the instance methods 1.send(:+, 2) my_array.send(:[], 4) my_array.send(:[]=, 3,"foo") if (x.send(:==, 3)) ... self.send(:my_func, z) Self is the current object. Ruby also includes non-objects in the form of keywords like if, class, alias, and begin, end, rescue. Some of these keywords provide control flow techniques; some, like alias, let you conduct business with the interpreter that affects the world in which your objects live. Non-object keywords Everything (really, everything!) evaluates to an object

20 REMEMBER! a.b means: call method b on object a
a is the receiver to which you send the method call, assuming a will respond to that method does not mean: b is an instance variable of a does not mean: a is some kind of data structure that has b as a member Understanding this distinction will save you from much grief and confusion

21 Variables, Arrays, Hashes
There are no declarations! local variables must be assigned before use instance & class variables ==nil until assigned OK: x = 3; x = 'foo' Integer x=3 (Valid Syntax, But No Need) Array: x = [1,'two',:three] x[1] == 'two' ; x.length==3 Hash: w = {'a'=>1, :b=>[2, 3]} w[:b][0] == w.keys == ['a', :b] Note, Array and hash elements can be anything, including other arrays/hashes, and don't all have to be same type. As in python and perl, hashes are the Swiss army chainsaw of building data structures.

22 Classes & Inheritance http://pastebin.com/m2d3myyP
class SavingsAccount < Account # inheritance # constructor used when SavingsAccount.new(...) called def initialize(starting_balance=0) # optional = starting_balance end def balance # instance # instance var: visible only to this object def balance=(new_amount) # note method name: like = new_amount def += amount = "MyBank.com" # class (static) variable # A class method def self.bank_name # note difference in method def # or: def SavingsAccount.bank_name ; ; end Self here refers to the current class, not an instance, since we are in the middle of defining a class.

23

24

25 Duck Typing (Engineering Software as a Service §3.7)
If it looks like a duck and it quacks like a duck, then it might as well be a duck.

26 So What If You’re Not My Type
Ruby emphasizes “What methods do you respond to?” over “What class do you belong to?” How does this encourage productivity through reuse?

27 What is “Duck Typing”? If it responds to the same methods as a duck...it might as well be a duck Similar to Java Interfaces but easier to use Example: my_list.sort [5, 4, 3].sort ["dog", "cat", "rat"].sort [:a, :b, :c].sort IO.readlines("my_file").sort NOT like C++ templates or Java overloading. Inside sort(), the only question is whether each element of the list responds to <=> method and whether it can compare itself against its neighbor element. Like C library “qsort” routine.

28 Modules Collection of methods that aren’t a class
you can’t instantiate it Some modules are namespaces, similar to Python: Math::sin(Math::PI / 2.0) Important use of modules: mix its methods into a class: class A ; include MyModule ; end A.foo will search A, then MyModule, then method_missing in A & MyModule, then A's super sort is actually defined in module Enumerable, which is mixed into Array by default The include method takes all the methods from another module and includes them into the current module. This is a language-level thing as opposed to a file-level thing as with require.

29 Making Accounts Comparable
Just define <=> and then use the Comparable module to get the other methods Now, an Account quacks like a Numeric 

30 When Module? When Class? Modules reuse behaviors
high-level behaviors that could conceptually apply to many classes Example: Enumerable, Comparable Mechanism: mix-in (include Enumerable) Classes reuse implementation subclass reuses/overrides superclass methods Mechanism: inheritance (class A < B) Remarkably often, we will prefer composition over inheritance John Ousterhout (former officemate) made this observation when developing Tcl/Tk and its predecessors.

31 Hashes & Poetry Mode Ruby idiom: “poetry mode”
h = {"stupid" => 1, :example => "foo" } h.has_key?("stupid") # => true h["not a key"] # => nil h.delete(:example) # => "foo" Ruby idiom: “poetry mode” using hashes to pass “keyword-like” arguments omit hash braces when last argument to function is hash omitting parentheses around function arguments link_to("Edit”,{:controller=>'students', :action=>'edit'}) link_to "Edit", :controller=>'students', :action=>'edit' link_to 'Edit', controller: 'students', action: 'edit' When in doubt, parenthesize defensively

32 Poetry Mode in Action a.should(be.send(:>=,7)) a.should(be() >= 7) a.should be >= 7 (redirect_to(login_page)) and return() unless logged_in? redirect_to login_page and return unless logged_in?

33 Which is not a legal call to foo():
def foo(arg,hash1,hash2) ... end Which is not a legal call to foo(): foo a, {:x=>1,:y=>2}, :z=>3 foo(a, :x=>1, :y=>2, :z=>3) foo(a, {:x=>1,:y=>2},{:z=>3}) Legal. Not legal. Looks like one arg, and one hash, when it should be 2 hashes. foo a, {:x=>1,:y=>2},{:z=>3}

34 DRY “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.” Andy Hunt and Dave Thomas, 1999 Don't Repeat Yourself (DRY) Don’t want to find many places have to apply same repair Refactor code so that it has a single place to do things Authors of Ruby and Agile Manifesto

35 Metaprogramming & Reflection
Reflection lets us ask an object questions about itself and have it modify itself Metaprogramming lets us define new code at runtime How can these make our code DRYer, more concise, or easier to read? (or are they just fancy words to make me look smart?) DRY == don’t repeat yourself

36 An International Bank Account
acct.deposit(100) # deposit $100 acct.deposit(euros_to_dollars(20)) acct.deposit(CurrencyConverter.new( :euros, 20)) Want beautiful code

37 An International Bank Account!
acct.deposit(100) # deposit $100 acct.deposit(20.euros) # about $25 No problem with open classes.... class Numeric def euros ; self * ; end end But what about acct.deposit(1.euro) gsub method substitutes the second string (null in this case) for all instances of the first string (“s” at end of currency name) Use missing_method:

38 The Power of method_missing
But suppose we also want to support acct.deposit(1000.yen) acct.deposit(3000.rupees) Surely there is a DRY way to do this? Use hash: Add the currency 'peso' with exchange rate 1 peso = dollars

39 The Power of method_missing
But suppose we also want to support acct.deposit(1000.yen) acct.deposit(3000.rupees) Surely there is a DRY way to do this? Use hash: Add the currency 'peso' with exchange rate 1 peso = dollars? Add the currency 'peso' with exchange rate 1 peso = dollars

40 Blocks, Iterators, Functional Idioms (Engineering Software as a Service §3.6)

41 If You Are Iterating with an Index, You Are Probably Doing It Wrong
Iterators let objects manage their own traversal (1..10).each do |x| ... end (1..10).each { |x| ... } 1.upto(10) do |x| ... end => range traversal my_array.each do |elt| ... end => array traversal hsh.each_key do |key| ... end hsh.each_pair do |key,val| ... end => hash traversal 10.times {...} # => iterator of arity zero 10.times do ... end These look different but are all examples of a common mechanism. Understand the mechanism and you won't have to worry about memorizing different-looking forms! Stuff between do…end or {…} is the iterator *block*. Variables in vertical bars are the parameters to the block

42 Ruby: “Expression-Oriented Programming”
x = ['apple','cherry','apple','banana'] x.sort # => ['apple','apple','banana','cherry'] x.uniq.reverse # => ['cherry','banana','apple'] x.reverse! # => modifies x x.map do |fruit| fruit.reverse end.sort # => ['ananab','elppa','elppa','yrrehc'] x.collect { |f| f.include?("e") } x.any? { |f| f.length > 5 } IMPORTANT QUESTION: how do these collection methods know the type of their receiver? ANSWER: it's all about what you respond to. it's a meritocracy: it's about what you can do, not what someone else has labeled you! FOLLOW-ON: how is comparison done in sort()? Map/collect iterates and produces an array of return values of block. Each does not produce an array.

43 The above code won’t run due to syntax error(s)
Which string will not appear in the result of: ['banana','anana','naan'].map do |food| food.reverse end.select { |f| f.match /^a/ } naan ananab anana The select method invokes the block on each element, returns array of elements *for which the block returns a value other than false or nil* The reverse of the elements will be ‘ananab’, ‘anana’, ‘naan’. The match will occur on ‘ananab’ and ‘anana’, but not ‘naan’. True False The above code won’t run due to syntax error(s)

44 Lambdas in Ruby A lambda is just a function, without a name

45 Summary: Ruby’s Distinguishing Features
Highly object-oriented everything is an object, even simple things like integers class, instance variables invisible outside class No multiple inheritance (but an alternative!) Everything is a method call usually, only care if receiver responds to method most “operators" (like +, ==) actually instance methods Dynamically typed: objects have types; variables don’t Expression-oriented: most methods nondestructive E.g., [array] + [array] returns new copy Exceptions: <<, some destructive methods (e.g. merge vs. merge! for hash) Idiomatically, {} and () sometimes optional

46 Homework 1 Due: 4 Jan def palindrome?
letter = self.downcase.gsub(/\W/,"") return letter == ( letter.reverse ) end def count_words array = self.downcase.strip.split(/\W+/) hashtable = Hash.new(0) array.each{|i| hashtable[i] = hashtable[i]+1} return hashtable def anagram_groups return self.split.group_by{|word| word.chars.sort}.values


Download ppt "CSCE 431 Software Engineering"

Similar presentations


Ads by Google