Saturday, April 16, 2016

Ruby on Rails_Lesson_Getting Started

1.Hello Rails I
Ruby on Rails is a web framework that makes it easy to build powerful web apps in a short amount of time.
Ruby on Rails is written in the Ruby programming language.
1.1.In the terminal, type 
$ rails new MySite
1.2. Then run
$ bundle install

1.3.Finally type

$ rails server

2.Hello Rails II
In three commands, you built a working Rails app that displays the Rails default page. How does it work?
  1. The rails new command created a new Rails app named MySite. It generated a number of files and folders that we will use to build the app. In the Code Editor, click on the folder icon to see these files and folders. We'll see what these files and folders are for in the next exercises. The rails new command is the starting point of every Rails project.
  2. The bundle install command installed all the software packages needed by the new Rails app. These software packages are called gems and they are listed in the file Gemfile.
  3. The rails server command started the Rails development server so that we could preview the app in the browser by visiting http://localhost:8000. This development server is called WEBrick.
3.Controller
What happens when you visit http://localhost:8000 in the browser? Check out the diagram in the browser.
  1. The browser makes a request for the URL http://localhost:8000.
  2. The request hits the Rails router in config/routes.rb. The router recognizes the URL and sends the request to the controller.
  3. The controller receives the request and processes it.
  4. The controller passes the request to the view.
  5. The view renders the page as HTML.
  6. The controller sends the HTML back to the browser for you to see.
This is called the request/response cycle. It's a useful way to see how a Rails app's files and folders fit together.

3.1.Looking at the request/response cycle, we need three parts to build a Rails app: a controller, a route, and a view. Let's start here by creating a controller.
In the terminal, type:

$rails generate controller Pages
3.2.After rails generate finishes running, in the Code Editor, open app/controllers/pages_controller.rb. Within the class PagesController, add a method home:

class PagesController < ApplicationController def home end end
4.Routes
We created a new controller named Pages. How did we do this?
  1. The rails generate controller Pages command generated a new controller named Pages. This created a file named app/controllers/pages_controller.rb.
  2. Inside the new Pages controller, we added a method called home. Methods in Rails controllers are also referred to as controller actions, so here we added the home action to the Pages controller.
4.1.Now that we have a controller, let's move on to the second part of the request/response cycle and create a route.
Open config/routes.rb and underneath line 1, type:
get 'welcome' => 'pages#home'
5.Views
Now when a user visits http://localhost:8000/welcome, the route
get 'welcome' => 'pages#home'
will tell Rails to send this request to the Pages controller's home action.
5.1.Now that we have a controller and a route, let's move on to the third part of the request/response cycle and create a view.
Open app/views/pages/home.html.erb, and type in the following HTML. Fill in your own name. 
<div class="main">
    <div class="container">
      <h1> Hello my name is Becky</h1>
    <p>I make Rails apps.</p>
  </div>
</div>
We've provided CSS in the file app/assets/stylesheets/pages.css.scss.
6.Generalizations
You built a Rails app from scratch. What can we generalize so far?
Using the request/response cycle as a guide, this has been our workflow when making a Rails app.
  1. Generate a new Rails app.
  2. Generate a controller and add an action.
  3. Create a route that maps a URL to the controller action.
  4. Create a view with HTML and CSS.
  5. Run the local web server and preview the app in the browser.



















Thursday, April 14, 2016

Ruby_Lesson_Object-Oriented Programming II

Information Hiding in Ruby
1.Need-to-Know Basis
Ruby allows you to explicitly make some methods public and others private. Public methods allow for an interface with the rest of the program; they say, "Hey! Ask me if you need to know something about my class or its instances."
Private methods, on the other hand, are for your classes to do their own work undisturbed. They don't want anyone asking them anything, so they make themselves unreachable!
3.Going Public
Methods are public by default in Ruby, so if you don't specify public or private, your methods will be public. In this case, however, we want to make it clear to people reading our code which methods are public. We do this by putting public before our method definitions, like so:
 class ClassName
  # Some class stuff
  public
  def public_method
    # public_method stuff
  end
end
Note that everything after the public keyword through the end of the class definition will now be public unless we say otherwise.For now, let's add a public method called bark to Dog. The bark method should puts "Woof!".
class Dog
    def initialize(name,breed)
        @name = name
        @breed = breed
    end
    public
    def bark
        puts "Woof!"
    end
end

4.Private! Keep Out!
Add a private method called id to Dog. The id method should create an @id_number instance variable and set it equal to 12345.
  private
    def id
        @id_number = 12345
    end

5.attr_reader, attr_writer











Ruby needs methods in order to access attributes. For instance, if we want to access a @name instance variable, we had to write something like
def name
  @name
end
Well, no longer! We can use attr_reader to access a variable and attr_writer to change it. If we write
class Person
  attr_reader :name
  attr_writer :name
  def initialize(name)
    @name = name
  end
end
Ruby does something like this for us automatically:
def name
  @name
end

def name=(value)
  @name = value
end
Like magic, we can read and write variables as we please! We just pass our instance variables (as symbols) to attr_reader or attr_writer.
(That name= might look funny, but you're allowed to put an = sign in a method name. That's just a Ruby convention saying, "hey, this method sets a value!")
class Person
  def initialize(name, job)
    @name = name
    @job = job
  end
 
  def name
    @name
  end
 
  def job=(new_job)
    @job = new_job
  end
end

We've brought back our Person class with a method for getting @name and a method for changing his or her @job. Go ahead and remove the name and job= methods and add an attr_reader for :name and an attr_writer for :job.
class Person
  def initialize(name, job)
    @name = name
    @job = job
  end
  attr_reader :name
  attr_writer :job
end

