Python Assignment– 9

Advanced Python Concepts

Basic Questions

  1. 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’.
  2. Define a generator function ‘count_up(n)’ that ‘yield’s numbers from 1 to ‘n’; iterate with a ‘for’ loop and print the numbers.
  3. Create a generator function ‘even_numbers(limit)’ that ‘yield’s only even numbers up to ‘limit’; print the yielded values on one line.
  4. 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.
  5. Write a list comprehension ‘[x for x in range(10) if x % 2 == 1]’ to collect odd numbers; print the resulting list.
  6. Create a set comprehension ‘{c for c in “mississippi”}’ and print the resulting set to show uniqueness.
  7. Build a dict comprehension ‘{x: x * x for x in range(5)}’ and print the resulting dictionary.
  8. 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’.
  9. Show dynamic typing by assigning ‘x = 10’ then reassigning ‘x = “ten”‘ and printing ‘type(x)’ after each assignment.
  10. 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.
  11. 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.
  12. 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.
  13. 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.
  14. 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.
  15. 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’.
  16. Create a generator function ‘chunks(seq, size)’ that ‘yield’s slices of length ‘size’ from ‘seq’; print all chunks for a sample list.
  17. Build a generator expression to stream uppercase characters from a string ‘(ch.upper() for ch in s)’; print the first four results using ‘next()’.
  18. Write a list comprehension that flattens ‘[[1, 2], [3], [], [4, 5]]’ into a single list and print it.
  19. Create a set comprehension to collect all vowels appearing in a sentence and print the sorted list of unique vowels.
  20. Use a dict comprehension to invert a dictionary (swap keys and values) and print the inverted mapping.

Intermediate Questions

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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()’.
  6. 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.
  7. Use a dict comprehension to count character frequencies from ‘s = “banana”‘ without loops by combining ‘set(s)’ and ‘s.count’; print the resulting dictionary.
  8. Implement a context manager ‘Timer’ with ‘enter’ returning ‘self’ and ‘exit’ printing elapsed seconds; use it to time a simple loop.
  9. 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.
  10. Create a nested ‘with’ using two different context managers (file openers) to copy text from one file to another line by line.
  11. 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.
  12. 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.
  13. 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.
  14. 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.
  15. Use ‘copy.deepcopy’ on the same structure and show that changes to nested lists in the original no longer affect the deep copy.
  16. 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.
  17. Create a list comprehension that builds a 5×5 identity matrix (as a list of lists) and print it row by row.
  18. 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.
  19. 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.
  20. Build a generator ‘unique_everseen(seq)’ that ‘yield’s items, skipping any that have appeared before; verify with a list containing duplicates.

Advanced Questions

  1. 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.
  2. Create a lazy ‘merge_sorted(g1, g2)’ generator that merges two already-sorted input generators without materializing lists; demonstrate with two finite numeric generators.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. 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).
  10. 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.