3 – Variables

“Think twice; code once”

Theory

Data types and Operators

Two of the data types that we are using are integers and strings.

  • an integer: any integer number
    • .., -3, -2, -1, 0, 1, 2, 3, …
  • a string: any sequence of 0 or more characters between quotes
    • “”
    • “5”
    • “look at me mom!”

The following are a few of their operators:

integer operators

+  # addition
-  # subtraction
*  # multiplication
/  # division

string operators

+  # concatenation

Now we can take an integer expression and reduce it to its value:

(2 + 3) * 2 - (6 / 2) = 5 * 2 - 3 # evaluate parentheses first
                      = 10 - 3    # follow standard precedence rules
                      = 7

We can also evaluate an expression of strings:

"Hello" + " " + "World" + "!" = "Hello World!"

The value of a function

The value of a function is the value that the function returns, i.e., the value that follows the keyword return.

In Python, if the keyword return is not followed by anything, then the value of the function is set to the special value None. For example,

let me try it

# function w/o a return so its value is None
def greet():
    print( "Hello" )

# integer function that returns 15
def sum_1_to_5():
    return 1 + 2 + 3 + 4 + 5

# string function that returns "Hello world"
def greet():
    return "Hello" + " " + "world"

Variables

  • A variable is a value with a name.
  • When we name a value, we say that we are assigning the value to the variable.
  • We assign values to variables using the assignment operator =
  • A variable behaves like the value that it contains

let me try it

# assign a string value to a var
my_name = "Karel"

#assign string expres. to a var
greeting = "Hello " + my_name +"!"

# assign int expres. to a var
eggs_in_a_box = 5 + 5 + 2
eggs_in_10_boxes = eggs_in_a_box * 10

# assign the value of a function to a var
def greet():
    return "Hello" + " " + "world"

my_greeting = greet()
print( my_greeting )

Type casting

Expressions are usually composed of elements of the same type, e.g., all the terms are integers:

days_in_a_year = 365
seconds_in_a_year = days_in_a_year * 24 * 60 * 60

or all the terms are strings:

name = "Karel"
greeting = "Hello " + name + ", my friend!"

If we want to use a term of one type into an expression of another type we need to change its type; this is called casting.

Casting functions:

  • String to integer -> use int()
    int( “5” ) == 5
  • Integer to string -> use str(),
    str( 5 ) == “5”

let me try it

name = "John"
age = 10
message = name + " is " + str(age) + " years old"  # turn age into string
print( message )

Getting input from the user

Karel can read strings using input(), which receives a string to use in a dialog, and returns as a string with the user’s reply, i.e.,

 = input(  )

For example:

Show it to me

mesg = "How many eggs are in a dozen? "
reply = input( mesg )
dozen = int( reply )
ten_dozens = 10 * dozen
mesg = "There are " + str(ten_dozens) + "eggs in 10 dozens"
say( mesg )

Function Input/Output (I/O)

output

To get information from a function, we assign its value to a variable, e.g.,

about_to_crash = wall_in_front()        # about_to_crash is a boolean var
age = int( "12" )                       # age is an integer var
name = input( "what is your name? " )   # name is a string var

input

We pass information to a function within the parentheses; the data in the parentheses are called the arguments of the function call, e.g.,

move()              # call with no arguments
print( "hello" )    # call with a single arg: the string "hello"
repeat( move, 10 )  # call with two args: the name of
                    # the function 'move' and the integer 10

minus_diagramFunctions receive data in variables called parameters. The parameters are paired up with the arguments so that:

1st parameter = 1st argument
2nd parameter = 2nd argument

and so on

For example:

show it to me, let me try

# the parameters of minus are 'a' and 'b'
def minus( a, b ):               #  a = now;  b = year_born
    result = a - b
    return result

# main program
now = 2014
year_born = 2004

# the arguments of minus are 'now' and 'year_born'
age = minus( now, year_born )    # assign 'result' to the variable 'age'
print( age )

for loop

With for loops we can repeat a group of instructions many times. We saw that the following two pieces of code do the same thing:

Show it to me


for i in range( 0, 4 ):
     move()
     put()


move() # 1 time
put()

move() #2 times
put()

move() # 3 times
put()

move() # 4 times
put()


Now we’ll see why. In Python, for loops often use the function range(a, b), which returns a list of numbers where a is the first number that we want, and b is the first number that we do not want. For example, to get a list with the numbers from 0 to 4 (we do not want 5) we use:

print( range( 0, 4 ) )
>>> [ 0, 1, 2, 3 ]

Hence, when we call range() inside a loop we get a list, e.g., these are equivalent pieces of code:


for i in range( 0, 4 ):
     move()
     put()


for i in [0, 1, 2, 3]:
     move()
     put()


The for loop sets up the variable i to be each value of the list, in succession. Hence, the three following three pieces of code are equivalent:


Show it to me

for i in range( 0, 4 ):
    print(i)
    move()
    put()


show it to me

for i in [0,1,2,3]:
    print(i)
    move()
    put()


Show it to me

i = 0
print(i)
move()
put()

i = 1
print(i)
move()
put()

i = 2
print(i)
move()
put()

i = 3
print(i)
move()
put()


Training Missions

3.TM1 Life in SoCal – Football

Work it out

It is no surprise that a football player as skilled as Karel is being courted to play in different leagues. The canadian football fields are larger than the american ones. Help Karel run some reconnaissance on the perimeter of each field. Most of the program is already written; we need to write the functions that find the perimeter and announce the result.

American football field

American football field

