10.2. Solutions to Chapter 4 Exercises#

10.2.1. Exercise 1#

In this exercise we want to determine if a number is positive (>0) or not. Write a function that will return a value based on whether the number is positive or not. Then try it out with different arguments.

def is_positive(x):
    is_positive = False
    if(x>0):
        is_positive = True
    return is_positive
print(is_positive(5))
print(is_positive(-5))
True
False

10.2.2. Exercise 2#

Write a function that will receive an arbitrary number of integer arguments and will compute their average. Test it with different numbers of arguments.

def find_average(*args):
    sum = 0
    no_elements = 0
    for no in args:
        sum = sum + no
        no_elements = no_elements + 1
    return sum / no_elements
print(find_average(1,2,3))
print(find_average(1,2,3,4,5))
2.0
3.0

10.2.3. Exercise 3#

Suppose that we have the following piece of code:

def find_square(x):
return x**2

print(find_square(2))

Do you think it will run? Explain your reasoning.

These code snippet is violating the indentation rules. When trying to run it, it will give an IndentationError because the return statement is at the same indentation level as the function definition, thus it is not inside the function.

10.2.4. Exercise 4#

Suppose that we have the following piece of code:

def function_xyz(x,y,z):
    x = 5
    
    if(y>0):
        a = x*3
    else:
        b = z*2
    
    return a*b


print(function_xyz(1,2,3))
print(function_xyz(1,-2,3))
print(function_xyz(1,0,3))

Do you think any of the function calls will execute correctly? Explain your reasoning.

In this case, none of the function calls will be able to execute correctly because either a or b will not have been initialized. In the first case, x=1, y=2 and z=3. The first statement in the function block is executed and it shadows argument x. So x will have the value 5. Then y=2 implies that y>0 is true, so a will be 15. b will not be initialized since the else block is skipped. When it comes to the return statement, an error will be thrown because we are trying to access b without ever initializing it in any part of the code. In the second case, the same logic follows, but instead of b now a will not be initialized because the condition y>0 will fail since y=-2. So the code will fail trying to access a in the return statement. The second and the third cases have the same failure reasoning.

10.2.5. Exercise 5#

Suppose that we have the following piece of code:

def function_xyz(x,y,z):
    x = 5
    
    if(y>0):
        a = x*3
    if(z>0):
        b = z*2
    
    return a*b


print(function_xyz(1,2,3))
print(function_xyz(1,-2,-3))

Do you think any of the function calls will execute correctly? Explain your reasoning.

This is similar to the previous exercise. However, note that now we are checking for the value of z as well. In the first function call, we are passing arguments: x=1, y=2 and z=3. The value of x does not have any effect since we are changing it to 5 in the first statement in the function block. Then we go and check if y>0, which is true, thus a is initialized to 15. Next, we go and check if z>0, which is true, thus b is initialized to 6. In the end we return the product of 15*6 = 90. Note how we are able to access variables declared within if blocs outside of these blocks but inside the function. In the second case, both y and z are negative, so both condition is the if statements fail, so none of a and b will be initialized. In the return statement, when the interpreter will try to access a, since it will not have been initialized an error will be thrown and the execution will stop.

10.2.6. Exercise 6#

Remember the Christmas tree we were trying to build on exercise 6 of chapter 3? Now we want to be more flexible and based on our available space build different-sized Christmas trees, not only with 5 stars. Modify the following code so that it takes different numbers, and using them builds Christmas trees of different sizes. (You need to substitute only the question marks.)

def build_christmas_tree(length):
    for i in range(0,length):
        for j in range(0,(i+length)):
            if j>=(length-(i+1)):
                if (j%2==0 and i%2==0) or (j%2==1 and i%2==1):
                    print('*', end='')
                else:
                    print(' ', end='')
            else:
                print(' ', end='')
        print(' ')
length_of_christmas_tree = 20
build_christmas_tree(length_of_christmas_tree)
                     
                   *  
                  * *  
                 * * *  
                * * * *  
               * * * * *  
              * * * * * *  
             * * * * * * *  
            * * * * * * * *  
           * * * * * * * * *  
          * * * * * * * * * *  
         * * * * * * * * * * *  
        * * * * * * * * * * * *  
       * * * * * * * * * * * * *  
      * * * * * * * * * * * * * *  
     * * * * * * * * * * * * * * *  
    * * * * * * * * * * * * * * * *  
   * * * * * * * * * * * * * * * * *  
  * * * * * * * * * * * * * * * * * *  
 * * * * * * * * * * * * * * * * * * *