1 of 60

Review

Winter 2024

2 of 60

Reminders/Exam info

  • mic
  • Four rooms:
    • CSB 01,
    • CSB 02,
    • SOLIS 104,
    • SOLIS 107
  • Cheatsheet:
    • Double sided
    • Handwritten
    • Submit with the exam
  • How to study?

3 of 60

Major Topics

  • Classes, Inheritance
  • repr and str and other special methods
  • Higher - order functions, lambdas
  • Mutable, Immutable
  • Exceptions
  • Python:
    • Dictionaries, tuples, lists, list comprehension, map, filter, iterators

4 of 60

Major Topics

  • Recursion Questions
  • Complexity:
    • Given code, find running time
  • Files
    • Read, write, append

5 of 60

Let’s start

6 of 60

T/F?

n2 + log n10 = O (n2 ) -> T/F

n! = O(n^n)

5^n = O(n^n)

7 of 60

Complexity?

  1. O(1)
  2. O(log n)
  3. O(n)
  4. O(n log n)
  5. Something else

8 of 60

Complexity?

9 of 60

Complexity?

O(1)

  • O(1)
  • O(log n)
  • O(n)
  • O(n log n)
  • Something else

10 of 60

Complexity?

O(1)

O (n log n)

11 of 60

One more

def complexity3(lst):

t = 0

for i in range(lst):

t = t + 1

print(t)

  • O(1)
  • O(log n)
  • O(n)
  • O(n log n)
  • Something else

12 of 60

repr and str

13 of 60

repr and str

Try to answer:

  1. Why do we need functions like str and repr?

2) What is the difference between str and repr

3) Can they give different outputs?

4) Can they give the same outputs?

5) Can repr or str give you an error (given syntax is correct?)

14 of 60

class UC(object):

def __init__(self, name):

self.name = name

def __repr__(self):

return "UC('" + self.name + "')"

def __str__(self):

return 'UC ' + self.name

ucsd = UC("San Diego")

print(repr(ucsd))

A: UC San Diego

B: "UC('San Diego')"

C: UC('San Diego')

15 of 60

class UC(object):

def __init__(self, name):

self.name = name

def __repr__(self):

return "UC('" + self.name + "')"

def __str__(self):

return 'UC ' + self.name

ucsd = UC("San Diego")

print(str(ucsd))

A: UC San Diego

B: 'UC('San Diego')'

C: UC('San Diego')

16 of 60

class UC(object):

def __init__(self, name):

self.name = name

def __repr__(self):

return "UC('" + self.name + "')"

def __str__(self):

return 'UC ' + self.name

ucsd = UC("San Diego")

print(ucsd.__repr__())

A: UC San Diego

B: 'UC('San Diego')'

C: UC('San Diego')

17 of 60

class UC(object):

def __init__(self, name):

self.name = name

def __repr__(self):

return "UC('" + self.name + "')"

def __str__(self):

return 'UC ' + self.name

ucsd = UC("San Diego")

print(ucsd.__str__())

A: UC San Diego

B: 'UC('San Diego')'

C: UC('San Diego')

18 of 60

class UC(object):

def __init__(self, name):

self.name = name

def __repr__(self):

return "UC('" + self.name + "')"

def __str__(self):

return 'UC ' + self.name

ucsd = UC("San Diego")

repr(str(ucsd)) == repr(ucsd.__str__())

A: True

B: False

19 of 60

print(a)

repr(a)

a.str()

a.repr()

str(a)

a.__str__()

a.__repr__()

print(A())

repr(A())

A().__str__()

A().__repr__()

A.__str__(a)

A.__repr__(a)

https://docs.google.com/presentation/d/1fOwxZXp7VJCxi8sBsFJ5N2nZtbK70EbM/edit#slide=id.p53

20 of 60

Lambda function

>>> j = lambda: lambda x: x*2

What is the proper way to call it?

A: j

B: j()

C: j(3)

D: j()(3)

