Python questions Flashcards

(69 cards)

1
Q

List vs Tuple

A

List:
- Mutable
- Worse performance
- More built-in methods

Tuple:
- Immutable
- Better performance (faster iterations, less memory used)
- Less built-in methods

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is __init__() ?

A

It is a method which is class constructor

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is list comprehension?

A

It’s a loop statement condensed to one line, usually used to create a new, altered list based on other list eg:

odd_powers_of_two = [2**x for x in range(0, 11) if ( x % 2 ) == 1]

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Are python classess fully mutable?

A

Yes, to the point of programmer being able to replace classess methods during runtime of the program (monkeypatching)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Exceptions - full statement

A

class XdError(Exception):
pass

try:
raise XdError
1/”xd”
except ZeroDivisionError:
print(“Nie dziel przez zero”)
except TypeError:
print(“Nie dziel przez c”)
except XdError:
print(“Nie dziel przez xd”)
except:
print (“other exception”)
else:
print (“else”)
finally:
print (“finally”)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is decorator?

A

Decorator is a function which can modify behavior of other function (creates and returns other function, which adds some behavior around the base function)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How to use decorator function without @decorator statement?

A

def example_decorator ( func ):
def wrapper(args, **kwargs):
print(“Decorator Start”)
result = func(
args, **kwargs)
print(“Decorator End”)

    return result
return wrapper

def print_xd():
print(“xd”)

print_xd = example_decorator ( print_xd )

print_xd()

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is del keyword used for?

A

del is used to delete objects; everything in Python is an object, so everything can be deleted

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Create class with one private attribute; create getter and setter to the attribute

A

class Person:

def \_\_init\_\_(self, name: str) -> None:
    self._name: str = name

@property
def name(self):
    return self._name

@name.setter
def name(self, new_name):
    self._name = new_name

p1 = Person(“Anna”)
print(p1.name)
p1.name = “Janina”
print(p1.name)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is set?

A

set - unordered collection of unique items (items can be added or popped, but not changed)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is *args?

A

args is a dictionary

It’s argument for unknown number of arguments in function:

def example(*args):
#args is a tuple
for word in args:
print(word)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is @staticmethod

A

It is a decorator for creating a static method, which means that the method can be called by refering both to class and instance of the class:

class Class:

@staticmethod
def static_method(a, b):

both are ok:
Class.static_method(1, 2)
Class().static_method(1,2)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What is a dictionary?

A

It’s an ordered (since Py3.7), changeable, unique* collection of pairs key:value

  • only keys need to be unique
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What is @classmethod

A

It is a decorator allowing for creation of function, refering to class, not to instance of it:

class Class

@classmethod
def class_method(cls):

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is **kwargs

A

It’s argument for unknown number of keyworded arguments in function:

def example(**kwargs):
#kwargs is a dictionary
for key, value in kwargs.items():
print(f”{key}: {value}”)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What are hashing algorithms used for?

A

They are used for creating signatures for messages and files in order to assure they haven’t been changed e.g. during transmission

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What are examples of hashing algorithms?

A

MD-5
SHA-1
SHA-256

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

When to use THREADS ?

A

For concurrent tasks, which need to syncronise access to data

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

When to use ASYNCIO ?

A

For tasks with waiting times, which can be carried out concurrently, but without need to share data

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

When to use PROCESSES ?

A

When performance is the key; when you need to run and syncronise multiple applications

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Using asyncio make concurrent program

A

import asyncio

async def fetch_data(time_s):
await asyncio.sleep(time_s)
print(f”Awaited: {time_s} seconds”)

async def main():
print(“start main”)

task1 = asyncio.create_task(fetch_data(3))
task2 = asyncio.create_task(fetch_data(1))

await task1
await task2
task3 = asyncio.create_task(fetch_data(2))

await task3
print("end main")

asyncio.run(main())

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

What is lambda?

A

it’s one line, anonymous function:
x = lambda a, b : a+b

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

What is with statement used for?

A

It’sa context manager used for exception management in cases like openeing files - it guards access to resources, which should not be access after end of with block

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Name 4 Python namespaces

A

