---
tags: Python
---
# Python Self-Check 12
CS 1358 Introduction to Programming in Python
Fall Semester 2022
Prof. Pai H. Chou
Self-Check 12
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 a for loop:
```
for i in L:
print(i)
```
Can L be the following? If so, what does the loop print? If not, why not?
```
a. ['a', 'b', 'c']
//Yes a b c
b. ('a', 'b', 'c')
//Yes a b c
c. 'abc'
//Yes a b c
d. {'a', 'b', 'c'}
//Yes, non-sequence we don't know order
e. {'a': 100, 'b': 200, 'c': 300}
//Yes non-sequence we don't know order
f. 0xabcd
//No,int can't iterable
g. range(3)
//Yes 0 1 2
h. 23+4j
//No,complex can't iterable
```
2. Given an iterable data structure L,
```
a. How do you obtain an iterator r of L?
//iter(L)
b. Once you have an iterator r, what can you do to get the next value?
//next(r)
c. What happens when you call next(r) but your iterator r has finished iterating over all values of L?
//StopIteration
d. Is there a limit to the number of iterators that you can create on the same iterable?
//no
```
3. Assume you have
```
D = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
r = iter(D)
L = [next(r) for i in range(3)]
s = iter(D)
M = [next(s) for i in range(2)]
```
after executing these five lines
```
a. What is the value of L?
//['Sun', 'Mon', 'Tue']
b. What is the value of M?
//['Sun', 'Mon']
c. What is the value of D?
//['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
```
4. Recall the Vector class from the previous lecture,
```
import operator as op
class Vector:
def __init__(self, *v):
self._v = list(v) # covert tuple to list
def __repr__(self):
return __class__.__name__+repr(tuple(self._v))
```
Suppose a class defines an \_\_iter__() special method, and v is an instance of Vector.
```
a. How does Python intend that v's __iter__() special method be invoked by the programmer? Hint: not v.__iter__()
//iter(v)
b. What kind of object should the __iter__() method return?
//<class 'list_iterator'>
c. What is one simple way to implement Vector's __iter__() method, given that the iterator for Vector would essentially be the same as the iterator for the list self._v ?
//
def __iter__(self):
return iter(self._v)
```
5. An alternative to part 4.\(c\) is to define a class for VectorIterator, and Vector's \_\_iter__() method would instantiate and return it. The code is as follows:
```
class Vector:
def __iter__(self):
return Vector_Iterator(self):
....
class VectorIterator:
def __init__(self, vec):
self._vec = vec
self._i = 0
def __next__(self):
if self._i >= len(self._vec):
raise StopIteration
val = self._vec[self._i]
self._i += 1
return val
```
```
a. In VectorIterator's constructor, what is the purpose of initializing _i = 0?
//store the index current in
b. Why does VectorIterator's constructor need to set its _vec attribute to the iterable? Why isn't it enough to just keep track of its position _i?
//Vector_Iterator should return the value
c. How does Python intend that the __next__() method of a VectorIterator instance vi be invoked? Hint: not vi.__next__()
//next(vi)
d. How does __next__() special method indicate that it has finished iterating all elements?
//StopIteration
```
6. Assume Vector is iterable, rewrite the following for-loop using a while loop and explicit iter() instantiation, next(), and catching StopIteration exception:
```
v = Vector(7, 1, 4, 3, 9, 6, 5)
for i in v:
print(i, end='')
```
```
try:
r = iter(v)
while(true):
print(next(r), end = '')
except StopIteration:
print('', end = '')
```
7. Can any iterable object v be passed as arguments to
```
a. list(v) //Yes
b. max(v) //Yes
```
8. For the Blackjack game example, Card is declared as a class:
```
class Card:
ACE, JACK, QUEEN, KING = 'A', 'J', 'Q', 'K'
FACES = (ACE,2,3,4,5,6,7,8,9,10, JACK, QUEEN, KING)
SUITS = tuple(map(chr, (9824, 9827, 9829, 9830)))
SPADE, CLUB, HEART, DIAMOND = SUITS # ♠ ♣ ♥ ♦
def __init__(self, suit, face):
self._suit = suit
self._face = face
def __int__(self):
if self._face in {Card.JACK,Card.QUEEN,Card.KING}:
return 10
return 1 if self._face == Card.ACE else self._face
def __str__(self):
return self._suit + str(self._face)
def __repr__(self):
return __class__.__name__ + \
repr((self._suit, self._face))
```
```
a. Why is it a good practice to declare class attributes such as SPADE, CLUB, HEART, and DIAMOND even though Python3 handles unicode character literals such as '♠' '♣' '♥' '♦'.
//user don't need to input
b. What is the purpose of special method __int__()?
//to use in check if greater than 21 point
c. Why declare a __str__() special method even though __repr__() also exists and can make a string that represents the card?
//when print(Card) it will call string function
d. Is Card class iterable? Should it be iterable?
//No
e. Is Card class for instantiating iterators?
//No
```
9. Continuing with the BlackJack example, a separate class named Deck is also declared.
```
class Deck:
def __init__(self):
self._deck = [Card(suit, face) \
for suit in Card.SUITS for face in Card.FACES]
def shuffle(self):
import random
random.shuffle(self._deck)
def __iter__(self):
return iter(self._deck)
```
```
a. Is Deck an iterable? If so, is it required to implement the __getitem__() special method?
//Yes, it don't need to
b. Explain how the Deck class is able to create iterators by simply returning iter(self._deck) from its __iter__() special method. Explain why this works
//because self._deck is a list, so we can use list_iterator
```
10. In Single-player BlackJack
```
def BlackJack():
D = Deck()
D.shuffle()
total = 0
it = iter(D)
while True:
c = next(it)
total += int(c)
print(f'your card: {c}, total = {total}.', end='')
if total > 21:
print(f'you lose! total = {total}')
break
if total == 21:
print(f'you win! total = 21')
break
ans = input('More cards? [y/n] ')
if ans not in 'Yy':
c = next(it) # draw one more to test
print(f'next card {c}. You ' +\
('win' if total + c > 21 else 'lose'))
break
```
```
a. What kind of object is it as created on line 5?
//list_iterator
b. What kind of object is returned by a call to next(it) on line 7 or 18?
//Card
c. Why doesn't this program have to handle the case where the iterator raises StopIteration exception when the deck is empty?
//because if the iterator raises StopIteration then total will greater than 21
```
11. Is the following a function or a generator?
```
a. def X(z):
for i in range(20):
yield i
//generator
b. def Y(z):
for i in range(20):
return i
//function
c. def K(z):
for i in range(20):
yield i
return -1
//generator
```
12. if fib() is a generator for Fibonacci numbers, what is the syntax for
a. instantiating a generator,
b. generate the initial number,
c. generate 10 more numbers after?
Fill in the blanks below.
```
g = ____ # instantiate generator
init_num = ________
print('initial number = ', init_num)
for i in range(10):
num = ______
print(num)
```
```
fib()
next(g())
next(g())
```
13. Assume
g = fib() is a generator for Fibonacci numbers, and
r = iter(deck) is an iterator where deck is an instance of iterable class Deck
Which of the following are allowed?
```
a. list(r) //allow
b. list(g) //allow
c. list(fib()) //no allow
d. list(deck) //no allow
e. [i for i in r] //allow
f. [i for i in g] //allow
g. [i for i in fib()] //allow
h. [i for i in iter(deck)] //allow
i. next(r) //allow
j. next(g) //allow
k. x, y, z = deck //no allow
l. x, y, z = fib() //no allow
m. x, y, z = g //no allow
n. x, y, z = r //allow
```