The perimeter of a rectangle is the sum of the length of all its sides, e.g., if its width it 5 ft. and its length is 10 ft. then its perimeter is:

perimeter = 2 * 5 + 2 * 10    # asterisk * is multiplication
          = 30                # 30 ft.

Answer: Show it to me

def rectangle_perimeter( width, height ):
    # the asterisk * is the multiplication operator
    perimeter = 2 * width + 2 * height    
    return perimeter

def announce( league, perimeter ):
    msg = "The " + league + " field has a perimeter of "
    msg = msg +  str(perimeter) + " ft."
    print( msg )

# main program
league_1 = "National football league"
w = 160  # ft.
h = 360   # ft.
nfl_perim = rectangle_perimeter( w, h ) 

league_2 = "Canadian football league"
w = 195  # ft.
h = 450   # ft.
canadian_perim = rectangle_perimeter( w, h )

announce( league_1, nfl_perim )
announce( league_2, canadian_perim )

3.TM2 Olympic dreams – Mountain training

Work it out

Karel has seen the benefits of mountain training. Now that he is in the downhill team, he is helping to prepare the course for his teammates. Karel needs to climb the mountain and place a marker at each level so that his teammates get oriented as to where they are: he needs to place 1 marker at elevation 1, 2 at elevation 2, and so on. After Karel is done, he needs to go home and ask for a replenishment of the markers that he used, so he can mark another course some other day. It goes without saying that Karel cannot fly; he has to go up and down the steps.

Jenny Hadfield - Image from runnersworld.com

Jenny Hadfield – Image from runnersworld.com

We have been using the variable i as the index of the loop. Here we will need variables that take two other roles.
The first one is a counter, which is a variable that keeps track of how many times we have iterated over a loop:

let me try

counter = 0
for i in range( 0, 5 ):
    counter = counter + 1
    print( "index = " + str(i) + ", counter = " + str(counter) )

In a for loop, there is usually a close relationship between the index of the loop i and the counter, but there does not need to be.

The second structure that we need is an accumulator, which is a variable that accumulates some value:

let me try

accum = 0
for i in range( 0, 5 ):
    accum = accum + i
    print( "index = " + str(i) + ", accum = " + str(accum) )

Often we accumulate some value that depends on i, but this does not need to be the case.

Answer: Show it to me

Before...

Before…

...and after.

…and after.

3.1 Strawberries – Fertilizer tryout

Work it out

Karel is trying out a new fertilizer. The manufacturer left 50 bags for Karel but we only need a few of them. Use input() to tell Karel a number between 0 and 50; he needs to move these many bags to the shed, then go home, and then use say() to confirm the number of bags that he moved to the shed.

fertilizer tryout

Answer: Show it to me

We ask Karel to take 12 bags to the shed

We ask Karel to take 12 bags to the shed


Job well done

Job well done

3.2 Strawberries – Single file

★★ Work it out

Karel wants to plant strawberry plants in each of the 7 cells in front of his house. This time, though, he has a strategy for planting them: he will place 1 plant in the farthest cell from his house and then, as he approaches the house, he will place one more plant in each cell than he placed in the preceding cell, i.e., he will plant, 1, 2, 3, 4, 5, 6, and 7 plants in the 7 cells in front of his house. Keep track of how many strawberries he has planted and announce the total when he gets home.

Notice the pattern: if he deposited i plants in a cell, Karel will deposit i+1 plants in the next cell, i.e.,
1, 2, 3, 4, 5, etc.

Strawberry, ''gariguette'' variety Copyright © 2005 David Monniaux

Strawberry, ”gariguette” variety Copyright © 2005 David Monniaux

Answer: Show it to me

Plant the strawberries in front of the house

Plant the strawberries in front of the house

Ha!  Done.

Ha! Done.

3.3 Strawberries – single file harvest

★★★ Work it out

The strategy of Karel worked out: it turns out that the more plants you put together, the more strawberries you get; in each grid we got the square of the number of plants that we initially planted, i.e., if we planted 5 plants, we got 5 x 5 = 25 strawberries; if we planted 6, we got 6 x 6 = 36 strawberries, and so on.

Notice the pattern: if he picked up i plants from a cell, Karel will picked up i*i plants from the next cell, i.e., 1, 4, 9, 16, 25, …

Have Karel pick up all the strawberries and put 120 in the fridge, in the shed. The rest he takes home to bake a pie.

"Strawberry Cheese Pie" by Own work - Own work. Licensed under Creative Commons Attribution 2.5 via Wikimedia Commons

“Strawberry Cheese Pie” by Own work – Own work. Licensed under Creative Commons Attribution 2.5 via Wikimedia Commons

Answer: Show it to me

Collect the strawberries, put 120 in the shed and take the rest home to bake a pie.

Collect the strawberries, put 120 in the shed and take the rest home to bake a pie.

Final scenario

Final scenario

Optional Mission – Does not give a star

3.4 Life in SoCal – Binary harvest

★★★★ Work it out

Karel is encouraged by his success with the single line crop and increasing crop sizes. He has bought fertilizer to follow this strategy further. He bought lots of fertilizer of increasing size, this time each twice as big as the previous one, i.e., lots of 1, 2, 4, 8, 16, … etc. Please, move the bags to the sheds and go home to announce how many bags we got in total.

Notice the pattern: if he move i bags to a shed, Karel will move i+i bags to the next shed, i.e., 1, 2, 4, 8, 16, …

Image from vegetable-garden-basics.com

Image from vegetable-garden-basics.com

Answer: Show it to me

Before

Before

..and after

..and after