6.attr_accessor
If we want to both read and write a particular variable, there's an even shorter shortcut than using attr_reader and attr_writer. We can use attr_accessor to make a variable readable and writeable in one fell swoop.
Here we have an attr_reader and an attr_writer for :job. Go ahead and replace these with an attr_accessor!
attr_accessor :job
Introduction to Modules
7.What's a Module?
You can think of a module as a toolbox that contains a set methods and constants. There are lots and lots of Ruby tools you might want to use, but it would clutter the interpreter to keep them around all the time. For that reason, we keep a bunch of them in modules and only pull in those module toolboxes when we need the constants and methods inside!
You can think of modules as being very much like classes, only modules can't create instances and can't have subclasses. They're just used to store things!
module Circle
  PI = 3.141592653589793 
  def Circle.area(radius)
    PI * radius**2
  end 
  def Circle.circumference(radius)
    2 * PI * radius
  end
end

8.Module Syntax
module ModuleName
  # Bits 'n pieces
end
Like class names, module names are written in CapitalizedCamelCase, rather than lowercasewithunderscores.
It doesn't make sense to include variables in modules, since variables (by definition) change (or vary). Constants, however, are supposed to always stay the same, so including helpful constants in modules is a great idea.
Ruby doesn't make you keep the same value for a constant once it's initialized, but it will warn you if you try to change it. Ruby constants are written in ALL_CAPS and are separated with underscores if there's more than one word.
An example of a Ruby constant is PI, which lives in the Math module and is approximately equal to 3.141592653589793.
Create your own module called MyLibrary in the editor to the right. Include a constant called FAVE_BOOK and set it equal to a string naming your favorite book!
module MyLibrary
    FAVE_BOOK = "Harry Potter"
end

9.Resolve to Keep Learning
One of the main purposes of modules is to separate methods and constants into named spaces. This is called (conveniently enough) namespacing, and it's how Ruby doesn't confuse Math::PI and Circle::PI.
See that double colon we just used? That's called the scope resolution operator, which is a fancy way of saying it tells Ruby where you're looking for a specific bit of code. If we say Math::PI, Ruby knows to look inside the Math module to get that PI, not any other PI (such as the one we created in Circle).
Use the scope resolution operator to puts the value of PI from the Math module to the console.
puts Math::PI
10.A Few Requirements
Some modules, like Math, are already present in the interpreter. Others need to be explicitly brought in, however, and we can do this using require. We can do this simply by typing
require 'module'
We want to use the Ruby Date module to show today's date, but we haven't required it yet!
require 'date'
puts Date.today

11.Feeling Included
We can do more than just require a module, however. We can also include it!
Any class that includes a certain module can use those module's methods!
A nice effect of this is that you no longer have to prepend your constants and methods with the module name. Since everything has been pulled in, you can simply write PI instead of Math::PI.
class Angle
    include Math 
  attr_accessor :radians
  def initialize(radians)
    @radians = radians
  end 
  def cosine
    cos(@radians)
  end
end
acute = Angle.new(1)
acute.cosine

Fixin' for a Mixin
12.The Marriage of Modules and Classes
When a module is used to mix additional behavior and information into a class, it's called a mixin. Mixins allow us to customize a class without having to rewrite code!
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
  end
end

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

peter = Rabbit.new("Peter")
jiminy = Cricket.new("Jiminy")

peter.jump
jiminy.jump

13.Imitating Multiple Inheritance
Now you understand why we said mixins could give us the ability to mimic inheriting from more than one class: by mixing in traits from various modules as needed, we can add any combination of behaviors to our classes we like!
14.Extend Your Knowledge
Whereas include mixes a module's methods in at the instance level (allowing instances of a particular class to use the methods), the extend keyword mixes a module's methods at the class level. This means that class itself can use the methods, as opposed to instances of the class.
# ThePresent has a .now method that we'll extend to TheHereAnd

module ThePresent
  def now
    puts "It's #{Time.new.hour > 12 ? Time.new.hour - 12 : Time.new.hour}:#{Time.new.min} #{Time.new.hour > 12 ? 'PM' : 'AM'} (GMT)."
  end
end

class TheHereAnd
  extend ThePresent
end

TheHereAnd.now

Project
1.What You'll Be Building
In this case, we'll be making an Account object with public methods to display balances and transfer funds, but which rely on private methods to make sure the user's PIN (personal identification number) is correct before approving transactions.
2.Creating the Account Class
def initialize(name, balance=100)
  @name = name
  @balance = balance
What's that balance=100 doing? It's signifying an optional parameter. Ruby is saying that you can pass one or two arguments to initialize; if you pass two, it uses your balance argument to set @balance; if you only pass a name, balance gets a default value of 100, and that's what gets stored in @balance.
You probably also noticed we used underscores in our 1_000_000 (one million). Ruby allows this, and it makes it easier to read big numbers!Create an Account class in the editor. The :name and :balance attributes should be readable (but not writeable!). The class' initialize method should take two parameters, name and balance, and the balance parameter should default to 100.
Finally, go ahead and store your parameters in instance variables @name and @balance, respectively.
class Account
    attr_reader :name
    attr_reader :balance
    def initialize(name,balance=100)
        @name = name
        @balance = balance
    end
end

3.Private Affairs
Add two private methods to your Account class, pin and pin_error.
pin should take no arguments and set an instance variable, @pin, equal to the PIN number 1234.
pin_error should take no arguments and should simply return the string "Access denied: incorrect PIN."
class Account
    attr_reader :name
    attr_reader :balance
    def initialize(name,balance=100)
        @name = name
        @balance = balance
    end
    private
    def pin
        @pin = 1234
    end
    private
    def pin_error
        return "Access denied: incorrect PIN."
    end
end

