#!/usr/bin/env ruby
=begin
This file contains the ex from the 20180305 lesson.
Topics:
* Recap on math operators
* Conditional execution
* Input from the user
* Range
MB.
=end
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Recap on math operators
puts "\n\n== Recap on math operators"
# Computes the real roots of a polynomial of 2nd degree
# with the following form "ax^2 + bx + c = 0"
# Returns: [zero1, zero2]
def real_roots(a, b, c)
delta = b*b - 4*a*c
# Use sqrt function from the Math library
sqrt_delta = Math.sqrt(delta)
# we may return multiple results, our zeros in this case, as an array.
return [(-b + sqrt_delta) / (2*a.to_f), (-b - sqrt_delta) / (2*a.to_f)]
end
puts "Roots of x^2 + 3x + 2 #{real_roots(1,3,2)}"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Conditional execution
puts "\n\n== Conditional execution"
# Computing the roots of a polynomial of 2nd degree
# with the following form "ax^2 + bx + c = 0"
# Returns: [zero_1_real, zero_1_imaginary, zero_2_real, zero_2_imaginary]
def roots(a, b, c)
delta = b*b - 4*a*c
if delta >= 0 then
# Parallel assignment here is used to assign each element of the
# result array to its own variable.
x1, x2 = real_roots(a, b, c)
return [x1, 0, x2, 0]
else
sqrt_delta = Math.sqrt(-delta)
# Mind the int vs float division !!!
return [-b.to_f/(2*a), sqrt_delta/(2*a), b.to_f/(2*a), -sqrt_delta/(2*a)]
end
end
puts "Roots of 5x^2 + 10x + 3 #{roots(5,10,3)}"
puts "Roots of 5x^2 + 2x + 3 #{roots(5,2,3)}"
=begin
CONDITIONAL STATEMENTS
It is subordinate the execution of a block (piece of code) to conditions.
This can be done be means of the `if` statement which can appear in
the following form.
* Simple
`
if condition then
code to execute only if condition is true
end
`
* Complete
`
if condition then
code to execute only if condition is true
else
code to execute only if condition is false
end
`
* Chained:
In chained `if` ONLY the block corresponding to the FIRST (in reading order)
true condition is executed, the others are not evaluated.
`
if condition_1 then
code to execute only if condition_1 is true
# NOTE: this is not a typo. It really is 'elsif'
elsif
code to execute only if
condition_1 is false AND condition_2 is true
# NOTE: there many be more than one elsif.
...
# The else if optional, like for the first two examples.
else
code to be executed only if non of the above was executed.
In this case if both condition_1 and condition_2 were false.
end
`
=end
=begin
BOOLEAN EXPRESSIONS
The "conditions" used in the previous example must be boolean expression. A
boolean expression is an expression that evaluates to either true or false.
A boolean expression result is a boolean value that can be stored in
boolean variable. A boolean variable can also be created by assignment of the
truth values true, false.
It follows a list of operators that produce boolean values.
=end
x = 5
y = 10
puts ""
puts "For the following examples x is #{x} and y is #{y}"
puts "Are equal: x == y -> #{x == y}"
puts "Are different: x != y -> #{x != y}"
puts "Is greater: x > y -> #{x > y}"
puts "Is greater/equal: x >= y -> #{x >= y}"
puts "Is smaller: x < y -> #{x < y}"
puts "Is smaller/equal: x <= y -> #{x <= y}"
# This operator is useful when sorting. Furthermore, it can be used to
# implement any of the above (we will see it again when talking about
# Object Oriented Programming - OOP).
#
# It returns
# -1 if x < y
# 0 if x == y
# 1 if x > y
# nil if the comparison of x and y is not defined.
puts "Spaceship: x <=> y -> #{x <=> y}"
=begin
BOOLEAN EXPRESSIONS - BOOLEAN OPERATORS
a.k.a logical operators
Boolean expression are so called because operate on boolean values,
there exist specialized operators: boolean operators.
=end
a = true
b = false
puts ""
puts "For the following examples a is #{a} and b is #{b}"
puts "a AND b: a and b -> #{a and b}"
puts "a OR b: a or b -> #{a or b}"
puts "not(a): !a -> #{!a}"
puts "a OR b: a || b -> #{a || b}"
=begin
BITWISE OPERATORS
(just for reference)
^ -> binary xor,
if used with boolean variable is equal to: ((a and not b) or (not a and b))
& -> binary and
! -> binary or
~ -> binary ones complement
<< binary left shift
>> binary right shift
=end
=begin
ADVANCED CONDITIONAL STATEMENTS
* Postfix if
` if condition`
equivalent to:
`
if condition then
statement
end
`
* Postfix unless
` unless condition`
equivalent to:
`
if not condition then
statement
end
`
* Ternary operator
`condition ? : `
equivalent to:
`
if condition then
else
end
* Switch case
NOT the same as in C & friends.
1) Does not fall through
2) Returns the value of the last executed statement.
Thus, it can be used in assignment.
"simple version"
x = case
when condition then statement
when condition
code
else
end
"magic version"
case var
when y then statement
...
else
end
In this version `var` is compared to y with the `===` operator
which can be defined on classes. This "should make the code more readable",
look at the following examples. For more details please refer to the online
documentation:
https://ruby-doc.com/docs/ProgrammingRuby/html/tut_expressions.html#S5
=end
puts ""
q = 42
puts case q
when 30...40 then "#{q} is between 30 and 40"
# === for range it means "is x in range"
when 40...50 then "#{q} is between 40 and 50"
when 50...60 then "#{q} is between 50 and 60"
else "#{q} is not between 30 and 60"
end
q = "hello"
puts case q
when "lol" then "#{q} is lol"
when "Hello" then "#{q} is Hello"
# === for string is the same as == (case sensitive)
when "hello" then "#{q} is hello"
when 40...50 then "#{q} is between 40 and 50"
end
q = 42
puts case q
when "lol" then "#{q} is lol"
when "hello" then "#{q} is hello"
# They can be mixed !!
when 40...50 then "#{q} is between 40 and 50"
end
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Input from the user
# `gets`: read the user input until
puts "\n\n== Input from the user"
puts "Computing ax^2 + bx + c"
# Once read about loops (next topic) try to implement a check that guarantees
# out inputs to be a number different from 0
# hint: x != Nan and x != 0
puts "Provide `a`"
# gets -> get input
# chomp -> clean it
# to_i -> cast (aka convert) to integer
a = gets.chomp.to_i
puts "Provide `b`"
b = gets.chomp.to_i
puts "Provide `c`"
c = gets.chomp.to_i
puts "Roots for #{a}x^2 + #{b}x + #{c} are #{roots(a,b,c)}"
# Conversion
# A value can be converted to an integer via the `to_i` method, to a float with
# `to_f`, to a string with `to_s`, and to an array with `to_a`.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Range
puts "\n\n== Range"
# [1,3]
puts "1..3 ->"
puts (1..3).to_a
# [1,3[
puts "1...3 ->"
puts (1...3).to_a