CSC 321.01, Class 02: Getting started with Ruby
Overview
- Preliminaries
- Notes and news
- Upcoming work
- Good things to do
- Questions
- A brief introduction to Ruby
- Some exercises
- Duck typing
- Additional characteristics of Ruby
News / Etc.
- Welcome to day two of CSC 321!
- Yes, I will take attendance.
- Today and Thursday, we will continue to explore the wonders of Ruby.
- Your mentor will be giving up some class time to have evening mentor sessions (increasingly so as the first half of the semester continues).
- I’m still working on the course Web site.
- Yes, I know the assignments were time-consuming. But we want you to practice getting up to speed quickly. I’m limiting the work for Thursday.
- Some concerns and comments
- If I’m going to use your reading journals to prepare class, I really do need them in on time. (That’s my fault for not giving a clear due time.) They will be due at 8 p.m.
- When I write “Email your ids for the various services to the mentor and to me”, that means you should send it to both of us.
- Please follow the instructions for giving titles to email messages. You should know why.
- Reminder: Self Gov your workspace
Upcoming Work
Good things to do
Academic
- Community time today at 11:00 am in JRC 101.
- CS Table today in the Whale Room.
- CS Extras Thursday at 4:15 pm.
- Rosenfield Symposium next week.
Peer
- ???
Questions
A brief introduction to Ruby
- Computer scientists and computer programmers are passionate and opinionated about their programming languages.
- Two models:
- Programming languages are designed to help competent programmers get their work done as quickly as possible.
- Programming languages are designed to help competent programmers get their work done as correctly as possible.
- Model two: Think about Java
-
At compile time, Java checks carefully to make sure that what you are doing is legal.
public class Foo { int foo() { return 1; } } public class Bar extends Foo { int bar() { return 0; } } … public Foo f; f = new Bar(); // Does the object that f refers to have a
barmethod? Yes. // Can I use that method blithly? System.out.println(f.bar()); -
“Java is your nanny”
-
- Model one: We know what we’re doing. Having to deal with those complaints just slows us down. (When we want to know about possible problems, we’ll run a “look for problems” program.)
- Type theory snobbery says: We can protect programmers without getting in their way. But type theory snobs have lost lots of oxygen to their brain due to traingle holds.
- Ruby (and much of agile) comes from the “trust the programmer world”
- There are also different paradigms (ways of thinking about how you
express algorithms): functional, imperative, object-oriented, (declarative)
- In functional programming - think in terms of functions - as first-class value (inputs to other functions, outputs from other functions); functions are pure - given the same input you get the same output
- In imperative programming, we think about explicit sequences of steps and the state of the system
- In object-oriented programming, we think about objects (things
that have both methods and state) along with three core ideas
of object-oriented programming: inheritance, encapsulation, and
polymorphism.
- Inheritance lets us define new objects or new classes in terms of other objects or classes.
- Enapsulation lets you deal with the complexities of state by hiding the state of your object from your clients.
- Encapsulation lets you group related things (data and the methods applicable to those data) into a single whole.
- Polymorphism lets you write general functions (or types) that
can be applied to a wide variety of values, provided they meet
some specification.
- I can write a
doubleprocedure that will work with any object that knows how to add to elements of the same type. - I can write a
HomogeneousList<T>class that will represent homogeneous lists of any underlying type. - I can write a
SortedList<T>class that will represent lists that are stored in order from least to greatest, provided that T is a class that provides a compareTo(T) method.
- I can write a
- Ruby, like most modern languages, embodies/includes all three paradigms. Ruby’s core umwelt is object-oriented.
- Ruby is interesting, in part, because it has a single primary designer, Matsumoto.
- Ruby is very popular
- Programmers like the “I can write what I want, quickly” model.
- Ruby on Rails.
- Way too multi-expressive. We have two numbers, a and b. In the
cases in which b is strictly larger than a, print “Hello”
if a < b then puts "Hello" endputs "Hello" if a < bputs "Hello" unless b <= aunless b <= a [some syntax that Sam doesn't use] puts "Hello"
- Wow, that’s a pain because it becomes harder to read. Given four programmers, you’ll find five different approaches to doing the same thing, and that adds cognitive load.
- Wow, that’s awesome because it gives you a lot of options and lets you match how you might say things in English
- Lets us match the other langauges we think in.
- More variations - More chance that you’ll remember one
- Or if you’re Sam, you’ll remember one incorrectly.
Some exercises
We will explore the ways in which you solved some of the problems from the SaaSbook. Explain your high-level approach and then the details.
sum_to_n?
Define a method sum_to_n?(array, n) that takes an array of integers
and an additional integer, n, as arguments and returns true if any
two elements in the array of integers sum to n. sum_to_n?([], n)
should return false for any value of n, by definition.
- Contextual question one: What is
sums_to_n?([2,3],4)? - false
- Contextual question one: What is
sums_to_n?([2,2],4)? - true
Contextual question two: What are some other “interesting” inputs?
What is the time and space overhead of each?
Strategy one: Nested loops
- Outer loop: For each index
- Inner loop: For each subsequent index
- Time efficiency: O(n^2)
- Space efficiency: O(n) for the arrays (given to us); O(1) for the additional values.
Strategy two: Nested loops, with additional stuff
- Outer loop: For each value
- Inner loop: Clone of the array, remove elements, for each
- Time complexity: O(n^2)
- Space complexity: O(n)
Detour
- How would you implement array.drop(k), which returns an array like the original but without the first k elements? (If you were in a pure language? If you were in an impure language? If you could define the semantics?)
- O(1) or in between or O(n) or worse
Option 1
- Create a new array
- Copy over elements
- Space: O(n-k)
- Time: O(n-k)
Option 2
- Return something like what you get from
arr+kin C. - That is, it refers to a subset of the memory allocated to arr.
- Space: O(1)
- Time: O(1)
Strategy 3:
- Sort the array
- Start at the two ends, moving inward, and checking pairs
- Running time O(sort + n), which is almost certainly O(nlogn)
Strategy 4:
- Make all pairs
- Add all pairs
- See if any of them equal the desired sum, using find.
- About two lines of Ruby!
- Making all pairs might by O(n^2)
Code
def sums_to_n? arr, n
arr.combinations(2).find({|x,y| x + y == n})
end
This, to me, is like the inner product you should write in Scheme.
Inner product: Given two lists, A and B, of the same length, compute a0b0 + a1b1 + a2*b2 ….
(reduce + (map * A B))
Short code
- Is likely to have fewer mistakes
- May be clearer
- Is likely faster to write
- Makes assumptions about efficiency of underlying operations
binary_multiple_of_4?
Define a method binary_multiple_of_4?(s) that takes a string
and returns true if the string represents a binary number that is a
multiple of 4. NOTE: be sure it returns false if the string is not a
valid binary number!
Solution 1
def binary_mutiple_of_4?
return false if s == "0"
return s.to_i % 4 == 0
end
Solution 2
def binary_multiple_of_4?
return false if s.length==0 || s.match(/[^01]/);
s.to_i(2) == 0
end
Solution 3
def binary_multiple_of_4? s
last = s.length - 1
i = 0
until i == last
if (s[i] != "0") && (s[i] != "1")
return false
end
i += 1
end
return s.end_with?("00")
end
Solution 4
def binary_multiple_of_? s
n = 0
for i in 0..s.length
if (s[i] != '0' && s[i] != '1')
return false
end
n *= 2
n += s[i].to_i
end
return n%4 == 0
end
Duck typing
Not covered
Additional characteristics of Ruby
Not covered