4.Displaying the Balance
  1. Define a public display_balance method to your Account class. It should take a single parameter, pin_number.
  2. The body of your method should check whether the pin_number is equal to pin (the result of calling the private pin method)
  3. If it is, display_balance should puts "Balance: $#{@balance}."
  4. Otherwise (else), it should puts pin_error (the pin_error message)
 public
    def display_balance(pin_number)
        if pin_number == pin.call
            puts "Balance: $#{@balance}."
        else
            puts pin_error
        end
    end

5.Making a Withdrawal
Add a public withdraw method to your class that takes two parameters, pin_number and amount. If pin_number matches pin, your method should subtract the amount from the balance and puts "Withdrew #{amount}. New balance: $#{@balance}." Otherwise, it should puts pin_error.
public
    def withdraw(pin_number,amount)
        if pin_number == pin
            @balance -= amount
            puts "Withdrew #{amount}. New balance: $#{@balance}."
        else
            puts pin_error
        end
    end

6.Opening an Account
Last step: create an instance of your Account class called checking_account. Give it whatever name and starting balance you like!
 checking_account = Account.new("Becky",123)













Wednesday, April 13, 2016

Ruby_Lesson_Object-Oriented Programming I

Introduction to Classes
1.Why Classes?
Ruby is an object-oriented programming language, which means it manipulates programming constructs called objects. (Almost) everything in Ruby is an object! You've been using them all along, so they should be very familiar. Objects have methods, which you've seen before, and attributes, which are just data. For instance, in
"Matz".length
# ==> 4
the "Matz" object is a string with a .length method and a length attribute of 4But what exactly makes "Matz" a string? The fact that it's an instance of the String class. A class is just a way of organizing and producing objects with similar attributes and methods.
2.Class Syntax
A basic class consists only of the class keyword and the name of the class. Check it out:
class NewClass
  # Class magic here
end
Our NewClass has the ability to create new Ruby objects of class NewClass (just like "Hello!" is a String and 4 is a Fixnum). By convention, class names start with a capital letter and use CamelCase instead of relyingonunderscores.
3.Classing It Up
we started our class definition off with a method called initialize. You can think of initialize as the function that "boots up" each object the class creates.
class Person
    def initialize
    end
end

4.What's in a @name?
In Ruby, we use @ before a variable to signify that it's an instance variable. This means that the variable is attached to the instance of the class. For example,
class Car
  def initialize(make, model)
    @make = make
    @model = model
  end
end

kitt = Car.new("Pontiac", "Trans Am")
creates an instance, kitt, of the class Car. kitt has his own @make ("Pontiac") and @model ("Trans Am"). Those variables belong to the kitt instance, which is why t5.Instantiating Your First Object
We can create an instance of a class just by calling .new on the class name, like so:
me = Person.new("Eric")
Classes and Objects
6.Scope it Out
Another important aspect of Ruby classes is scope. The scope of a variable is the context in which it's visible to the program.
It may surprise you to learn that not all variables are accessible to all parts of a Ruby program at all times. When dealing with classes, you can have variables that are available everywhere (global variables), ones that are only available certain methods (local variables), others that are members of a certain class (class variables), and variables that are only available to particular instances of a class (instance variables).
The same goes for methods: some are available everywhere, some are only available to members of a certain class, and still others are only available to particular instance objects.
7.Naming Your Variables
Recall that instance variables begin with an @. This isn't just a Ruby convention—it's part of the syntax! Always start your instance variables with @.
Class variables are like instance variables, but instead of belonging to an instance of a class, they belong to the class itself. Class variables always start with two @s, like so: @@files.
Global variables can be declared in two ways. The first is one that's already familiar to you: you just define the variable outside of any method or class, and voilĂ ! It's global. If you want to make a variable global from inside a method or class, just start it with a $, like so: $matz.
class MyClass
  $my_variable = "Hello!"
end
puts $my_variable

8.For Instance...
Good! A caveat, though: global variables can be changed from anywhere in your program, and they are generally not a very good idea. It's much better to create variables with limited scope that can only be changed from a few places!
For example, instance variables belong to a particular object (or "instance"). Let's get in some practice with instance variables!
Go ahead and add age and profession parameters to the initialize method, then set these equal to instance variables in the body of the method. Use the name/@name example as a guide.
class Person
  def initialize(name,age,profession)
    @name = name
    @age = age
    @profession = profession
  end
end

9.Twice the @, Twice as Classy
We can create class variables by starting a variable name with two @ symbols. Class variables are attached to entire classes, not just instances of classes, like so:
class MyClass
  @@class_variable
end
Because there's only one copy of a class variable shared by all instances of a class, we can use them to pull off some cool Ruby tricks. For example, we can use a class variable to keep track of the number of instances of that class we've created.
class Person
  @@people_count = 0
  def initialize(name)
    @name = name
    @@people_count += 1
  end
  def self.number_of_instances
    return @@people_count
  end
end

matz = Person.new("Yukihiro")
dhh = Person.new("David")

puts "Number of Person instances: #{Person.number_of_instances}"

Inheritance
11.Watch Your Step
Inheritance is the process by which one class takes on the attributes and methods of another, and it's used to express an is-a relationship. For example, a cartoon fox is a cartoon mammal, so a CartoonFox class could inherit from a CartoonMammal class. However, a Wizard is not an Elf , so it shouldn't inherit from the Elf class (even if they have a lot of magical attributes and methods in common). Instead, both Wizard and Elf could ultimately inherit from the same MagicalBeing class.
12.Inheritance Syntax
In Ruby, inheritance works like this:
class DerivedClass < BaseClass
  # Some stuff!
end
where the derived class is the new class you're making and the base class is the class from which that new class inherits. You can read "<" as "inherits from."
13.Override!
Sometimes you'll want one class that inherits from another to not only take on the methods and attributes of its parent, but to override one or more of them.
For instance, you might have an Email class that inherits from Message. Both classes might have a send method that sends them, but the e-mail version may have to identify valid e-mail addresses and use a bunch of e-mail protocols that Message knows nothing about. Rather than add a send_email method to your derived class and inherit a send method you'll never use, you can instead just explicitly create a send method in the Email class and have it do all the email-sending work.
This new version of send will override (that is, replace) the inherited version for any object that is an instance of Email.
class Creature
  def initialize(name)
    @name = name
  end
 
  def fight
    return "Punch to the chops!"
  end
