This is the solution to Homework 5: Problems - Python branching and functions.

The following figure illustrates the grade distribution for this homework.

Maximum possible points is 100.



This homework aims at giving you some experience with variables in Python and their syntax, also some experience with using Lists and Dictionaries in Python. Write your Python scripts with the corresponding *.py file names, and add a readme.md file in HW 5 folder of your project if you need to add any additional explanation (Don’t forget to use markdown syntax highlight in your readme file, if needed).





1.  In mathematics, the Fibonacci numbers are the numbers in the following integer sequence, called the Fibonacci sequence, that are characterized by the fact that every number after the first two is the sum of the two preceding ones:

with the following sequence equation,

Write a Python function named fib that takes in an input argument which should be integer number n, and then calculates the $n^{th}$ number in the Fibonacci sequence and outputs it on the screen. Also, if the input argument is not a non-negative integer, it prints an error message on the screen and asks the user to re-enter a non-negative integer number. Also, when it is done with finding the requested Fibonacci number, it asks again the user to either input a new non-negative integer, or enter ‘stop’ to end the function, like the following,

>>> fib('amir')
The input argument amir is not a non-negative integer!
Please enter a non-negative integer: -123
The input argument -123 is not a non-negative integer!
Please enter a non-negative integer: 12.4
The input argument 12.4 is not a non-negative integer!
Please enter a non-negative integer: 0
Fib(0) = 0
Please enter another non-negative integer or type stop: 1
Fib(1) = 1
Please enter another non-negative integer or type stop: 2
Fib(2) = 1
Please enter another non-negative integer or type stop: 3
Fib(3) = 2
Please enter another non-negative integer or type stop: 4
Fib(4) = 3
Please enter another non-negative integer or type stop: 5
Fib(5) = 5
Please enter another non-negative integer or type stop: 6
Fib(6) = 8
Please enter another non-negative integer or type stop: 7
Fib(7) = 13
Please enter another non-negative integer or type stop: 8
Fib(8) = 21
Please enter another non-negative integer or type stop: 9
Fib(9) = 34
Please enter another non-negative integer or type stop: 10
Fib(10) = 55
Please enter another non-negative integer or type stop: 11
Fib(11) = 89
Please enter another non-negative integer or type stop: 12
Fib(12) = 144
Please enter another non-negative integer or type stop: stop

Hint:

  1. First write a function fibo(n_int) that finds the requested Fibonacci number for you, given a non-negative integer input (for example, name it n_int).
  2. Then put this function inside another Python function fib(n) that checks the type of the input argument n and prints the appropriate error message as in the above and then asks the user to enter another number (and then again checks for its type to be integer).
  3. Then if this number is an integer, this function fib(n) passes the integer number n to the function fibo(n_int) which is inside of itself (it is a nested function), in order to get the requested Fibonacci number.
  4. Finally, once the requested Fibonaccy number is obtained, it prints the number value with the requested format as in the above example, AND then asks again the user to input a new non-negative integer, or simply type stop to stop the function.

Note that, if you call the function as fib('stop') in the Python interpreter, it should return nothing to you, just like the following example,

fib('stop')


I highly recommend you to write your function in Jupyter notebook, test it there, and then get the results for the same input arguments as in the above example (a string, negative integer, float, and n=1,…,12, and also ‘stop’) and download all of the notebook as a Markdown file, and put it in your repository folder for this homework. Name the notebook, fib.md.

Also note that, you don’t need to know or use anything beyond Python function syntax, Python built-in functions and methods (like input, isdigit(), print, str(), int(), …), and Python if-blocks.

I recommend you to use Jupyter notebook on your device, since the online version of notebook, can be interrupted repeatedly because of internet connection.


Answer:

def fib(n):

    def fibo(n_int):
        if n_int==0: return 0
        elif n_int==1: return 1
        else:
            return fibo(n_int-1) + fibo(n_int-2)

    if n=='stop':
        return None
    elif not str(n).isdigit():    # Make sure n is integer, if not then
        print( 'The input argument {} is not a non-negative integer!'.format(n) )    
        n = input("Please enter an integer: ")  # Note that n is read as string!
        return fib(n)
    else:
        n=int(n) 
        print('Fib({}) = {}'.format(n,fibo(n)))
        n = input("Please enter another integer or type stop: ")  # Note that n is read as string!
        return fib(n)





2.  Branching…, the Pythonic way.

(A) Change the first if statement in the following script to an equivalent one-line if-expression. Test the resulting new script, and make sure it behaves as the original,

#!/usr/bin/env python

abbr = input ("What is the three letter abbreviation of this course? ")

answer_status = 'wrong'
if abbr == 'ECL':
    answer_status = 'correct'

