Python Assignment– 9
Advanced Python Concepts
Basic Questions
- Use ‘iter()’ to obtain an iterator over a list and call ‘next()’ repeatedly to print its first three elements, then handle ‘StopIteration’ with a simple ‘try/except’ to print ‘done’.
- Define a generator function ‘count_up(n)’ that ‘yield’s numbers from 1 to ‘n’; iterate with a ‘for’ loop and print the numbers.
- Create a generator function ‘even_numbers(limit)’ that ‘yield’s only even numbers up to ‘limit’; print the yielded values on one line.
- Build a generator expression ‘(x * x for x in range(6))’ and consume it with ‘next()’ three times; print the three values and then iterate the rest.
- Write a list comprehension ‘[x for x in range(10) if x % 2 == 1]’ to collect odd numbers; print the resulting list.
- Create a set comprehension ‘{c for c in “mississippi”}’ and print the resulting set to show uniqueness.
- Build a dict comprehension ‘{x: x * x for x in range(5)}’ and print the resulting dictionary.
- Implement a simple custom iterator class ‘Countdown’ that stores ‘start’ and on each ‘next()’ returns the next number down to 0, then raises ‘StopIteration’; demonstrate with ‘for’.
- Show dynamic typing by assigning ‘x = 10’ then reassigning ‘x = “ten”‘ and printing ‘type(x)’ after each assignment.
- Show strong typing by attempting to add an ‘int’ to a ‘str’ and catching the resulting ‘TypeError’ with a ‘try/except’ that prints the error message.
- Demonstrate mutable vs immutable: set ‘a = [1, 2, 3]’ and ‘b = a’; set ‘a[0] = 99’ and print both ‘a’ and ‘b’; then set ‘s1 = “hi”‘, ‘s2 = s1’, attempt ‘s1[0] = “H”‘ inside ‘try/except’ and print the exception type.
- Using the ‘copy’ module, create a shallow copy ‘a_copy = copy.copy(a_list)’ and prove that modifying a nested list element in the original affects the shallow copy.
- Using the ‘copy’ module, create a deep copy ‘a_deep = copy.deepcopy(a_list)’ and prove that modifying a nested list element in the original does not affect the deep copy.
- Write a minimal context manager class ‘Opener’ implementing ‘enter’ and ‘exit’ to open a text file and ensure it is closed; use ‘with Opener(path) as f:’ and write one line.
- Use a ‘with’ statement with a built-in file context manager to read the first line of a file and print it; verify the file is closed after the block by printing ‘f.closed’.
- Create a generator function ‘chunks(seq, size)’ that ‘yield’s slices of length ‘size’ from ‘seq’; print all chunks for a sample list.
- Build a generator expression to stream uppercase characters from a string ‘(ch.upper() for ch in s)’; print the first four results using ‘next()’.
- Write a list comprehension that flattens ‘[[1, 2], [3], [], [4, 5]]’ into a single list and print it.
- Create a set comprehension to collect all vowels appearing in a sentence and print the sorted list of unique vowels.
- Use a dict comprehension to invert a dictionary (swap keys and values) and print the inverted mapping.
Intermediate Questions
- Implement a custom iterator ‘Peekable’ that wraps any iterator and provides methods ‘peek()’ (look at next item without consuming) and ‘next()’; demonstrate by iterating and occasionally peeking.
- Write a generator function ‘read_lines(path)’ that opens a file with a ‘with’ statement and ‘yield’s lines stripped of trailing newlines; print the first five lines produced.
- Create a generator ‘window(seq, k)’ that ‘yield’s overlapping windows (as tuples) of size ‘k’ from ‘seq’; print all windows for a sample list.
- Build a pipeline using generator functions: ‘numbers(n)’ ‘yield’s 1..n, ‘squares(it)’ ‘yield’s ‘x*x’ for each ‘x’ from ‘it’, and ‘evens(it)’ ‘yield’s only even results; print the final stream.
- Compare memory usage by creating a list comprehension ‘[i for i in range(100000)]’ and a generator expression ‘(i for i in range(100000))’; print ‘type’ and iterate only the first 3 values from the generator with ‘next()’.
- Create a list comprehension that produces all pairs ‘(i, j)’ for ‘i in [1, 2, 3]’ and ‘j in [4, 5]’ except where ‘i == 2’; print the resulting list.
- Use a dict comprehension to count character frequencies from ‘s = “banana”‘ without loops by combining ‘set(s)’ and ‘s.count’; print the resulting dictionary.
- Implement a context manager ‘Timer’ with ‘enter’ returning ‘self’ and ‘exit’ printing elapsed seconds; use it to time a simple loop.
- Write a context manager ‘Suppress’ that swallows a given exception type passed at construction (e.g., ‘Suppress(ZeroDivisionError)’); inside ‘with’, deliberately divide by zero and confirm no exception escapes.
- Create a nested ‘with’ using two different context managers (file openers) to copy text from one file to another line by line.
- Build a generator function ‘walk_dict(d)’ that ‘yield’s ‘(key, value)’ pairs by iterating a nested dictionary recursively; print all pairs from a small nested sample.
- Show dynamic typing in functions by writing ‘apply_twice(fn, x)’ and calling it with different ‘fn’ (e.g., a numeric doubler and a string repeater); print both results.
- Demonstrate mutation effects during iteration: iterate a list via ‘for x in a[:]’ (a slice copy) and append to the original ‘a’ inside the loop; print final ‘a’ to show safe behavior.
- Use ‘copy.copy’ on a dictionary whose values include lists; modify a nested list in the original and show that the shallow-copied dictionary reflects the nested change.
- Use ‘copy.deepcopy’ on the same structure and show that changes to nested lists in the original no longer affect the deep copy.
- Combine generator expressions: ‘(x for x in (y*y for y in range(6)) if x % 2 == 0)’; iterate and print all values to show composability.
- Create a list comprehension that builds a 5×5 identity matrix (as a list of lists) and print it row by row.
- Write a generator function ’round_robin(*iters)’ that alternately ‘yield’s one item from each iterator until all are exhausted; demonstrate with three short ranges.
- Implement a context manager ‘Replacer(mapping)’ that temporarily replaces selected globals in a module (e.g., substitute a dummy function) and restores them in ‘exit’; show before/after behavior.
- Build a generator ‘unique_everseen(seq)’ that ‘yield’s items, skipping any that have appeared before; verify with a list containing duplicates.
Advanced Questions
- Implement an iterator class ‘BatchReader’ over a binary file that opens the file in ‘enter’, closes in ‘exit’, and ‘yield’s fixed-size byte chunks via iteration; use it in a ‘with BatchReader(path, size) as br:’ and print the size of each chunk read.
- Create a lazy ‘merge_sorted(g1, g2)’ generator that merges two already-sorted input generators without materializing lists; demonstrate with two finite numeric generators.
- Write a generator ‘tail(iterable, n)’ that ‘yield’s the last ‘n’ items by maintaining a fixed-size buffer; test with a range and print the outputs.
- Build a context manager ‘TransactionalList’ that snapshots a list on ‘enter’ (using ‘copy.deepcopy’) and restores the original on ‘exit’ if an exception occurred; demonstrate both commit and rollback paths.
- Implement a generator-based ‘tee’ function ‘tee_iter(it)’ that creates two independent generators from a single input iterator using an internal buffer; show that consuming one does not starve the other.
- Design a chain of decorators that add generator behavior: write ‘@log_yields’ to print each value as it is ‘yield’ed by a generator function and ‘@limit(n)’ to stop after ‘n’ ‘yield’s; decorate a sample generator and demonstrate the combined effect.
- Create a custom context manager ‘RedirectStdout’ that temporarily binds ‘sys.stdout’ to a file-like object (use an in-memory ‘io.StringIO’); inside ‘with’, print some lines, then after exit print the captured text.
- Explore copying semantics: build a nested structure with shared inner lists, make a shallow copy and a deep copy, then modify shared parts to show aliasing differences; print identity checks using ‘is’ to support the explanation.
- Implement an iterator protocol wrapper ‘Cycle’ that cycles indefinitely over an underlying finite iterable; show that ‘next()’ continues beyond the end by looping back to the start (include a manual ‘break’ after 10 outputs).
- Compose comprehensions and generators into a data pipeline that reads lines from a file, uses a generator expression to strip and filter non-empty lines, a list comprehension to transform to ‘(line, len(line))’ tuples, and a dict comprehension to map ‘line -> length’; print the final dictionary.