pm21-dragon/exercises/release/exercise-02/1 - Python Basics - Variables and Functions.ipynb
Andrew Straw a254b5cb90 lecture 1
2024-10-18 09:44:25 +02:00

20 KiB

None <html> <head> </head>

Python Basics - Variables and Functions

In [ ]:
# You must run this cell, but you can ignore its contents.

import hashlib

def ads_hash(ty):
    """Return a unique string for input"""
    ty_str = str(ty).encode()
    m = hashlib.sha256()
    m.update(ty_str)
    return m.hexdigest()[:10]

Problem 1 - variable assignment

Assign a value of 42 to the variable named x.

In [ ]:
# YOUR CODE HERE
raise NotImplementedError()
In [ ]:
# This checks that the above worked
assert ads_hash(x)=='73475cb40a'

Problem 2 - solving exceptions

Modify the following so that it runs without an "exception" (an error in Python):

y = 2 plus 2
In [ ]:
# YOUR CODE HERE
raise NotImplementedError()
In [ ]:
# This checks that the above worked
assert ads_hash(y)=='4b227777d4'

Problem 3 - using the Python Tutor

Run the following code at the Python Tutor.

  1. Click on "Visualize your code and get live help now" in the Python Tutor website.
  2. Copy this code into your clipboard:
    x = 42
    y = x + 42
    
  3. Paste it into the edit window of the Python Tutor.
  4. Click the "Visualize Execution" button of the Python Tutor.
  5. Click the "Next button" until all steps are done.

For great insight, run all the problems in this exercise in the Python Tutor and carefully watch what is happening. This will be a massive help for you understand what your programs are doing

How many variables are in the global frame? Assign the answer to the variable named answer.

In [ ]:
# YOUR CODE HERE
raise NotImplementedError()
In [ ]:
# This checks that the above worked
assert ads_hash(answer)=='d4735e3a26'

Problem 4 - functions

Here is an example function named double that has one input named x and returns x*2 (x times two).

def double(x):
    return x*2

Remember that all functions in python are defined with the def word, then the name of the function, then zero, one, two, or more arguments in parentheses, then a colon. The body of the function must be in a block - a group of lines with the same indentation.

Now, make a function named triple that has one input named x and returns x*3.

In [ ]:
# YOUR CODE HERE
raise NotImplementedError()
In [ ]:
# This checks that the above worked
assert ads_hash(triple(3))=='19581e27de' 
assert ads_hash(triple(4))=='6b51d431df'
assert ads_hash(triple(5))=='e629fa6598'

Problem 5 - functions with multiple arguments

Here is an example function named my_func that takes two inputs, x and y and does a bit of math on the inputs:

def my_func(x,y):
    return x + 2*y

Make a function named foo which returns five times the first argument plus three times the second argument.

In [ ]:
# YOUR CODE HERE
raise NotImplementedError()
In [ ]:
# This checks that the above worked
assert ads_hash(foo(3,10))=='811786ad1a'
assert ads_hash(foo(10,3))=='3e1e967e9b'
assert ads_hash(foo(13,2302))=='5f7635b6a1'

Problem 6 - calling functions from functions

We can call functions from within functions.

Here are two example functions named double and double_twice

def double(x):
    return x*2

def double_twice(x):
    y = double(x)
    z = double(y)
    return z

Re-use your function triple from above and make a function named triple_thrice which calls triple three times repeatedly on its input value.

In [ ]:
# YOUR CODE HERE
raise NotImplementedError()
In [ ]:
assert ads_hash(triple_thrice(3))=='5316ca1c5d'
assert ads_hash(triple_thrice(4))=='9537f32ec7'

Problem 7 - variable scopes

Functions are also useful because they let you "hide" variables so they do not "pollute" other parts of your code. In other words, functions let you make modular pieces of code which do not affect each other.

Consider this piece of code, and think about the value of x throughout the code.

x = 43

def blah(x):
    x = x - 26
    return x

blah(2)

x

In the very last line, what is the value of x?

In the very last line, x has a value of 43. However, inside the function there is a local variable, also named x, which can have a different value. Changes to this local variable x in the function do not affect the x in the global frame. (This could also be called the global scope. "Frame" and "scope" are synonyms.)

Inside a function, variable from the outside frame can be read if there is no local variable in the function with the same name. Consider this code. Here we will read the variable x inside the function because we have no argument or other local variable named x.

x = 43

def blah(y):
    z = x - y
    return z

q = blah(2)

What is the value of q?

The value of q here will be 41.

Advanced: Frames can be nested - for example if you call a function named function2 from another function named function1, the frame of function2 will be created while the frame of function1 continues to exist.

In this second example, y is defined only inside the function. What is it's value in the function? Assign your answer to the variable y.

In [ ]:
# YOUR CODE HERE
raise NotImplementedError()
In [ ]:
assert ads_hash(y)=='d4735e3a26'

Problem 8 - return values of functions

To return a value, a function must use the keyword return. Otherwise, the special python type None is returned. Check these two functions out:

def func_one(x):
    return x*10

def func_two(x):
    x*10

What is the result of func_one(10)? It is 100. What is the result of func_two(10)? It is None, a special type in Python which means "nothing".

Taking this as a starting point, fix the my_triple function so that it returns the value of x*3.

def my_triple(x):
    x*3
In [ ]:
# YOUR CODE HERE
raise NotImplementedError()
In [ ]:
assert ads_hash(my_triple(100))=='983bd614bb'

Problem 9 - print() is not return

One thing that can be confusing is the difference between the return value of a cell in Jupyter notebook - which gets displayed automatically and the use of the built-in print() function.

print(1234)

Will print 1234 but has no return value. This can be tricky in functions.

Consider this function

def my_great_function(a):
    print(a*30)

What does this function return?

It returns None.

Now make a function called my_even_better_function which returns the value of its input times thirty.

In [ ]:
# YOUR CODE HERE
raise NotImplementedError()
In [ ]:
assert ads_hash(my_even_better_function(32))=='7f5642cd0c'
</html>