Learn To Program


Learn To Program is a beginner’s programming primer. The author uses Ruby as a teaching language To introduce you To the world of programming with concise but vivid examples.

This book is both a beginner programming primer and a Ruby primer. Therefore, for those who have a certain programming foundation and want to learn Ruby, this book will also get a lot of knowledge.

There are 12 lessons in the book. They are listed and linked here for those who are interested to read them.

  1. Getting Started
  2. Numbers
  3. Letters
  4. Variables and Assignment
  5. Mixing It Up
  6. More About Methods
  7. Flow Control
  8. Arrays and Iterators
  9. Writing Your Own Methods
  10. Classes
  11. Blocks and Procs
  12. Beyond This Tutorial

Since Ruby is the tutorial language for this book, the environment installation is no longer necessary. Course 1 teaches you how to install Ruby and recommends using a handy IDE to write Ruby. I use VSCode to write Ruby, and I feel good about it. In the early stages, I suggest learning or debugging Ruby directly through irB. Just enter the IRB at the terminal and try it out.

Numbers

The Number types in Ruby are Integer and Float (note that Ruby has no int, long, nor Float, double, there are only two types of numbers, Integer and Float). . And the logical operation +-*/ between Number.

Practice printing below and see if it works.

puts 1+2
puts 2*3
puts 5-8
puts 9/2
Copy the code

3-3, 4, 6

Letters

In Ruby, the representation of a string is expressed as a pair of ‘ ‘or “”.

puts 'Hello, world! '
puts ' '
puts "Good-bye."
Copy the code

String concatenation can be represented simply by +.

puts 'I like' + ' apple pie.'
Copy the code

I like apple pie.

To concatenate repeating strings, we can also use the * operator.

puts 'blink ' * 4
Copy the code

blink blink blink blink

Of course, the above String and number combinations are because both + and * are functions of String, so we can use them as functions.

We can also call it as follows:

puts 'I like'. + (' apple pie.')
Copy the code

I like apple pie.

Their pseudocode is as follows:

class String
    def +(other)
        "# {self}#{other}"
    end

    def *(other)
        s = self
        other.times do
            s = s + self
        end
        return s
    end

end

Copy the code

Variables and Assignment

(Note: Ruby does not need to specify the type of a variable. This is a dynamic language. It changes the type of a variable based on the assignment.)

composer = 'Mozart'
puts composer + ' was "da bomb", in his day.'
Copy the code

Mixing It Up

When we run the following example, the program prompts us for syntax errors. Why is that? The type did not match, so the runtime error was reported. How can numbers and strings add together? Only numbers and numbers, strings and strings add together.

var1 = 2
var2 = '5'

puts var1 + var2
Copy the code

This requires the ability to convert numbers and strings to each other.

To_s means convert to a string. So the following expression is true.

var1 = 2
var2 = '5'

puts var1.to_s + var2
Copy the code

Others include to_I to integer and TO_F to floating point.

puts '15'.to_f
puts "10".to_i
Copy the code

More About Methods

Ruby uses.syntax to call a function, using strings as an example.

var1 = 'stop'
puts var1.reverse
Copy the code

pots

Get user input by calling the gets function. Gets. Chomp wraps lines after user input.

puts 'What is your full name? '
name = gets.chomp
puts 'Did you know there are ' + name.length.to_s +
     ' characters in your name, ' + name + '? '
Copy the code

What is your full name?

User Input

Did you know there are 22 characters in your name, Christopher David Pine?

# 5 to the second power
puts 5台湾国2
# take over
puts 7%3
# the absolute value
puts((5-2).abs)
puts((2-5).abs)
# Random number no greater than 1 (float)
puts rand
# 0<=x<10 random integer
puts rand(10)

Copy the code

Flow Control

Control flow, that is, compare >, <, =>, ==, <=,! ,! =

puts 1= =1
puts 2! =1
puts 1 > 2
Copy the code