if answer_status=='correct':
    print('You answer is correct!')
else:
    print("wrong buddy...try again")


(B) Can you acheive the same goal as in (A) without if-expression or block, but instead using only tuple notation? Explain why your solution works.

Modify the if block and the print statements that are only in the last part of the code,

if answer_status=='correct':
    print('You answer is correct!')
else:
    print("wrong buddy...try again")


to write a single-line Python statement that only uses print and tuple or list notations, to perform the exact same task as the original print and if-block statement.


Answer:

(A)

#!/usr/bin/env python

abbr = input ("What is the three letter abbreviation of this course? ")

answer_status = 'correct' if abbr == 'ECL' else 'wrong'

if answer_status=='correct':
    print('You answer is correct!')
else:
    print("wrong buddy...try again")


(B)

#!/usr/bin/env python

abbr = input ("What is the three letter abbreviation of this course? ")

answer_status = ('wrong','correct')[abbr=='ECL']

if answer_status=='correct':
    print('You answer is correct!')
else:
    print("wrong buddy...try again")


(C)

#!/usr/bin/env python

abbr = input ("What is the three letter abbreviation of this course? ")

answer_status = ('wrong','correct')[abbr=='ECL']

print( ('wrong buddy...try again','You answer is correct!')[answer_status=='correct'] )






3. 

(A) Write a single-line Python code that reads a string containing comma-separated first-name, last-name, and the city in which a person lives from the Python interpreter command line, and simultaneouly, in the same line of Python code, removes all white-space characters from the input string, and converts all letters of the input variables to lower-case, and converts the string to a tuple and saves in a tuple (first,last,city), such that, for example,

Enter the first name, last name, and the city of the person (comma-separated): Amir, Shahmoradi  ,  Austin


would give,

(first,last,city)
('amir', 'shahmoradi', 'austin')

Hint: Use input function for this purpose. The output of input is a string, which can be manipulated repeatedly on the same line, using multiple string methods that you learned about in the previous lectures.

(B) As discuss in our lecture 6, the one-line if-expression syntax does not provide a functionality like elif keyword as in the if-statement syntax. Our goal here is to learn how to convert a Python if-statement containing elif to a one-line Python expression. Convert the following if-block to a single line if-expression. Modify the if-block inside the following function to one-line if-expression:

def dummy(i):
    if i==0:
        j=0
    elif i==1:
        j=1
    elif i==2:
        j=2
    else: j = 'j is not in [0,1,2]' 
    return j

Answer:

(A)

(first,last,univ) = ((input('Enter the first name, last name, and the city of the person (comma-separated): ').replace(' ','')).lower()).split(',')


(B)

def dummy(i):
    j = 0 if i==0 else (1 if i==1 else (2 if i==2 else 'j is not in [0,1,2]') )
    return j





4.  An arbitrary triangle can be described by the coordinates of its three vertices: $(x1,y1),(x2,y2),(x3,y3)$, numbered in a counterclockwise direction. The area of the triangle is given by the formula,

Write a function get_triangle_area(vertices) that returns the area of a triangle whose vertices are specified by the argument vertices, which is a nested list of the vertex coordinates. Test your implementation with the following test function, which also illustrates how the get_triangle_area function works.

def test_get_triangle_area():
    """
    Verify the area of a triangle with vertex coordinates
    (0,0), (1,0), and (0,2).
    """
    v1 = (0,0); v2 = (1,0); v3 = (0,2)
    vertices = [v1, v2, v3]
    expected = 1
    computed = get_triangle_area(vertices)
    tol = 1E-14
    success = abs(expected - computed) < tol
    msg = 'computed area=%g != %g (expected)' % (computed, expected)
    assert success, msg


Answer:

def get_triangle_area(vert):
    area = 0.5 * abs(vert[1][0] * vert[2][1] - vert[2][0] * vert[1][1] -
                     vert[0][0] * vert[2][1] + vert[2][0] * vert[0][1] +
                     vert[0][0] * vert[1][1] - vert[1][0] * vert[0][1])
    return area





5.  Write a logical (boolean) function named is_prime(n) that takes in an integer number n, and finds whether it is a Prime number or not. Example output is the following,

is_prime(n=23)
True
is_prime(12)
False

Note that you do not need and don’t have to use for-loop for this problem (we have not yet discussed loops in our class!). All of it can be done using recursive function concept.

Answer:

def is_prime(n):
    
    is_prime = True
    
    def is_divisible(n,divisor):
        if n<(divisor-1)*divisor: return False
        if n%divisor==0: return True
        else:
            divisor += 1
            return is_divisible(n,divisor)

    if is_divisible(n,divisor=2): is_prime=False
    return is_prime



Comments