# CSC 321.01, Class 02: Getting started with Ruby

Overview

• Preliminaries
• Notes and news
• Upcoming work
• Extra credit
• Questions
• Reflections on the assignment

## Preliminaries

• Some of you are getting check-minus grades on the assignment.
• For assignments, that will still count as a 90. (You should not get lower than the timebox value, provided that it’s clear that you’ve put in an appropriate level of effort and time.)
• For journals, that will count lower.
• Today is the last day to fill out the data buddies survey https://cerp.co1.qualtrics.com/jfe/form/SV_3UH7q6TmdZ8YRPD. Surveys are more meaningful if we get higher participation.

### Good things to do (Academic)

• Convocation Thursday at 11 in JRC 101: Democracy at the Roots: Culture and Sovereignty in Haiti
• CS extras Thursday: Summer research opportunities in CS.

### Questions

About how long is the typical question response in a journal entry?
A paragraph. So, say, 50-100 words.

## Reflections on the assignment

In reading your responses, I see that there are still some significant confusions. We’re going to talk through them.

• Most of you need to work on clear and precise writing. Some of you need to work on grammar. While this is not an essay class, I do expect that you will write well when you write for me.
• Some of you were worried about the amount of time you spent. “Approximately five hours” does include six hours.

### Chomping and more

Three versions

# v1
text = gets
text.chomp!
text.downcase!

# v2
text = gets.chomp
text.downcase!

# v3
text = gets.chomp.downcase

* chomp is a pure operation.  It returns a new string.
* chomp! is a mutator.  It changes the underlying string.
* downcase is a pure operation.  It returns a new string.
* downcase! is a mutator.  It changes the underlying string.

Some questions

* What do you think happens if we give downcase a string that is
already lowercase?  Does it give you the same string or a
copy?
* A copy.
* Why?  So that we can change the two independently.
* What value do we get from downcase! if the string is already
lowercase?  It doesn't change the string, but what does it
return?
* nil.
* Why?  Provides a signal to the caller.  The primary goal
is to mutate the string.  We return nil to say "No changes
necessary"  We return the string to say "Changed!"
* Although it may be tempting to write
text = gets.chomp!.downcase!, you can't.
* Why use strategy 1? (Sequence of side-effecting operations)
* Might want to reuse
* Saves memory!
* Some people like the clarity of "one instruction per line"
* Why use strategy 3? (Chained pure operations)
* Concise and clear; saves programmer conceptual time
* May help avoid problems (e.g., I mistyped a variable name)
* We might actually want all three versions (although this
form doesn't give it to us)

text1 = gets
text2 = text1.chomp
text3 = text2.downcase

* Why use strategy 2? (What the Tutorial uses)
* A good middle ground.
* No one really wants the one with the newline.

### Redaction

* Most of you figured out that gsub is the way to go.
* But it's complicated.
* You don't want to use text.gsub(redact, "REDACTED").
* Why not?
* The redacted thing can appear *within* a word



irb(main):008:0> text = “concatenate those cats, catherine!” => “concatenate those cats, catherine!” irb(main):009:0> redact = “cat” => “cat” irb(main):010:0> text.gsub(redact,”READACTEASDFDA”) => “conREADACTEASDFDAenate those READACTEASDFDAs, READACTEASDFDAherine!” irb(main):011:0> text => “concatenate those cats, catherine!”


_Conclusion: Sam should have been nicer on grading this one._

### Hash tables



frequencies = frequencies.sort_by {|a, b| b }


* A hash table is an array of key-value pairs (or, more frequently,
lists of key-value pairs)
* We run a hash function on the key, mod by the table size, and
add to that bucket in the array.
* Given that hash tables are necessarily stored according to hash value,
it makes no sense to think of sorting a hash table in place.
* What might sort therefore do?
* We could have a separate sorted list of keys for when we want
to iterate.
* sort could return a list of key/value pairs that are sorted by
the key.  (That's what Ruby does)
* Sam thinks that any sensible language would disallow this.
* Before assignment statement, frequencies is a hash
* After assignment statement, frequencies is a list of pairs

### Superclass constructor

* Most of you noted that we can use super to call the parent's constructor.
(You can also use super in other cases; it normally means "the procedure
with the same name in my parent")
* There is one other case in which the parent's constructor is called: If
you don't define a constructor for the class.



def get_rating begin puts “Enter movie rating: “ rating = gets.chomp
rating = rating.to_i puts “Please enter a rating between 0 and 10” if rating < 0 || rating > 10 end while rating < 0 || rating > 10 return rating end


* We might use rating = gets.chomp.to_i.
* The indentation is wrong!
* Uses a structure we don't know.
* Logic issue.  Any non-number will give 0.
* Positive: Nice refactoring
* Potential UI issue: If I enter 3.5, it does not store 3.5 and I
don't know that.

### Mixins

_Nope, we didn't get this far.  We might on Monday or Wednesday._

Why don't I like the following code?  (Apologies to the author.)



module Action def jump @distance += rand(4) + 2 puts “I jumped forward #{@distance} feet!” end end

class Rabbit include Action attr_reader :name def initialize(name) @name = name @distance = 0 end end

class Cricket include Action attr_reader :name def initialize(name) @name = name @distance = 0 end end


This code "fixes" that problem, but introduces another problem.  What is it?



module Action @@total_distance = 0 def jump @distance = rand(4) + 2 puts “I jumped forward #{@distance} feet!” end

def total_distance total_distance = @@total_distance + @distance end end

class Rabbit include Action attr_reader :name def initialize(name) @name = name end end

class Cricket include Action attr_reader :name def initialize(name) @name = name end end


This code fixes that problem, but introduces another.  Can you tell what
it is?  (You may not be able to tell from inspection.)



Module Action @overall_dist = 0

def jump @distance = rand(4) + 2 @overall_dist += @distance puts “I jumped forward #{@distance} feet!” end end

class Rabbit include Action attr_reader :name def initialize(name) @name = name end end

class Cricket include Action attr_reader :name def initialize(name) @name = name end end `