true

true

false

Conditional branches if, ELSE, ELIF, end

puts 'Hello, what\'s your name? '
name = gets.chomp
puts 'Hello, ' + name + '. '
if name == 'Chris'
  puts 'What a lovely name! '
end
Copy the code

Hello, what’s your name?

Your input…

Hello, Chris.

What a lovely name!

Loop while

command = ' '

whilecommand ! ='bye'
  puts command
  command = gets.chomp
end

puts 'Come again soon! '
Copy the code

Hello?

Hello?

Hi!

Hi!

Very nice to meet you.

Very nice to meet you.

Oh… how sweet!

Oh… how sweet!

bye

Come again soon!

Logic judgment merger or (| |), and (&), not (!)

puts 'Hello, what\'s your name? '
name = gets.chomp
puts 'Hello, ' + name + '. '
if (name == 'Chris' or name == 'Katy')
  puts 'What a lovely name! '
elsif name == 'Jack' and name.length == 4
    puts ""
end
Copy the code

Hello, what’s your name?

Katy

Hello, Katy.

What a lovely name!

Arrays and Iterators

The Ruby way to represent arrays is array = [1,2,3,”3″], where each element in the array can have a different type.

Gets the elements in an array

puts array[0]
puts array[1]
puts array[-1]
Copy the code

1 2 3 “”

To get each element in an array, you can iterate through the each method.

languages = ['English'.'German'.'Ruby']

languages.each do |lang|
  puts 'I love ' + lang + '! '
  puts 'Don\'t you? '
end

puts 'And let\'s hear it for C++! '
puts '... '
Copy the code

I love English!

Don’t you? I love German! Don’t you? I love Ruby! Don’t you? And let’s hear it for C++! .

To repeat the operation a certain number of times, you can do this by placing times of integer.

3.times do
  puts 'Hip-Hip-Hooray! '
end
Copy the code

Hip-Hip-Hooray!

Hip-Hip-Hooray!

Hip-Hip-Hooray!

Writing Your Own Methods

In Ruby, methods are defined in a format where arguments are saved

def sayMoo numberOfMoos
  puts 'mooooooo... '*numberOfMoos
end

sayMoo 3
puts 'oink-oink'
sayMoo 
Copy the code

mooooooo… mooooooo… mooooooo…

oink-oink

Classes

Ruby uses the keyword class to define a class. When the class is an existing class, it means to add information to the class.

class Integer
  def to_eng
    if self= =5
      english = 'five'
    else
      english = 'fifty-eight'
    end

    english
  end
end


puts 5.to_eng
puts 58.to_eng
Copy the code

five

fifty-eight

Class instance variables are represented by @+ variable names, and class variables are @@+ variable names

class Die

  def roll
    @numberShowing = 1 + rand(6)
  end

  def showing
    @numberShowing
  end

end

die = Die.new
die.roll
puts die.showing
puts die.showing
die.roll
puts die.showing
puts die.showing
Copy the code

4

4 June 6

Blocks and Procs

This lesson is on closures in Ruby, which can be understood as a quick code, written between the do end and represented by the Proc class. Do end can also be written in {} form. Closures can be used as arguments to functions or as functions.

# Create a closure and store it in the toast variable. Call to execute the block of code in the closure
toast = Proc.new do
  puts 'Cheers! '
end

toast.call
toast.call
toast.call
Copy the code

Cheers!

Cheers!

Cheers!

You can also pass arguments in the closure.

doYouLike = Proc.new do |aGoodThing|
  puts 'I *really* like '+aGoodThing+'! '
end

doYouLike.call 'chocolate'
doYouLike.call 'ruby'
Copy the code

I really like chocolate!

I really like ruby!

When a closure is used as an argument to a function:

def doSelfImportantly someProc
  puts 'Everybody just HOLD ON!  I have something to do...'
  someProc.call
  puts 'Ok everyone, I\'m done. Go on with what you were doing.'
