# CS 1358 Introduction to Programming in Python SC10
###### tags: `pythonSC`
Answer the following questions to check your understanding of your material. Expect the same kind of questions to show up on your tests.
# 1. Definitions and Short Answers - functions
1. In Python, suppose you have the code
```python
return [13, 25, 'hello', 'z']
```
Which of the following are objects?
- [ ] return
- [x] 13
- [x] 25
- [x] 'hello'
- [x] 'z'
- [x] [13, 25, 'hello', 'z']
- [ ] ,
2. In Python, do the following keywords or built-in identifiers refer to objects?
- [ ] if
- [x] print
- [x] len
- [x] str
- [ ] ==
3. How can you make a clone of an object?
> by copying, by instantiating from a class
4. What is a class? How is a class related to an instance?
> class : definition for data (attributes) and code (methods)
> instance : an object created according to a class definition
5. What is the term for a function call whose name is the name of a class?
> constructor
6. How is a method different from a function?
> a function defined in a class to operate on its data
> it can only call by the class or instance
7. When you do
```python
import os
L = os.listdir()
```
are you making a method call with os.listdir(), or are you making a function call? Why?
> function call, os is not a class
8. In Python, suppose you have a class defined as
```python
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def move_by(self, dx, dy):
self.x += dx
self.y += dy
```
a. How do you instantiate a point with a coordinate of (2, 3) and assign it to the variable p?
```python
p = Point(2, 3)
```
b. What are the two attributes created by the constructor of this point?
```python
p.x
p.y
```
c. The move_by() method defines three parameters (self, dx, dy) but the call takes only two arguments, such as p.move_by(-2, 7). Why?
>Python actually calls
```python
Point.move_by(p, 2, 3)
```
d. Is it ever okay to declare an instance method without any parameter, such as
```python
def sayhi():
print("I am a point")
```
> No, instance method should pass instance itself as parameter.
9. How would you define the __repr__ method for the Point class above? What should it display if p = Point(2, 3) and you type p at the interactive prompt?
```python
def __repr__(self):
return f'Point({self.x}, {self.y})'
```
10. Suppose in your class definition,
```python=
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def move_by(self, dx, dy):
self.x += dx
self.y += dy
m = move_by
@property
def area_of_box(self)
return self.x * self.y
```
a. What is the effect of line 8?
> declare m to be an alias for move_by
b. What type of construct is the @property on line 9?
> uniform syntax like regular attributes
c. With line 9, how should you invoke the code for area_of_box on a Point object p?
> p.area_of_box
d. What is the purpose of applying the @property decorator here?
> say p.area_of_box instead of p.area_of_box()
11. Suppose you have
```python
>>> p = Point(2, 3)
>>> q = Point(4, 5)
>>> p.z = 7
```
a. What happens when you try to read the value of q.z?
> AttributeError, no such attribute
b. if you set q.z = 10, what happens to the value of p.z?
> No change, p.z==7
c. Is it okay if you do Point.count = 0 next? If so, what kind of attribute is it called?
> Yes, enter into the class namespace
d. Assuming the assignment Point.count = 0 is allowed, what is the value of p.count? Is it defined?
> 0, Yes
e. What is the value of dir\(p\) ? Does it include 'count' as a key in this dict? What about dir(q)?
> The namespace of p, no, yes
12. If you want your constructor to increment a class attribute to count the number of instances created so far,
a. How should you initialize the class attribute count = 0?
> define in class namespace
b. How should you increment the class attribute count in the constructor? As self.count += 1 or as Point.count += 1? Why?
> Point.count += 1, change in class namespace
13. Why is it better to define setter/getter methods than allowing user code to modify the attributes directly? For instance, suppose you have a DateTime class that allows you to do
```python
>>> dt = DateTime(year=2019, month=11, day=11, hour=9, \
... minute=8, second=7)
>>> dt.set_year(2023)
```
Why would it be preferred, compared to
```python
>>> dt.year = 2023
```
> first one, be more safe
14. In DateTime class shown on slide #35, the attributes are named with an underscore in front, such as \_year, \_month, \_day, etc. What is the reason for this?
> use _ to protect attribute from outside access
15. In the DateTime class, the check_and_set() method is defined to be
```python
def check_and_set(self, field_name, field_value, L, U):
if not (L <= field_value <= U):
raise ValueError(f'{field_name} must be {L}..{U}')
self.__dict__['_'+field_name] = field_value
```
a. What is the purpose of self. \__dict\__ ['\_'+field_name] = field_value? If field_name is 'year', self is p, and field_value is 2010, then what attribute of p gets assigned the value 2010?
> p.\_year
b. Why is it a good idea to write check_and_set() as a method that is called by set_year(), set_month(), set_day(), etc methods to assign value via self. \__dict\__ [] instead of assigning to the attributes self. \_year, self.\_ month, self.\_ day directly?
> to protect the attribute self
16. Assume you have a getter and a setter for the instance attribute \_month in the DateTime class:
```python
1 class DateTime:
2 def get_month(self):
3 ...
4 def set_month(self, mo):
5 ...
6 month = property(lambda self: self.get_month(),
7 lambda self, v: self.set_month(v))
```
a. What is the effect of lines 6-7? Suppose you have a variable dt which is an instance of DateTime, what method gets called when you do
```python
print(dt.month)
```
and
```python
dt.month = 5
```
> it will not show getter and setter
17. Which of the following correctly describes a class method? Assume you want to declare one named set_year_range() for the DateTime class and it takes parameters for the lower and upper bounds.
a. you need to use the decorator @classmethod on the line immediately before def set_year_range() method definition to make it a class method
> Yes
b. As long as you have the @classmethod decorator, the class method works just like an instance method because you would declare it as def set_year_range(self, lower, upper)and self refers to the instance that you invoke the method on.
> No
c. In addition to @classmethod decorator, you also need to declare the first parameter as cls instead of self because it refers to the class object instead of the instance object
> Yes
d. Even though you want cls to refer to the class object, you still invoke the class method on an instance object (e.g., named p)
p.set_year_range(100, 3000)
and Python will pass the class object for p as the cls parameter.
> Yes
18. Consider the leap-year function
```python
def leap(year):
return (year % 400 == 0) or \
((year % 4 == 0) and (year % 100 != 0))
```
a. and you would like to define it as a method inside the class DateTime rather than as a function outside the class.
> ~~define it as an instance method~~
> ~~define it as a class method~~
> define it as a static method
b. Is there any difference in how you would call the leap method?
> difference in passing the self or cls or not
c. Which of the three methods would be the preferred way and why?
> define it as a static method