---
tags: Python
---
# Python Self-Check 6
CS 1358 Introduction to Programming in Python
Fall Semester 2022
Prof. Pai H. Chou
Self-Check 1
Due Date: --
Answer the following questions to check your understanding of your material. Expect the
same kind of questions to show up on your tests. For this course, we use vi and vim
interchangeably.
## 1. Definitions and Short Answers
1. Given the following if-statement
```
x = int(input('enter one number: '))
y = int(input('another number: '))
if y == 0:
print('sorry, cannot divide by 0!')
else:
print(f'{x} / {y} = {x/y}')
```
```
What is the purpose of checking if y == 0?
//check if divide by 0
What is the purpose of calling the int() function on the first two lines?
//to cast input type(string) to int
Will the code still work if you replace lines 1-2 with
x = input('enter one number: ')
y = input('another number: ')
instead? Why or why not?
//No,string can't divide
```
2. The following if-statements are not correct in Python syntax. What is wrong with them and how can they be fixed? Do not change the functionality.
```
if y == 0:
# do nothing
else:
print(f'{x} / {y} = {x/y}')
if y != 0:
print(f'{x} / {y} = {x/y}')
else:
# do nothing
if x == 0:
print('zero, without checking y')
else if y == 0:
print('sorry, cannot divide by 0!')
else:
print(f'{x} / {y} = {x/y}')
if y == 0: print('sorry, cannot divide by zero') else:
print(f'{x}/{y}={x/y}')
```
```
#do nothing need to be place by pass
else if need to be place by elif
the last else should be in next line
```
3. Given the dictionary
eng = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
what is the value of the following expressions, and which ones cause errors?
```
## in 代表找dict中的key
4 in eng //False
'three' in eng //True
('two', 2) in eng //False
{'one': 1} in eng //error
eng['three'] //3
eng[0] //key error
eng[1] //key error
eng['two':2] //key error
```
4. Consider the code:
```
english={'one':1,'pan':'鍋子''cabbage':'高麗菜','pie':'派餅'}
spanish = {'uno':1, 'pan':'麵包','col':'高麗菜', 'pie':'腳'}
french = {'une':1, 'toi':'你', 'col':'衣領', 'pie':'鵲'}
word = input('enter word to look up: ')
if word in english:
print(f'in English: {english[word]}')
elif word in spanish:
print(f'in Spanish: {spanish[word]}')
elif word in french:
print(f'in French: {french[word]}')
else:
print(f'{word} not found in dictionary')
```
When running the program, what happens when you type the following text when prompted?
```
uno //in Spanish: 1
pan //in English: 鍋子
toi //in French: 你
pie //in English: 派餅
col //in Spanish: 高麗菜
cabbage //in English: 高麗菜
1 //1 not found in dictionary
ten //ten not found in dictionary
```
5. In Question #4, if you swap lines 7-8 with lines 9-10, will the code output exactly the same results for all inputs or different for some inputs? Which?
```
uno //same
pan //same
toi //same
pie //same
col //in french: 衣領
cabbage //same
1 //same
ten //same
```
6. If the code in Question#4 is modified so all elif clauses get replaced by if, as shown in the following code:
```
if word in english:
print(f'in English: {english[word]}')
if word in spanish:
print(f'in Spanish: {spanish[word]}')
if word in french:
print(f'in French: {french[word]}')
else:
print(f'{word} not found in dictionary')
```
```
Suppose the user enters a word that is in english but not in french, does the print statement on the last line still get executed? Why or why not?
```
```
yes, because the expression if word in french is false, then executed else
```
7. Given the following code
```
passing = False
if int(input('enter grade: ')) >= 60:
passing = True
```
```
what is the equivalent statement that uses both if and else?
//
if int(input('enter grade: ')) >= 60:
passing = True
else:
passing = False
what is the equivalent (assignment) statement that does not use if at all?
//
def grade(a):
return a >= 60
passing = grade(input('enter grade: '))
```
8. Consider the following version of the code
```
word = input('enter word to look up: ')
outList = []
if word in english:
outList.append(f'in English: {english[word]}')
if word in spanish:
outList.append(f'in Spanish: {spanish[word]}')
if word in french:
outList.append(f'in French: {french[word]}')
if not outList:
print(f'{word} not found in dictionary')
else:
print('\n'.join(outList))
```
```
If line 9 is changed to if outList:, then how should the rest of the code be updated so it behaves exactly the same?
//swap line 13 with 15
What does line 12 do?
//output all the value of outList
Is line 2 really necessary?
//Yes
What if line 2 is removed and line 4 is replaced by
outList = [f'in English: {english[word]}']
will the code still work the same way as before? if not, how can it be fixed by adding more code?
//No, if outList find word in english, then the outList will only contain english[word]
```
9. Convert the if-else statement in the previous question (lines 9-12) into a single print() with a conditional expression as its argument.
```
print(f'{word} not found in dictionary' if not outList\
else '\n'.join(outList))
```
10. Convert the if-elif-elif-else statement with four suites in Question#4 (lines 5-12) into a single print() statement whose argument is a conditional expression.
```
print(f'in English: {english[word]}' if word in english \
else f'in Spanish: {spanish[word]}' if word in spanish \
else f'in French: {french[word]}' if word in french \
else f'{word} not found in dictionary')
```
11. Is there a form of conditional expression that uses the elif keyword? If so, provide an example.
```
NO
```
12. Given the following nested if-statement
```
if x < 0:
if y > 3:
print('correct')
```
rewrite it as a single if statement by combining the two conditions
```
if x < 0 and y > 3:
print('correct')
```
13. Given the following function that returns a boolean value:
```
def test(y):
if y % 10:
return False
else:
return True
```
rewrite it as a single return statement by eliminating the if-else construct completely.
```
def test(y):
return (y % 10 == 0)
```
14. Given the following function:
```
def fn(z):
if z % 10:
return True
if z > 400:
return False
return True
```
rewrite it as a single return statement by eliminating all if-constructs completely.
```
def fn(z):
return (z % 10 != 0) or not(z > 400)
```
15. Write a Python function to concatenate a list of strings using a while loop.
```
def concat_str(L): # L is a list of strings
# initialize local variables:
# - an index into L to select one item at a time
# - a result variable initialized to empty string
while ____: # fill in your condition
# concatenate result with the next string in L
# increment the index variable
# return the result string
```
```
def concat_str(L):
index = 0
str = ""
while index < L.size():
str += L[index]
index += 1
return str
```
16. Write a Python function to concatenate a list of strings using a for loop.
```
def concat_str(L): # L is a list of strings
initialize local variables:
# - the result variable initialized to empty string
for ______ : # get one string at a time from L
# concatenate result with string from for loop
# return the result string
```
```
def concat_str(L):
str = ""
for i in L:
str += i
return str
```
17. Given the source code
```
def index(L, val):
i = 0
while i < len(L):
if L[i] == val:
break
i += 1
return i if i < len(L) else -1
```
Rewrite the code so that it does not use a break to exit the loop but still uses the same code as line 7 to return the i value. Hint: you need a separate "flag" variable that can take a True or False value; it should be initialized before the loop and is tested as part of the while-condition. The flag should be set to cause a break out of the loop. Be sure the i value is correct after exiting the loop.
```
def index(L, val):
i = 0
flag = False
while i < len(L):
if L[i] == val:
flag = True
i += 1
return i if flag else -1
```
18. Convert the code from Problem #17 into a while-else construct (where the else clause is associated with the while construct rather than with an if clause)
```
def index(L, val):
while i < len(L):
if L[i] == val:
break
i += 1
else:
return -1
return i
```
19. Convert the code from Problem #17 into a while True: on line 3 and convert the while condition into an if condition inside the loop.
```
def index(L, val):
i = 0
while True:
if L[i] == val or i >= len(L):
break
i += 1
return i if i < len(L) else -1
```
20. Referring to the same code as in Problem #17, what happens if you replace break on line 5 with continue? For example,
```
>>> L = "abaca"
>>> index(L, 'a')
Does the function return a value or go into an infinite loop? Why?
Yes,go into an infinite loop, when execute L[i] == val then continue
>>> L = "abcde"
>>> index(L, 'z')
Does the function return a value or go into an infinite loop and why?
Yes,will return -1, because the i will exceed len(L)
Try to predict the behavior of the code before you try running it to verify your answer.
```
21. In the code
```
def index(L, val):
i = 0
while i < len(L):
if L[i] == val:
break
i = i + 1
else:
return -1
return i
```
What causes the else suite (lines 7-8) to be executed? If line 5 is executed, will line 8 be executed?
```
when i >= len(L)
No
```
22. Given the code
```
ESdict = { 'one': 'uno', 'dos': 'two', 'three': 'tres'}
word = input('enter an English word:')
while word != '':
if word in ESdict:
print(f'{word} in Spanish is {ESdict[word]}')
else:
print(f'{word} not in dictionary')
word = input('enter an English word:')
```
However, there is redundancy because line 2 and line 8 are exactly the same (except for indentation). How can this code be rewritten to eliminate this redundancy?
```
ESdict = { 'one': 'uno', 'dos': 'two', 'three': 'tres'}
while True:
word = input('enter an English word:')
if(word == ''):
break
if word in ESdict:
print(f'{word} in Spanish is {ESdict[word]}')
else:
print(f'{word} not in dictionary')
```
23. Given the following code
```
def StackInterpreter():
L = []
while True:
line = input('command? ')
words = line.split()
if len(words) == 0:
pass
elif words[0] == 'show':
print(L)
elif words[0] == 'push':
L.extend(words[1:])
elif words[0] == 'pop':
print(L.pop())
elif words[0] == 'quit':
break
else:
print('unknown command')
```
If the elif keywords on lines 8, 10, 12, 14 are replaced by if, will the code still behave the same way as far as the user is concerned? Why?
```
No, it will always print unknown command
```
24. Using the same code from the previous problem, line 7 can be replaced by a single-keyword statement and the code still behaves the same way to the user. What is the keyword? Explain.
```
continue, because continue statement will execute next loop
```
25. Using the same code from the previous problem, line 15 can be replaced by a single-keyword statement and the code still behave the same way. What is it?
```
return
```
26. Given the code
```
def StackInterpreter():
L = []
while True:
line = input('command? ')
words = line.split()
if len(words) == 0:
continue
if words[0] == 'show':
print(L)
continue
if words[0] == 'push':
L.extend(words[1:])
continue
if words[0] == 'pop':
print(L.pop())
continue
if words[0] == 'quit':
break
print('unknown command')
```
Why doesn't line 19 need to be inside an else-clause but can be an unconditional statement at the same level as all preceding if-statements?
```
because every command will goes into if and execute continue
```
27. Given the Python code
```
def product(L):
p = 1
for i in range(len(L)):
p = p * L[i]
return t
```
```
Rewrite it as a while-loop
//
def product(L):
p = 1
i = 0
while i < len(L):
p = p * L[i]
i += 1
return p
Rewrite it as a Pythonic for-loop
//
def product(L):
p = 1
for i in L:
p = p * i
return p
```
28. What is the value of the expression
```
list(enumerate("abcde"))
//[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]
list(enumerate(range(5, 10)))
//[(0, 5), (1, 6), (3, 7), (4, 8), (5, 9)]
list(enumerate(['Sun', 'Mon', 'Tue', 'Wed']))
//[(0, 'Sun'), (1, 'Mon'), (2, 'Tue'), (3, 'Wed')]
list(enumerate(['Jan', 'Feb', 'Mar'], start=1))
//[(1, 'Jan'), (2, 'Feb'), (3, 'Mar')]
```
29. Rewrite the following code using a Pythonic for-loop:
```
def find(L, val):
i = 0
while i < len(L):
if L[i] == val:
return i
i = i + 1
return -1
```
```
def find(L, val):
i = 0
for i, ele in enumerate(L):
if(ele == val):
return i
return -1
```
## 2. Programming
1. Write a Python program named dateconv.py to prompt the user for date in US format of mm/dd/yyyy (e.g., '02/15/2019' and outputs it in the full format of 'February 15, 2019'. You may assume the dates are given as decimal literals separated by '/', but you should also check if the dates are in range. If the dates are out of range, then you should inform the user what is wrong. For instance
$ python3 dateconv.py
enter date in mm/dd/yyyy: 02/15/2019
February 15, 2019
enter date in mm/dd/yyyy: 02/29/2019
Invalidate day 29 for February: not a leap year
enter date in mm/dd/yyyy: 01/01/2001
January 1, 2001
enter date in mm/dd/yyyy: 13/10/2038
Invalid month 13: should be between 01 and 12
enter date in mm/dd/yyyy: 10/32/2019
Invalid day for October: should be between 01..31
enter date in mm/dd/yyyy: 04/31/2019
Invalid day for April: should be between 01..30
enter date in mm/dd/yyyy: quit
bye
$ _
Hint: Build up your program one piece at a time. First, simply use a loop to prompt for input and check for 'quit'. If not quit then first use a print statement to check if the input is as you expect. Once confirmed, you can use str's split() method to split a string by its separator ('/' in this case). Then, you can check the array of strings, assuming you can convert them to int, and check if each one is within range. Month can be checked easily. Day depends on the month, and for the month of February, day also depends on whether the year is a leap year (28 or 29 days). If any field is invalid, then report the error and loop again. If all fields are correct then display the full month string.
You may store the names of the months all in a list indexed by the month number or in a dictionary keyed by the month. You may use the leap year function from a previous lecture.
## 3. Small Programming Project
[somewhat challenging] Write a Python program named long_multiply(a, b) to return a string that shows the steps in a long multiplication. (note: a is called the multiplier, and b is the multiplicand) For example
```
>>> print(long_multiply(12, 34))
12
x)34
----
48
36
----
408
```
Hint: You should construct the return value of the function by concatenating different strings together. It is probably easier if you just append the strings into a list and join them by '\n'.join(listOfStrings).
Before you join the strings, you need to determine the width to format each line. This is the maximum number of characters needed to represent the multiplier, multiplicand + 2 (because 'x)' takes two positions), and the product.
Create the following strings and append each one into a list:
string for the multiplier with the width (right aligned),
'x)' concatenated the multiplicand formatted with width-2 (also right-aligned),
string of '-' repeated for width times
loop over the partial products of multiplier * each digit of the multiplicand, but each time shifted one position to the left.
anotherr string of '-' repeated for width times
finally, the product as a string, formatted to the same width, right aligned.
finally, return '\n'.join( list of strings created in above steps )
Note: you may assume a and b are both nonnegative integers. Your code should work with integers of any number of digits.