Built-in
Global
Enclosed
Local

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
t1 = (1, [1, 2, 3], "str") t1[1][0] = 0 Why this operation is legal?
Because list is mutable, and even though the tuple is immutable, it (tuple) is only interested with "reference" to list, not in its insights
22
What is scope?
It's a part of program where variable is accesible
23
What are built-int mutable types in python? (3)
list set dict
24
What is the difference between these two operations? (ID and value of x) lst = [1,2,3] x = lst ivar = 1 x = ivar
There is no difference, in boh cases x will have the same ID and value as the original variable
25
What is the difference between these two operations? (id?) lst = [1,2,3] x = lst lst.append(4) ivar = 1 y = ivar ivar += 4
lst and x still have the same ID, before and after change ivar has new ID, y's ID remains the same
26
What 3 fields has structure PyObject?
Type (eg. string, int, etc) Reference count Value (eg. "xd", 1)
27
What 4 fields has structure PyVarObject?
Type (container types eg. list, tuple, dict, etc) Reference count Value (eg. "xd", 1) Size
28
What are generators?
Generators are a special kind of functions returning lazy iterators. Lazy iterators are iterable objects like lists, but unlike lists they don't store their contents in memory, just return next value when prompted
29
What are pros and cons of using generators over lists?
Generators use less memory while working on big datasets, but lists tend to be faster
30
Use following generator with next() method: def cLike_for_loop(start: int, end: int, delta: int = 1): count:int = start while count < end: yield count count += delta
ticks = 0 loop_gen = cLike_for_loop(10, 56, delta=2) while ticks < 5: value = next(loop_gen) print(value) ticks +=1
31
What are advanced methods to use with generator?
generator.send(value) - send data back to generator generator.throw(ExceptionType) - throw exception at generator generator.close() - stop generator
32
What is iterator?
Iterator is an object that allows you to iterate over collections of data (list, tuple, dict, set). It decouples iteration process from the data structure itself.
33
Which magic methods each iterator has to have implemented? What should they return?
__iter__(self) - typically returns self __next__(self) - must return next item or raise a StopIteration exception
34
Name 3 types of iterators
- Classic - return/yield original data - Transforming original data - Generating new data set from starting conditions
35
What are: fibonacci_generator fib_gen def fibonacci_generator(stop_idx=2): if stop_idx < 2: stop_idx = 2 index = 0 prev = [1, 1] while index < stop_idx: if index < 2: yield 1 else: new_value = sum(prev) yield new_value prev[1] = prev[0] prev[0] = new_value index += 1 fib_gen = fibonacci_generator(10)
fibonacci_generator - generator function fib_gen - generator interator
36
How are iterators/generators more efficient than functions and collections?
Iterators and generators are lazy - they only store one, last value of dataset in memory
36
What does it mean that iterator is exhausted?
It means that iterator has been used to iterate over entire set, and will always raise StopIteration exception if used again; it cannot be resetted
37
What is an iterable object? What makes an iterable?
Iterable object contains data and can be iterated over. In order for a collection to become an iterable it must implement the Iterable Protocol or Sequence Protocol (Iterable Protocol - implementation of __iter__) (Sequence Protocol - __getitem__ and __len__)
38
What does it mean that type implements the iterable protocol?
Type implements __iter__ method, returning an Iterator (or Iterator generator) OR Type implements __getitem__ and __len__ methods (sequence protocol) - python is able to create implementation of __iter__ method automatically if Sequence Protocol is implemented
39
Create and use CubeIterator with: input: list of int output: these values to the power of three
class CubeIterator: def __init__(self, sequence: list[int]) -> None: self._index: int = 0 self._sequence: list[int] = sequence def __next__(self) -> int | StopIteration: if self._index < len(self._sequence): self._index += 1 return (self._sequence[self._index - 1])**3 else: raise StopIteration def __iter__(self): return self for cube in CubeIterator([1, 2, 5, 10]): try: print(cube) except: break
40
Create GenericIterator and use it WITHOUT for loop (use iter() and next())
class GenericIterator: def __init__(self, sequence: list[int]) -> None: self._index: int = 0 self._sequence: list[int] = sequence def __next__(self) -> int | StopIteration: if self._index < len(self._sequence): self._index += 1 return self._sequence[self._index - 1] else: raise StopIteration def __iter__(self): return self iterator = iter(GenericIterator([1, 2, 3, 10])) while True: try: x = next(iterator) print(x) except: break
41
What are 2 mechanism of preventing memory leaks/garbage collection in CPython?
- reference counting (deleting objects with 0 references) - cyclic garbage collection (deleting unreachable objects)
42
Describe python memory leak with following code: class Money: name = '' symbols = [] # This is the dangerous line here def set_name(self, name): self.name = name def add_symbol(self, symbol): self.symbols.append(symbol)
Mutable type in class scope - each time we append to symbols list (even when done locally, actually the symbols in class scope is appended and never cleared
43
What is stored in _ variable in an interactive interpreter session?
The result of last expression
44
What does it mean that functios are first-class objects?
It means that functions can be passed around as arguments like any other object
45
What will be printed? How to "save" original name of the save_to_file function? def manage_file(foo): def wrapper(*args): print("Open file") ret_val = foo(*args) print("Close file") return ret_val return wrapper @manage_file def save_to_file(message): print(f"Message '{message}' saved to file!") print(save_to_file.__name__)
out: wrapper import functools def manage_file(foo): @functools.wraps(foo) def wrapper(*args): print("Open file") ret_val = foo(*args) print("Close file") return ret_val return wrapper
46
Create decorator taking one argument
import functools def manage_file(filename): def manage_file_decorator(foo): @functools.wraps(foo) def manage_file_wrapper(*args): print(f"Open file {filename}") ret_val = foo(*args) print("Close file") return ret_val return manage_file_wrapper return manage_file_decorator @manage_file("doc.txt") def save_to_file(message): print(f"Message '{message}' saved to file!") save_to_file("xd.txt") ## Footnote save_to_file("Random message")
47
Create decorator counting and remembering how many time a method was called
import functools def call_counter(foo): call_counter.count = 0 @functools.wraps(foo) def call_counter_wrapper(*args, **kwargs): call_counter.count += 1 ret_val = foo(*args, **kwargs) print(f"This method has been called {call_counter.count} time(s)") return ret_val call_counter.count = 0 return call_counter_wrapper @call_counter def save_to_file(message): print(f"Message '{message}' saved to file!") @call_counter def nuffin(): pass ## save_to_file("Danger,") save_to_file("Danger!") save_to_file("High Voltage!!!") nuffin()
48
Create decorator based on CALLABLE CLASS, counting and remembering how many time a method was called
from typing import Any class CallCounter: def __init__(self, foo) -> None: self.foo = foo self.counter = 0 def __call__(self, *args: Any, **kwds: Any) -> Any: ret_val = self.foo(*args, **kwds) self.counter += 1 print(f"function '{self.foo.__name__}' has been called {self.counter} time(s)") return ret_val @CallCounter def func(value): print(f"value: {value}") @CallCounter def xd(): print("xdxdxd") func(11) func(11) xd() func(11) func(11) xd()
49
How many times is function sum_retvals called? How many times is function sum_retvals_wrapper called? import functools def sum_retvals(foo): @functools.wraps(foo) def sum_retvals_wrapper(*args, **kwargs): ret_val = foo(*args, **kwargs) sum_retvals_wrapper.sum += ret_val print(f"Sum of retvals for function {sum_retvals_wrapper.__name__} = {sum_retvals_wrapper.sum}") return ret_val sum_retvals_wrapper.sum = 0 return sum_retvals_wrapper @sum_retvals def multiply(a, b): return a*b @sum_retvals def divide(a, b): return a/b _in = [1, 5] multiply(*_in) multiply(*_in) _in=[2, 1] multiply(*_in) divide(*_in)
How many times is function sum_retvals called? - Twice, once per usage of decorator How many times is function sum_retvals_wrapper called? - four times, each time divide and multiply functions are called
50
What is closure?
Closure - inner function, which is dynamically created and returned by its enclosing function. Their main feature is that they have full access to the variables and names defined in the local namespace where the closure was created, even though the enclosing function has returned and finished executing
51
Create closure factory function, which creates pointers to functions, raising input value to power chosen in moment of definition, usecase.: p_2 = your_function(2) print( p_2(5) )
def set_exponent(n): def power(x): return x**n return power power_of_2 = set_exponent(2) power_of_3 = set_exponent(3) power_of_4 = set_exponent(4) for r in range(0, 11): print(power_of_2(r)) print(power_of_3(r)) print(power_of_4(r), end="\n\n")
52
What is a functor?
Functor is an object containing: - value - (functional) mechanism of using the value
53
Create and use a simple functor
from __future__ import annotations from typing import Any, Callable Functor - object containig value and mechanism using this value class Functor: def __init__(self, value: Any) -> None: self.value = value def map(self, func: Callable): return Functor(func(self.value)) def add_one(value): return value + 1 def multiply_by_4(value): return value*4 print( Functor(2).map(add_one).map(multiply_by_4).map(add_one).value )
54
What is a difference between functor and endofunctor?
Endofunctor always returns object of its own type, Functor can return object of different type
55
What are Context Managers used for?
They are used for automatization of setup and teardown phases when dealing with external resources or other operations which require those phases
56
What is Context Manager Protocol?
It's a protocol, which must be implemented by object in order for with statement to work with it.
57
What are methods in Context Manager Protocol, what do they do and what do they return?
__enter__(self) - handles setup logic, return value is target variable (after as keyword) __exit__(self, except_type, except_value, except_traceback) - handles the teardown logic
58
Create a simple context manager class, taking one argument (name), saying hi at setup and goodbye at teardown.
class FirstContextManager: def __init__(self, name: str) -> None: self._name: str = name def __enter__(self)->str: print(f"Hi {self._name}") return f"Hi {self._name}" def __exit__(self, e_type, e_value, e_traceback): print(f"Goodbye {self._name}") print(e_type) print(e_value) print(e_traceback) with FirstContextManager("Mark") as yo: print(yo)
59
What is Concurrency?
It's an Ability to execute multiple task in overlapping manner; They can share one core or run pararelly
60
Are Concurrent processes executed pararelly?
Not always; Concurrency does not always is Pararellism, but Pararellism always is Concurrent
61
What is a Coroutine?
Coroutine is a repurposed generator function, which can suspend its execution and pass control to other coroutine
62
What is keyword async used for?
async def - define a Native Coroutine or an Asynchronous Generator async with - async for -
63
What is keyword await used for?
await passes control from a Coroutine back to the Event Loop
64