E: j(3)()

F: j(3)(3)

21 of 60

Dictionaries

Write a function accept_login(users, username, password). The function should return True if the user exists and the password is correct and False otherwise.

users = { "user1" : "password1",

"user2" : "password2",

"user3" : "password3"

}

if accept_login(users, "wronguser", "wrongpassword"):

print("login successful!")

else :

print("login failed...")

22 of 60

Dictionaries

users = { "user1" : "password1",

"user2" : "password2",

"user3" : "password3"

}

if accept_login(users, "wronguser", "wrongpassword"):

print("login successful!")

else :

print("login failed...")

def accept_login(users, username, password):

if users.get(username) == None:

return False

if users.get(username) != password:

print("login failed...")

else:

print("login successful!")

23 of 60

24 of 60

Check point

with open("check_point.txt", "r") as f:

read_data = f.read()

read_data = read_data.replace(",", "!")

with open("check_point.txt", "a") as f:

f.write(read_data)

f.write("Last Line")

D: Error

A:

B:

E: Other

C:

25 of 60

Hello, Ifra, best of luck on your exams!

26 of 60

27 of 60

Inheritance

class Test:

def __init__(self):

self.x = 0

class Derived_Test(Test):

def __init__(self):

self.y = 1

def main():

b = Derived_Test()

print(b.x,b.y)

main()

A) 0 1

B) 0 0

C) Error because class Derived_Test inherits Test but variable x isn’t inherited

D) Error because when object is created, argument must be passed like Derived_Test(1)

28 of 60

class Test:

def __init__(self):

self.x = 0

class Derived_Test(Test):

def __init__(self):

Test.__init__(self)

self.y = 1

def main():

b = Derived_Test()

print(b.x,b.y)

main()

A) Error because class Derived_Test inherits Test but variable x isn’t inherited

B) 0 0

C) 0 1

D) Error, the syntax of the invoking method is wrong

29 of 60

does every user defined class need an explicit constructor?

class Review:

message = "Good Luck!"

r = Review()

print(r.message)

Will it work?

30 of 60

Recursion

31 of 60

def pick_ared(input):

lst = list(input.keys()) # list if keys [“M.L.”, “A.B.”, “C.D.”]

def helper(lst):

if len(lst) == 0:

return ""

if input[“C.D.”][:3] == '858' or input[lst[0]][:3] == '619':

return str(lst[0]) + ':' + str(input[lst[0]]) + " " + helper(lst[1:])

else:

return helper(lst[1:])

rtn = helper(lst)

return rtn

32 of 60

Objects (if time permits)

Instance attributes are found before class attributes; class attributes are inherited

33 of 60

Objects

Instance attributes are found before class attributes; class attributes are inherited

34 of 60

Objects

Instance attributes are found before class attributes; class attributes are inherited

35 of 60

Objects

Instance attributes are found before class attributes; class attributes are inherited

36 of 60

Objects

Instance attributes are found before class attributes; class attributes are inherited

37 of 60

Land Owners

Instance attributes are found before class attributes; class attributes are inherited

38 of 60

Objects

Instance attributes are found before class attributes; class attributes are inherited

39 of 60

Objects

Instance attributes are found before class attributes; class attributes are inherited

40 of 60

Objects

What is the output?

>>> Worker().work()

41 of 60

Objects

What is the output?

>>> jack

42 of 60

Objects

What is the output?

>>> jack.work()

43 of 60

Objects

What is the output?

>>> john.work()

44 of 60

Objects

What is the output?

>>> john.elf.work(john)

45 of 60

Objects

46 of 60

Objects

47 of 60

Objects

48 of 60

Objects

49 of 60

Objects

50 of 60

Objects

51 of 60

Objects

52 of 60

Objects

53 of 60

Objects

54 of 60

Objects

55 of 60

Objects

56 of 60

Objects

57 of 60

Objects

58 of 60

Objects

59 of 60

Objects

60 of 60

Objects