This is the solution to Exam 1: Problems.

The following figure illustrates the grade distribution for the midterm exam.

This is the first (and last) midterm exam of this course, covering lectures 1-6. Please submit your answers to each of the following questions in a single readme.md file, in ECL2017S/exams/1/ directory in your private repository for this course. Don’t forget to push your answers to your remote Github repository by the end of the exam.

1.  Name the closest programming language to machine code, and the oldest high-level programming language in history, respectively.

2.  Name a programming language ancestor of Python.

3.  Name the three different generations (not different software) of Version Control Systems ever developed. If you don’t remember the exact names, you can instead briefly explain how each VCS paradigm works.

Local VCS, Centralized VCS, Distributed VCS. For details of each VCS paradigm see this lecture.

4.  What is the Git command that lists ALL tags in the project?

git tag


5.  Write a single-line python script, that applies the relevant Python string manipulator methods to this string,

Python Is Great For String Manipulation.


and transforms it to the following string and and prints it on screen,

.noitalupinam-gnirts-rof-taerg-si-nohtyp


print( "Python Is Great For String Manipulation.".lower().replace(' ','-')[::-1] )

.noitalupinam-gnirts-rof-taerg-si-nohtyp


6.  Name the three major types of programming errors.

syntax, runtime, and semantic errors.

7.  Are tuples mutable objects? Can they be redefined?

No. Yes.

8.  Download this code. This code is full syntax errors. Fix the errors and submit the corrected code with name script_full_of_errors_corrected.py in your exams/1/ folder of your project. Explain in front of each corrected Python statement, why the error occurred. On the last line of the script,

true = fox is rev in Persian


the statement runs without error. But can you explain what it does?

The corrected file can be downloaded from here.
The last line of the script, first compares the identity of fox with rev, the result of which is either True or False, then checks if this result is in the list Persian.

9.  (A) In the following code,

In [26]: a = [1,2,3,4,5]

In [27]: b = a

In [28]: b
Out[28]: [1, 2, 3, 5]

In [29]: b.append(6)

In [30]: a
Out[30]: [1, 2, 3, 5, 6]


explain the relationship between a and b (why does a change from line 25 to line 30?).

(B) Continuing with the above code,

In [31]: b = a + a

In [32]: a
Out[32]: [1, 2, 3, 5, 6]

In [33]: b
Out[33]: [1, 2, 3, 5, 6, 1, 2, 3, 5, 6]


explain why the values of b and a are different?

Simple.
(A) b is an alias for the content of a.
(B) When b is redefined in line 31, the alias between b and a is automatically broken.

10.  Are the following variable assignments considered an alias for the same value (list), or independent copies of the list?

a = b = c = [1,2,3,4]


If they constitute an alias, how can you assign independent copy of the values of one variable (e.g., c) to another variable (e.g., a)? Otherwise, if the above assignment, creates independent copies, how would you change the assignment, such that they becomes aliases for the same value?

Multiple assignment statements result in aliases for list values. To make hard copies, use the following copy() method:

In [45]: a = b = c = [1,2,3,4]

In [46]: a is b
Out[46]: True

In [47]: a = b.copy()

In [48]: a is b
Out[48]: False

In [49]: a
Out[49]: [1, 2, 3, 4]

In [50]: b
Out[50]: [1, 2, 3, 4]

In [51]: a == b
Out[51]: True


11.  Write a Python program, find_primes.py, that when executed, asks the user to enter an integer number, then the program prints on screen all the prime numbers smaller than the input integer number.
(Hint: Start with writing a function that finds whether an input integer number is prime or not, then write another function that repeatedly calls this function to find all the prime numbers smaller than the initial input number.)

Here is a sample output from the code:

Enter an integer number: 50
Here is a list of all prime numbers smaller than 50:
47
43
41
37
31
29
23
19
17
13
11
7
5
3
2


12.  (A) Rewrite the following statement in two different but equivalent ways:

1. A one-line if-expression.
2. Using only tuple notation, instead of if-block or if-expression syntax.
#!/usr/bin/env python

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

if abbr == 'ECL':


(B) Which one of the above two methods, would also be applicable to the following if-block + print statements. Rewrite it in whichever format that is suitable.

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


(A)

#!/usr/bin/env python
abbr = input ("What is the three letter abbreviation of this course? ")
answer_status = 'correct' if abbr == 'ECL' else 'wrong'


or,

#!/usr/bin/env python
abbr = input ("What is the three letter abbreviation of this course? ")


(B)

#!/usr/bin/env python
abbr = input ("What is the three letter abbreviation of this course? ")
print( ('wrong buddy...try again','You answer is correct!')[answer_status=='correct'] )


or,

#!/usr/bin/env python
abbr = input ("What is the three letter abbreviation of this course? ")
print( 'You answer is correct!' if answer_status=='correct' else 'wrong buddy...try again' )


13.  Consider the following two Python expressions,

(1,1) is (1,1)
(1,1) == (1,1)


Are these two the same? Explain your answer.

The keyword is checks for the same identity of the objects that are compared. The operator == checks for the same value of the objects.

14.  Consider the following function which takes another function as input:

def diff2nd(func, x, h=1E-6):
r = (func(x-h) - 2*func(x) + func(x+h))/float(h*h)
return r

x = 2
diff2nd_g = diff2nd(g, x)
print ( "g’’(x=%f)=%f" % (x, diff2nd_g) )


Write a lambda function as an input to this function, that calculates the function value $x^2 + 4x + 1$.

g = lambda x: x**2 + 4.0*x + 1.0


15.  The traditional way of swapping values of two variables in most programming languages is like the following,

In [68]: a = 5

In [69]: b = 7

In [70]: _ = a

In [71]: a = b

In [72]: b = _

In [73]: a
Out[73]: 7

In [74]: b
Out[74]: 5


Rewrite the swapping above, in a more abbreviated Pythonic way, once using lists, and another using tuples.

In [75]: (a,b) = (b,a)

In [76]: a
Out[76]: 5

In [77]: b
Out[77]: 7

In [78]: [a,b] = [b,a]

In [79]: a
Out[79]: 7

In [80]: b
Out[80]: 5