end

sayHello = Proc.new do
  puts 'hello'
end

sayGoodbye = Proc.new do
  puts 'goodbye'
end

doSelfImportantly sayHello
doSelfImportantly sayGoodbye
Copy the code

Everybody just HOLD ON! I have something to do…

hello

Ok everyone, I’m done. Go on with what you were doing.

Everybody just HOLD ON! I have something to do…

goodbye

Ok everyone, I’m done. Go on with what you were doing.

When the closure is the return value of a function:

def compose proc1, proc2
  Proc.new do |x|
    proc2.call(proc1.call(x))
  end
end

squareIt = Proc.new do |x|
  x * x
end

doubleIt = Proc.new do |x|
  x + x
end

doubleThenSquare = compose doubleIt, squareIt
squareThenDouble = compose squareIt, doubleIt

puts doubleThenSquare.call(5)
puts squareThenDouble.call(5)
Copy the code

100

50

We can also pass closures into functions without Proc, just by preending the arguments with an &.

class Array
If you pass in the Proc object directly, you will not be able to call the function directly after the do end block. You will need to create the Proc object first and then pass it in.
  def eachEven(&wasABlock_nowAProc)
    # We start with "true" because arrays start with 0, which is even.
    isEven = true

    self.each do |object|
      if isEven
        wasABlock_nowAProc.call object
      end

      isEven = (not isEven)  # Toggle from even to odd, or odd to even.
    end
  end
end

['apple'.'bad apple'.'cherry'.'durian'].eachEven do |fruit|
  puts 'Yum! I just love '+fruit+' pies, don\'t you? '
end

# Remember, we are getting the even-numbered elements
# of the array, all of which happen to be odd numbers,
# just because I like to cause problems like that.
[1.2.3.4.5].eachEven do |oddBall|
  puts oddBall.to_s+' is NOT an even number! '
end
Copy the code

Yum! I just love apple pies, don’t you?

Yum! I just love cherry pies, don’t you?

1 is NOT an even number!

3 is NOT an even number!

5 is NOT an even number!

For multiple arguments, block can only be placed at the end

def profile descriptionOfBlock, &block
  startTime = Time.now

  block.call

  duration = Time.now - startTime

  puts descriptionOfBlock+':'+duration.to_s+' seconds'
end

profile '25000 doublings' do
  number = 1

  25000.times do
    number = number + number
  end

  # Show the number of digits in this HUGE number.
  puts number.to_s.length.to_s+' digits'
end

profile 'count to a million' do
  number = 0

  1000000.times do
    number = number + 1
  end
end
Copy the code

7526 digits

25000 doublings: 0.026852 seconds

count to a million: 0.039258 seconds


Now let’s do a little exercise in the book.

part1: Grandfather Clock. Write a method which takes a block and calls it once for each hour that has passed today. That way, if I were to pass in the block do puts ‘DONG! ‘ end, it would chime (sort of) like a grandfather clock. Test your method out with a few different blocks (including the one I just gave you). Hint: You can use Time.now.hour to get the current hour. However, this returns a number between 0 and 23, so you will have to alter those numbers in order to get ordinary clock-face numbers (1 to 12).

This means that EVERY hour between 1 and 12 hours I print ‘DONG! ‘

def onHourAlarm(&block)
    hour = Time.new.hour
    if hour > 12 
        hour = hour - 12
    end
    block.call hour
end

onHourAlarm do |hour|
    puts "It is #{hour} o 'clock"
end
Copy the code

We can also implicitly call the function’s block, as follows:

def doItTwice
  if block_given?
    yield
    yield
  else
    puts 'no block'
  end
end

doItTwice do
  puts 'buritiate mustripe lablic acticise'
end
Copy the code

buritiate mustripe lablic acticise

buritiate mustripe lablic acticise

The yield keyword indicates the closure passed by the implicit call function, block_given? Is to determine whether the function has an passed closure.