Python questions Flashcards

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
Q

t1 = (1, [1, 2, 3], “str”)
t1[1][0] = 0

Why this operation is legal?

A

Because list is mutable, and even though the tuple is immutable, it (tuple) is only interested with “reference” to list, not in its insights

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

What is scope?

A

It’s a part of program where variable is accesible

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

What are built-int mutable types in python? (3)

A

list
set
dict

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

What is the difference between these two operations? (ID and value of x)
lst = [1,2,3]
x = lst

ivar = 1
x = ivar

A

There is no difference, in boh cases x will have the same ID and value as the original variable

25
Q

What is the difference between these two operations? (id?)
lst = [1,2,3]
x = lst
lst.append(4)

ivar = 1
y = ivar
ivar += 4

A

lst and x still have the same ID, before and after change

ivar has new ID, y’s ID remains the same

26
Q

What 3 fields has structure PyObject?

A

Type (eg. string, int, etc)
Reference count
Value (eg. “xd”, 1)

27
Q

What 4 fields has structure PyVarObject?

A

Type (container types eg. list, tuple, dict, etc)
Reference count
Value (eg. “xd”, 1)
Size

28
Q

What are generators?

A

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
Q

What are pros and cons of using generators over lists?

A

Generators use less memory while working on big datasets, but lists tend to be faster

30
Q

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

A

ticks = 0
loop_gen = cLike_for_loop(10, 56, delta=2)
while ticks < 5:

value = next(loop_gen)
print(value)
ticks +=1
31
Q

What are advanced methods to use with generator?

A

generator.send(value) - send data back to generator
generator.throw(ExceptionType) - throw exception at generator
generator.close() - stop generator

32
Q

What is iterator?

A

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
Q

Which magic methods each iterator has to have implemented? What should they return?

A

__iter__(self) - typically returns self
__next__(self) - must return next item or raise a StopIteration exception

34
Q

Name 3 types of iterators

A
  • Classic - return/yield original data
  • Transforming original data
  • Generating new data set from starting conditions
35
Q

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)

A

fibonacci_generator - generator function
fib_gen - generator interator

36
Q

How are iterators/generators more efficient than functions and collections?

A

Iterators and generators are lazy - they only store one, last value of dataset in memory

36
Q

What does it mean that iterator is exhausted?

A

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
Q

What is an iterable object? What makes an iterable?

A

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
Q

What does it mean that type implements the iterable protocol?

A

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
Q

Create and use CubeIterator with:
input: list of int
output: these values to the power of three

A

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
Q

Create GenericIterator and use it WITHOUT for loop (use iter() and next())

A

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
Q

What are 2 mechanism of preventing memory leaks/garbage collection in CPython?

A
  • reference counting (deleting objects with 0 references)
  • cyclic garbage collection (deleting unreachable objects)
42
Q

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)
A

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
Q

What is stored in _ variable in an interactive interpreter session?

A

The result of last expression

44
Q

What does it mean that functios are first-class objects?

A

It means that functions can be passed around as arguments like any other object

45
Q

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__)

A

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
Q

Create decorator taking one argument

A

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”)

save_to_file(“Random message”)

47
Q

Create decorator counting and remembering how many time a method was called

A

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(“High Voltage!!!”)

nuffin()

48
Q

Create decorator based on CALLABLE CLASS, counting and remembering how many time a method was called

A

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
Q

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)

A

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
Q

What is closure?

A

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
Q

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) )

A

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
Q

What is a functor?

A

Functor is an object containing:
- value
- (functional) mechanism of using the value

53
Q

Create and use a simple functor

A

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
Q

What is a difference between functor and endofunctor?

A

Endofunctor always returns object of its own type, Functor can return object of different type

55
Q

What are Context Managers used for?

A

They are used for automatization of setup and teardown phases when dealing with external resources or other operations which require those phases

56
Q

What is Context Manager Protocol?

A

It’s a protocol, which must be implemented by object in order for with statement to work with it.

57
Q

What are methods in Context Manager Protocol, what do they do and what do they return?

A

__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
Q

Create a simple context manager class, taking one argument (name), saying hi at setup and goodbye at teardown.

A

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
Q

What is Concurrency?

A

It’s an Ability to execute multiple task in overlapping manner; They can share one core or run pararelly

60
Q

Are Concurrent processes executed pararelly?

A

Not always;
Concurrency does not always is Pararellism, but Pararellism always is Concurrent

61
Q

What is a Coroutine?

A

Coroutine is a repurposed generator function, which can suspend its execution and pass control to other coroutine

62
Q

What is keyword async used for?

A

async def - define a Native Coroutine or an Asynchronous Generator

async with -
async for -

63
Q

What is keyword await used for?

A

await passes control from a Coroutine back to the Event Loop