end

class Dragon < Creature
    def fight
        return "Breathes fire!"
    end
end

14.When Good isn't Good Enough
On the flip side, sometimes you'll be working with a derived class (or subclass) and realize that you've overwritten a method or attribute defined in that class' base class (also called a parent or superclass) that you actually need. Have no fear! You can directly access the attributes or methods of a superclass with Ruby's built-in super keyword.
The syntax looks like this:
class DerivedClass < Base
  def some_method
    super(optional args)
      # Some stuff
    end
  end
end
When you call super from inside a method, that tells Ruby to look in the superclass of the current class and find a method with the same name as the one from which super is called. If it finds it, Ruby will use the superclass' version of the method.
Replace the return statement inside Dragon's definition of fight with the keyword super. (No need to pass any arguments to super, since Creature's fight method doesn't take any.)
class Dragon < Creature
    def fight
        puts "Instead of breathing fire..."
        super
    end
end

15.There Can Be Only One!
Any given Ruby class can have only one superclass. Some languages allow a class to have more than one parent, which is a model called multiple inheritance. This can get really ugly really fast, which is why Ruby disallows it.
However, there are instances where you want to incorporate data or behavior from several classes into a single class, and Ruby allows this through the use of mixins.if you want to end a Ruby statement without going to a new line, you can just type a semicolon. This means you can write something like
class Monkey
end
on just one line: class Monkey; end. This is a time saver when you're writing something very short, like an empty class or method definition.
class Dragon < Creature; end
class Dragon < Person; end

See how we're trying to get Dragon to inherit from Creature and Person? We'll get a superclass mismatch for class Dragon error if we try this.
Project
2.Create Your Class
Create a class called Computer and give it an initialize method that takes no parameters. The body of initialize should be empty.
class Computer
    def initialize
    end
end

3.Fancify Your Initialize Method
Update initialize to take two parameters, username and password. In the body of initialize, set the instance variables @username and @password (respectively) to these parameters.
In your initialize method, you'll also want to create a @files instance variable and set this to an empty hash. This is so we can keep track of our files later!
class Computer
    def initialize(username,password)
        @username = username
        @password = password
        @files = {}
    end
end

4.Have a Little Class
Add a class variable called @@users to your Computer class. Set it equal to an empty hash.
In your initialize method, set @@users[username] = password so that your @@users hash keeps usernames as keys with each username's password as the associated value.
class Computer
    @@users = {}
    def initialize(username,password)
        @username = username
        @password = password
        @files = {}
        @@users[username] = password
    end  
end

5.Getting More Creative

  1. Inside your Computer class, define a method called create with a single parameter, filename.
  2. Inside create, declare a variable called time and set it equal to the current time (using Time.now).
  3. Next, inside create, add a new key/value pair to the @files hash. Use the filename key to store the value time.
  4. For the final step in create, please puts a message telling the user that a new file was created. Feel free to put in any information you like; the one we used in exercise 1 printed the filename, the username, and the time.
class Computer
    @@users = {}
    def initialize(username,password)
        @username = username
        @password = password
        @files = {}
        @@users[username] = password
    end  
    def create(filename)
        time = Time.now
        @files[filename] = time
        puts "A new file was created,filename: #{filename},username: #{username}, time: #{time}"
    end
end

6.Who're the Users?
Because @@users is a class variable, we'll use a class method to grab it. Most of the methods you've seen so far are instance methods—they work on a particular instance/object, such as "matz" or "blixy". A class method belongs to the class itself, and for that reason it's prefixed with the class name, like so:
class Machine
  def Machine.hello
    puts "Hello from the machine!"
  end
end
  1. Add a new class method to your Computer class called Computer.get_users. It should have no parameters.
  2. Your new Computer.get_users method should return the @@users class variable.
class Computer
    @@users = {}
    def initialize(username,password)
        @username = username
        @password = password
        @files = {}
        @@users[username] = password
    end  
    def create(filename)
        time = Time.now
        @files[filename] = time
        puts "A new file was created"
    end
    def Computer.get_users
        return @@users
    end
end

7.Instantiation Nation
my_computer = Computer.new("Becky","123456")









Ruby_Lesson_Blocks, Procs, and Lambdas

Blocks:A Reintroduction
1.You Know This!
We said earlier that a block is like a nameless method, but that's not quite true. (We'll get to actual nameless methods, called lambdas)
A Ruby block is just a bit of code that can be executed. Block syntax uses either do..end or curly braces ({})
2.Collect 'Em All
There are a bunch of really useful Ruby methods that take blocks. One we haven't covered yet is collect.
The collect method takes a block and applies the expression in the block to every element in an array. Check it out:
my_nums = [1, 2, 3]
my_nums.collect { |num| num ** 2 }
# ==> [1, 4, 9]
If we look at the value of my_nums, though, we'll see it hasn't changed:
my_nums
# ==> [1, 2, 3]
This is because .collect returns a copy of my_nums, but doesn't change (or mutate) the original my_nums array. If we want to do that, we can use .collect! with an exclamation point:
my_nums.collect! { |num| num ** 2 }
# ==> [1, 4, 9]
my_nums
# ==> [1, 4, 9]
Recall that the ! in Ruby means "this method could do something dangerous or unexpected!" In this case, it mutates the original array instead of creating a new one.
3.Learning to Yield
Why do some methods accept a block and others don't? It's because methods that accept blocks have a way of transferring control from the calling method to the block and back again. We can build this into the methods we define by using the yield keyword.
def block_test
  puts "We're in the method!"
  puts "Yielding to the block..."
  yield
  puts "We're back in the method!"
end
block_test { puts ">>> We're in the block!" }

4.Yielding With Parameters
def yield_name(name)
  puts "In the method! Let's yield."
  yield("Kim")
  puts "In between the yields!"
  yield(name)
  puts "Block complete! Back in the method."
end
yield_name("Eric") { |n| puts "My name is #{n}." }

Procs: Savable Blocks
6.Keeping Your Code DRY
Blocks are not objects, and this is one of the very few exceptions to the "everything is an object" rule in Ruby.Because of this, blocks can't be saved to variables and don't have all the powers and abilities of a real object.
You can think of a proc as a "saved" block: just like you can give a bit of code a name and turn it into a method, you can name a block and turn it into a proc. Procs are great for keeping your code DRY, which stands for Don't Repeat Yourself. With blocks, you have to write your code out each time you need it; with a proc, you write your code once and can use it many times!
7.Proc Syntax
Procs are easy to define! You just call Proc.new and pass in the block you want to save. Here's how we'd create a proc called cube that cubes a number (raises it to the third power):
cube = Proc.new { |x| x ** 3 }
We can then pass the proc to a method that would otherwise take a block, and we don't have to rewrite the block over and over!
[1, 2, 3].collect!(&cube)
# ==> [1, 8, 27]
[4, 5, 6].map!(&cube)
# ==> [64, 125, 216]
(The .collect! and .map! methods do the exact same thing.)
The & is used to convert the cube proc into a block (since .collect! and .map! normally take a block). We'll do this any time we pass a proc to a method that expects a block.
7.1.The .floor method rounds a float (a number with a decimal) down to the nearest integer. Write a proc called round_down that will do this rounding (we've added the code to pass it to floats.collect).
floats = [1.2, 3.45, 0.91, 7.727, 11.42, 482.911]
round_down = Proc.new {|x| x.floor}
ints = floats.collect(&round_down)

8.Why Procs?
Why bother saving our blocks as procs? There are two main advantages:
  1. Procs are full-fledged objects, so they have all the powers and abilities of objects. (Blocks do not.)
  2. Unlike blocks, procs can be called over and over without rewriting them. This prevents you from having to retype the contents of your block every time you need to execute a particular bit of code.
# Here at the amusement park, you have to be four feet tall
# or taller to ride the roller coaster. Let's use .select on
# each group to get only the ones four feet tall or taller.

group_1 = [4.1, 5.5, 3.2, 3.3, 6.1, 3.9, 4.7]
group_2 = [7.0, 3.8, 6.2, 6.1, 4.4, 4.9, 3.0]
group_3 = [5.5, 5.1, 3.9, 4.3, 4.9, 3.2, 3.2]

over_4_feet = Proc.new {|x| x>=4}

can_ride_1 = group_1.select(&over_4_feet)
can_ride_2 = group_2.select(&over_4_feet)
can_ride_3 = group_3.select(&over_4_feet)

9.Create Your Own!
  1. Create a method, greeter, that takes no arguments and yields to a block.
  2. Create a Proc, phrase, that puts "Hello there!". Pass this to greeter instead of a block. (Don't forget to pass &phrase instead of just phrase!)
def greeter
    yield
end
phrase = Proc.new{ puts "Hello there!"}
greeter(&phrase)

10.Call Me Maybe
Unlike blocks, we can call procs directly by using Ruby's .call method. Check it out!
test = Proc.new { # does something }
test.call
# does that something!
11.Symbols, Meet Procs
strings = ["1", "2", "3"]
nums = strings.map(&:to_i)
# ==> [1, 2, 3]
By mapping &:to_i over every element of strings, we turned each string into an integer!
numbers_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
strings_array = numbers_array.collect(&:to_s)

Lamdas
12.The Ruby Lambda
Like procs, lambdas are objects. The similarities don't stop there: with the exception of a bit of syntax and a few behavioral quirks, lambdas are identical to procs.
lambda { puts "Hello!" }
Is just about the same as
Proc.new { puts "Hello!" }
def lambda_demo(a_lambda)
  puts "I'm the method!"
  a_lambda.call
end
lambda_demo(lambda { puts "I'm the lambda!" })

13.Lambda Syntax
Lambdas are defined using the following syntax:
lambda { |param| block }
Lambdas are useful in the same situations in which you'd use a proc. strings = ["leonardo", "donatello", "raphael", "michaelangelo"]
symbolize = lambda{|x| x.to_sym}
symbols = strings.collect(&symbolize)

14.Lambdas vs. Procs
First, a lambda checks the number of arguments passed to it, while a proc does not. This means that a lambda will throw an error if you pass it the wrong number of arguments, whereas a proc will ignore unexpected arguments and assign nil to any that are missing.
Second, when a lambda returns, it passes control back to the calling method; when a proc returns, it does so immediately, without going back to the calling method.
def batman_ironman_proc
  victor = Proc.new { return "Batman will win!" }
  victor.call
  "Iron Man will win!"
end
puts batman_ironman_proc
def batman_ironman_lambda
  victor = lambda { return "Batman will win!" }
  victor.call
  "Iron Man will win!"
end
puts batman_ironman_lambda

Batman will win!
Iron Man will win!
15.Now You Try!
Let's riff on it with a lambda that checks to see if each element in an array is a symbol. We can do this checking with the .is_a? method, which returns true if an object is the type of object named and false otherwise:
:hello.is_a? Symbol
# ==> true
The word Symbol has to be capitalized when you're doing an .is_a? check!
  1. Create a lambda, symbol_filter, that takes one parameter and checks to see if that parameter .is_a? Symbol.
  2. Create a new variable called symbols, and store the result of calling my_array.select and passing it your lambda.
my_array = ["raindrops", :kettles, "whiskers", :mittens, :packages]
symbol_filter = lambda{|x| x.is_a? Symbol}
symbols = my_array.select(&symbol_filter)

16.Quick Review
  1. A block is just a bit of code between do..end or {}. It's not an object on its own, but it can be passed to methods like .each or .select.
  2. A proc is a saved block we can use over and over.
  3. A lambda is just like a proc, only it cares about the number of arguments it gets and it returns to its calling method rather than returning immediately.










Tuesday, April 12, 2016

Ruby_Lesson_The Zen of Ruby

You're in Control
1.Ruby is a Delight
As a language, Ruby prioritizes programmer productivity over program optimization. This means that Ruby may not always run a program in the fastest way possible, but it strives to be a language that programmers (like you!) find easy and fun to use. The more intuitive a language's syntax is, the more productive its users can be. You're in control, not the machine!
2.A Simpler 'If'
If the "do something" is a short, simple expression, however, we can move it up into a single line. The syntax looks like this:
expression if boolean
Ruby will expect an expression followed by if followed by a boolean. The order is important. You can do this:
puts "It's true!" if true
but not this:
if true puts "It's true!"
It's also important to note that you don't need an end when you write your if statement all on one line.
3.The One-Line Unless
You can do the exact same thing with the unless statement. The order is the same as before: something for Ruby to do, the unless keyword, and then an expression that evaluates to true or false.
Remember, you don't need an end when you write a one-line if or unless!
puts "one line" unless false
4.One Good Turn Deserves a Ternary
An even more concise version of if/else is the ternary conditional expression. It's called "ternary" because it takes three arguments: a boolean, an expression to evaluate if the boolean is true, and an expression to evaluate if the boolean is false.
The syntax looks like this:
boolean ? Do this if true: Do this if false
An example might be
puts 3 < 4 ? "3 is less than 4!" : "3 is not less than 4."
Remember: the order of arguments is important, and you don't need an end for this version of if/else.
puts 3==4 ? "true" : "false"
5.When and Then: The Case Statement
The syntax looks like this:
case language
when "JS"
  puts "Websites!"
when "Python"
  puts "Science!"
when "Ruby"
  puts "Web apps!"
else
  puts "I don't know!"
end
But you can fold it up like so:
case language
  when "JS" then puts "Websites!"
  when "Python" then puts "Science!"
  when "Ruby" then puts "Web apps!"
  else puts "I don't know!"
end
Tips & Tricks
6.Conditional Assignment
But what if we only want to assign a variable if it hasn't already been assigned? For this, we can use the conditional assignment operator: ||=. It's made up of the or (||) logical operator and the normal = assignment operator.
favorite_book = nil
puts favorite_book
favorite_book ||= "Cat's Cradle"
puts favorite_book
favorite_book ||= "Why's (Poignant) Guide to Ruby"
puts favorite_book
favorite_book = "Why's (Poignant) Guide to Ruby"
puts favorite_book

  1. favorite_book is set to nil, which is Ruby for "nothing." When you try to puts it to the screen, you get exactly that: nothing!
  2. Now our variable is conditionally set to "Cat's Cradle." Since the value of the variable was nothing before, Ruby goes ahead and sets it, so you see "Cat's Cradle" printed out.
  3. We try conditional assignment again, this time with "Why's (Poignant) Guide to Ruby." But wait! Our variable already has a value, "Cat's Cradle," so it stays set to that value and that's what we see printed out.
  4. Finally, we use regular old assignment to tell Ruby to reset favorite_book to "Why's (Poignant) Guide to Ruby," which it gladly does.
8.Implicit Return
For instance, if you don't tell a JavaScript function exactly what to return, it'll return undefined. For Python, the default return value is None. But for Ruby, it's something different: Ruby's methods will return the result of the last evaluated expression.
This means that if you have a Ruby method like this one:
def add(a,b)
  return a + b
end
You can simply write:

def add(a,b)
  a + b
end
And either way, when you call add(1,1), you'll get 2.
9.Short-Circuit Evaluation
Ruby does this via short-circuit evaluation. That means that Ruby doesn't look at both expressions unless it has to; if it sees
false && true
it stops reading as soon as it sees && because it knows false && anything must be false.
Knowing What to Use
10.The Right Tool for the Job
If we want to do something a specific number of times, we can use the .times method, like so:
5.times { puts "Odelay!" }
If we want to repeat an action for every element in a collection, we can use .each:
my_array.each{ |x| puts x if x%2==0}
11.Up the Down Staircase
If we know the range of numbers we'd like to include, we can use .upto and .downto.
We might use .upto to print out a specific range of values:
95.upto(100) { |num| print num, " " }
# Prints 95 96 97 98 99 100
and we can use .downto to do the same thing with descending values.
"L".upto("P") {|letter| puts letter}
12.Call and Response
.respond_to? takes a symbol and returns true if an object can receive that method and false otherwise. For example,
[1, 2, 3].respond_to?(:push)
would return true, since you can call .push on an array object. However,
[1, 2, 3].respond_to?(:to_sym)
would return false, since you can't turn an array into a symbol.
age = 26
age.respond_to?(:next)

.next will return the integer immediately following the integer it's called on, meaning 4.next will return 5
13.Being Pushy
Instead of typing out the .push method name, you can simply use <<, the concatenation operator (also known as "the shovel") to add an element to the end of an array:
[1, 2, 3] << 4
# ==> [1, 2, 3, 4]
Good news: it also works on strings! You can do:
"Yukihiro " << "Matsumoto"
# ==> "Yukihiro Matsumoto"
Use the concatenation operator instead of .push and +.
alphabet = ["a", "b", "c"]
alphabet.push("d") #
caption = "A giraffe surrounded by "
caption += "weezards!"

caption = "A giraffe surrounded by "
caption << "weezards!"

14.String Interpolation
You can always use plain old + or << to add a variable value into a string:
drink = "espresso"
"I love " + drink
# ==> I love espresso
"I love " << drink
# ==> I love espresso
But if you want to do it for non-string values, you have to use .to_s to make it a string:
age = 26
"I am " + age.to_s + " years old."
# ==> "I am 26 years old."
"I am " << age.to_s << " years old."
# ==> "I am 26 years old."
This is complicated, and complicated is not the Ruby way. A better way to do this is with string interpolation. The syntax looks like this:
"I love #{drink}."
# ==> I love espresso.
"I am #{age} years old."
# ==> I am 26 years old.
All you need to do is place the variable name inside #{} within a string!










Monday, April 11, 2016

Ruby_Lesson_Hashes and Symbols

More on Hashes
1.The Story So Far
We can create hashes several ways, but two of the most popular are hash literal notation:
new_hash = { "one" => 1 }
and hash constructor notation:
new_hash = Hash.new
2.Iterating Over Hashes
matz.each {|x,y| puts y}
3.Nil: a Formal Introduction
What happens if you try to access a key that doesn't exist, though?
In many languages, you'll get an error of some kind. Not so in Ruby: you'll instead get the special value nil.
Along with false, nil is one of two non-true values in Ruby. (Every other object is regarded as "truthy," meaning that if you were to type if 2 or if "bacon", the code in that if statement would be run.)
It's important to realize that false and nil are not the same thing: false means "not true," while nil is Ruby's way of saying "nothing at all."
4.Setting Your Own Default
You don't have to settle for nil as a default value, however. If you create your hash using the Hash.new syntax, you can specify a default like so:
my_hash = Hash.new("Trady Blix")
Now if you try to access a nonexistent key in my_hash, you'll get "Trady Blix" as a result.
You can always read more hashy goodness in the offical Ruby documentation.
The Many Faces of Symbol
6.What's a Symbol?
You can think of a Ruby symbol as a sort of name. It's important to remember that symbols aren't strings:
"string" == :string # false
Above and beyond the different syntax, there's a key behavior of symbols that makes them different from strings: while there can be multiple different strings that all have the same value, there's only one copy of any particular symbol at a given time.
puts "string".object_id
puts "string".object_id
puts :symbol.object_id
puts :symbol.object_id


The .object_id method gets the ID of an object—it's how Ruby knows whether two objects are the exact same object. The two "strings" are actually different objects, whereas the :symbol is the same object listed twice.
7.Symbol Syntax
Symbols always start with a colon (:). They must be valid Ruby variable names, so the first character after the colon has to be a letter or underscore (_); after that, any combination of letters, numbers, and underscores is allowed.
Make sure you don't put any spaces in your symbol name—if you do, Ruby will get confused.
:my symbol # Don't do this!
:my_symbol # Do this instead.
8.What are Symbols Used For?
Symbols pop up in a lot of places in Ruby, but they're primarily used either as hash keys or for referencing method names. Symbols make good hash keys for a few reasons:
  1. They're immutable, meaning they can't be changed once they're created;
  2. Only one copy of any symbol exists at a given time, so they save memory;
  3. Symbol-as-keys are faster than strings-as-keys because of the above two reasons.
9.Converting Between Symbols and Strings
:sasquatch.to_s
# ==> "sasquatch"

"sasquatch".to_sym
# ==> :sasquatch
  1. Create a new variable, symbols, and store an empty array in it.
  2. Use .each to iterate over the strings array.
  3. For each s in strings, use .to_sym to convert s to a symbol and use .push to add that new symbol to symbols.
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = []
strings.each {
    |s|
    symbols.push(s.to_sym)
}

10.Many Paths to the Same Summit
Besides using .to_sym, you can also use .intern. This will internalize the string into a symbol and works just like .to_sym:
"hello".intern
# ==> :hello
The Marriage of Hash and Symbol
11.All Aboard the Hash Rocket!
The hash syntax you've seen so far (with the => symbol between keys and values) is sometimes nicknamed the hash rocket style.
numbers = {
  :one => 1,
  :two => "two",
  :three => 3,
}
12.The Hash Rocket Has Landed
new_hash = { one: 1,
  two: 2,
  three: 3
}
The two changes are:
  1. You put the colon at the end of the symbol, not at the beginning;
  2. You don't need the hash rocket anymore.
It's important to note that even though these keys have colons at the end instead of the beginning, they're still symbols!
13.Dare to Compare
We mentioned that hash lookup is faster with symbol keys than with string keys. Here, we'll prove it!
require 'benchmark'
string_AZ = Hash[("a".."z").to_a.zip((1..26).to_a)]
symbol_AZ = Hash[(:a..:z).to_a.zip((1..26).to_a)]
string_time = Benchmark.realtime do
  100_000.times { string_AZ["r"] }
end
symbol_time = Benchmark.realtime do
  100_000.times { symbol_AZ[:r] }
end
puts "String time: #{string_time} seconds."
puts "Symbol time: #{symbol_time} seconds."

14.Becoming More Selective
To filter a hash for values that meet certain criteria, we can use .select.
grades = { alice: 100,
  bob: 92,
  chris: 95,
  dave: 97
}
grades.select {|name, grade| grade < 97}
# ==> {:bob=>92, :chris=>95}
grades.select { |k, v| k == :alice }
# ==> {:alice=>100} 
15.More Methods, More Solutions
Ruby includes two hash methods, .each_key and .each_value, that do exactly what you'd expect:
my_hash = { one: 1, two: 2, three: 3 }
my_hash.each_key { |k| print k, " " }
# ==> one two three
my_hash.each_value { |v| print v, " " }
# ==> 1 2 3
Project: A Box Office Hash 
It'll do one of four things: add a new movie to a hash, update the rating for an existing movie, display the movies and ratings that are already in the hash, or delete a movie from the hash. If it doesn't receive one of those four commands, the program will output some kind of error message.
movies = {
  Memento: 3,
  Primer: 4,
  Ishtar: 1
}

puts "What would you like to do?"
puts "-- Type 'add' to add a movie."
puts "-- Type 'update' to update a movie."
puts "-- Type 'display' to display all movies."
puts "-- Type 'delete' to delete a movie."

choice = gets.chomp.downcase
case choice
when 'add'
  puts "What movie do you want to add?"
  title = gets.chomp
  if movies[title.to_sym].nil?
    puts "What's the rating? (Type a number 0 to 4.)"
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i
    puts "#{title} has been added with a rating of #{rating}."
  else
    puts "That movie already exists! Its rating is #{movies[title.to_sym]}."
  end
when 'update'
  puts "What movie do you want to update?"
  title = gets.chomp
  if movies[title.to_sym].nil?
    puts "Movie not found!"
  else
    puts "What's the new rating? (Type a number 0 to 4.)"
    rating = gets.chomp
    movies[title.to_sym] = rating.to_i
    puts "#{title} has been updated with new rating of #{rating}."
  end
when 'display'
  movies.each do |movie, rating|
    puts "#{movie}: #{rating}"
  end
when 'delete'
  puts "What movie do you want to delete?"
  title = gets.chomp
  if movies[title.to_sym].nil?
    puts "Movie not found!"
  else
    movies.delete(title.to_sym)
    puts "#{title} has been removed."
  end
else
  puts "Sorry, I didn
't understand you."
end

2.Setting Up
First things first: let's create a hash to hold our movies and their ratings, and let's prompt the user for input so we can eventually store movie/ratings pairs in our hash.

  1. A Hash is a way of storing data by a specifiable key, as opposed to an array which can only use numbers. It is created like { } above.
  2. puts asks a question on the command line, here we ask if you like coding in Ruby.
  3. In order to get the user input, we have to call .chomp on gets
movies = {
    love:10,
    war:1,
    family:6
    }
puts "Please make your choice:"
choice=gets.chomp

3.The Case Statement
The case statement, which will decide what actions to take based on what the user types in.The syntax looks like this:
case language
when "JS"
  puts "Websites!"
when "Python"
  puts "Science!"
when "Ruby"
  puts "Web apps!"
else
  puts "I don't know!"
end
The else is what the case statement will do if it doesn't match any of its when statements to the case.
Below your existing code, create a case statement for the choice variable with the following when conditions:
  1. when "add", please puts "Added!"
  2. when "update", please puts "Updated!"
  3. when "display", please puts "Movies!"
  4. when "delete", please puts "Deleted!"
  5. Otherwise (i.e. else), please puts "Error!"
Don't forget the end statement after your case/when lines.
case choice
when "add"
    puts "Added!"
when "update"
    puts "updated!"
when "display"
    puts "Movies!"
when "delete"
    puts "Deleted!"
else
    puts "Erro!"
end

4.Prompting: Redux!

  • Inside your when "add" block, remove the puts "Added!" statement.
  • In its place, prompt the user for a movie title. Save the result in a new variable called title. (*Your code already has an example of how to do this!)
  • Next, prompt the user for the rating of the movie. Save that in a new variable called rating.
  • Add that movie/rating pair to the movies hash and puts a message indicating the pair was added. (No need for to_sym or to_i just yet!)
puts "Input movie"
   title = gets.chomp
   puts "Input rating"
   rating = gets.chomp
   movies[title] = rating
   puts "#{title} with rating #{rating} has been added!"

5.Not My Type
Ruby's .to_sym method can convert a string to a symbol, and .to_i will convert a string to an integer.
Call .to_sym on your title and .to_i on your rating so that your movie titles are stored as symbols in the hash and the associated ratings are stored as integers.
   puts "Input movie"
   title = gets.chomp.to_sym
   puts "Input rating"
   rating = gets.chomp.to_i

6.Error! Error!
The final thing we'll want to do is perform a check to see whether the movie to be added is already in the hash.Add an if/else statement to the add branch of your case. If the movie isn't already in the hash (that is, if movies[title.to_sym] is nil), it should add the movie/rating pair; otherwise, it should puts that the movie already exists and not add anything to the hash. Make sure to test it!
   if movies[title.to_sym].nil?
        puts "Input rating"
        rating = gets.chomp
        movies[title.to_sym] = rating.to_i
        puts "#{title} with rating #{rating} has been added!"
    else
        puts "already exists!"

7.Update
  1. Inside your when "update" block, remove the puts "Updated!" statement.
  2. Prompt the user for a movie title. Store it in title.
  3. if the movies[title] is nil, then the movie is not in the hash. Please puts a string telling the user of their error.
  4. Otherwise (else), we need to update the movies hash. Prompt the user for a new rating. Set the movie's rating to that new value.
  puts "Input movie"
    title = gets.chomp
    if movies[title.to_sym].nil?
        puts "does not exists!"
    else
        puts "Input new rating"
        rate = gets.chomp
        movies[title.to_sym] = rate.to_i
    end

8.Display
  1. First, remove the puts "Movies!" when the user types "display".
  2. Next, iterate through the hash using .each and puts each movie/rating pair. The format should be "#{movie}: #{rating}.
 movies.each {
        |movie,rate| puts "#{movie}: #{rate}"
        }

9.Delete
Ruby makes it easy to remove a movie/rating pair from our hash: we just write movies.delete(title)!
  1. Go ahead and remove the puts "Deleted!" when the user types "delete".
  2. Get the title from the user.
  3. Include an if/else statement that puts an error if the movie's not in the hash; if it's there, use .delete to remove it as shown above.
    puts "Input title"
    title = gets.chomp
    if movies[title.to_sym].nil?
        puts "not exist"
    else
        movies.delete(title.to_sym)
    end