├── .gitignore ├── 01_exception_diversion.py ├── 02_number_explosion.py ├── 03_letter_explosion.py ├── 04_type_addition.py ├── 05_positional_arguments.py ├── 06_truthy_falsey.py ├── 07_list_popping.py ├── 08_modulo_list_comp.py ├── 09_zipping_lists.py ├── 100_idiomatic_inheritance.py ├── 101_maniacal_munging.py ├── 102_plonking_pinnipeds.py ├── 103_dataclass_difficulties.py ├── 104_cascading_comparisons.py ├── 105_methods_into_attrs.py ├── 105_methods_into_attrs_answer.py ├── 106_hello_world.py ├── 106_hello_world_answer.py ├── 107_string_methodology.py ├── 108_matching_mayhem.py ├── 109_unruly_unpacking.py ├── 10_packing_variables.py ├── 110_sorting_shutout.py ├── 11_lambdas_and_bools.py ├── 12_animaniacal.py ├── 13_set_subtraction.py ├── 14_nesting_ternary.py ├── 16_fstring_formatting.py ├── 17_fstring_dates.py ├── 18_fstring_rounding.py ├── 19_boolean_math.py ├── 20_dictionary_explosion.py ├── 21_fun_with_walruses.py ├── 22_fstring_justification.py ├── 23_whats_callable.py ├── 24_shadows.py ├── 25_dictionary_keys.py ├── 26_list_mutation.py ├── 27_fstring_numbers.py ├── 28_boolean_shenanigans.py ├── 29_string_slicing_fun.py ├── 30_enumerate_and_dict.py ├── 31_dynamic_docstrings.py ├── 32_magical_multipliers.py ├── 33_deranged_generators.py ├── 33_deranged_generators_explainer.py ├── 34_what_makes_a_function.py ├── 35_more_run_with_walruses.py ├── 36_dict_comp_trickery.py ├── 37_multiple_assignment_mania.py ├── 38_exhasting_generators.py ├── 39_list_o_functions.py ├── 40_fixing_the_math.py ├── 40_fixing_the_math_answer.py ├── 40_fixing_the_math_answer2.py ├── 41_fun_with_filenames.py ├── 42_truthy_falsy2.py ├── 43_more_fstring_formatting.py ├── 44_fun_with_types.py ├── 45_boolean_equality.py ├── 46_manic_multistrings.py ├── 47_slicing_and_dicing.py ├── 48_text_finding_adventures.py ├── 49_puzzling_shadows.py ├── 50_a_print_puzzle.py ├── 51_ellipsis_conditions.py ├── 52_crazy_exception_handling.py ├── 53_mixed_up_code.py ├── 53_mixed_up_code_answer.py ├── 54_return_vs_yield.py ├── 55_more_shadows.py ├── 56_the_scope_of_the_matter.py ├── 57_nanny_addition.py ├── 58_tuple_augmented_assignment.py ├── 59_exception_shadowing.py ├── 60_subclassing_silliness.py ├── 61_loopy_variables.py ├── 62_more_loopy_variables.py ├── 63_dictionary_madness.py ├── 64_silly_lists.py ├── 65_modifying_lists.py ├── 66_garbage_collection.py ├── 67_details_matter.py ├── 68_range_rules.py ├── 69_equality_vs_identity.py ├── 70_list_insanity.py ├── 71_enumerate_enigma.py ├── 72_walrus_comprehension.py ├── 73_indexing_indignation.py ├── 74_list_defaults.py ├── 75_counting_letters.py ├── 75_counting_letters_answer.py ├── 76_veritable_variables.py ├── 77_tuples_are_immutable.py ├── 78_tuple_addition.py ├── 79_exacerbated_exceptions.py ├── 80_tuple_enumeration.py ├── 81_lists_and_strings.py ├── 82_multireference_anarchy.py ├── 83_tuples_and_dictionaries.py ├── 84_ridiculous_rounding.py ├── 85_conditional_unpacking.py ├── 86_lengthy_lists.py ├── 87_list_addition.py ├── 88_asserts_essentials.py ├── 89_string_silliness.py ├── 90_list_insertion.py ├── 91_letter_splitting.py ├── 92_class_attributes.py ├── 93_class_for_loop.py ├── 94_split_length.py ├── 95_senseless_sorting.py ├── 96_eclectic_ellipses.py ├── 97_mindboggling_matrices.py ├── 98_diabolical_decorator.py ├── 98_diabolical_decorator_alternative.py ├── 98_diabolical_decorator_generic_answer.py ├── 99_tuple_comparison_controversy.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | 47 | # Translations 48 | *.mo 49 | *.pot 50 | 51 | # Django stuff: 52 | *.log 53 | 54 | # Sphinx documentation 55 | docs/_build/ 56 | 57 | # PyBuilder 58 | target/ 59 | 60 | images/chp1/.DS_Store 61 | 62 | *.DS_Store 63 | -------------------------------------------------------------------------------- /01_exception_diversion.py: -------------------------------------------------------------------------------- 1 | # 01_exception_diversion.py 2 | 3 | try: 4 | for i in range(3): 5 | try: 6 | 1 / 0 7 | except ZeroDivisionError: 8 | raise ZeroDivisionError("Error: You divided by zero!") 9 | finally: 10 | print("Finally executed") 11 | break 12 | except ZeroDivisionError: 13 | print("Outer ZeroDivisionError exception caught") 14 | -------------------------------------------------------------------------------- /02_number_explosion.py: -------------------------------------------------------------------------------- 1 | # 02_number_explosion.py 2 | 3 | numbers = range(3) 4 | output = {*numbers} 5 | print(output) -------------------------------------------------------------------------------- /03_letter_explosion.py: -------------------------------------------------------------------------------- 1 | # 03_letter_explosion.py 2 | 3 | print("{2}, {1}, {0}".format(*"abc")) -------------------------------------------------------------------------------- /04_type_addition.py: -------------------------------------------------------------------------------- 1 | # 04_type_addition.py 2 | 3 | my_list = [True, 1, "python", 5, False, {}, True] 4 | integers_found = 0 5 | bools_found = 0 6 | 7 | for item in my_list: 8 | if isinstance(item, int): 9 | integers_found += 1 10 | elif isinstance(item, bool): 11 | bools_found += 1 12 | 13 | print(f"{integers_found = } {bools_found = }") -------------------------------------------------------------------------------- /05_positional_arguments.py: -------------------------------------------------------------------------------- 1 | # 05_positional_arguments.py 2 | 3 | def positional(name, age, /, a, b, *, key): 4 | print(name, age, a, b, key) 5 | 6 | if __name__ == "__main__": 7 | positional('Mike', 17, key='test') -------------------------------------------------------------------------------- /06_truthy_falsey.py: -------------------------------------------------------------------------------- 1 | # 06_truthy_falsey.py 2 | 3 | print(sum([ 4 | all([[]]), 5 | all([]), 6 | all([[[]]]) 7 | ])) -------------------------------------------------------------------------------- /07_list_popping.py: -------------------------------------------------------------------------------- 1 | # 07_list_popping.py 2 | 3 | my_list = list(range(1, 7)) 4 | for index, item in enumerate(my_list): my_list.pop(index) 5 | print(my_list) -------------------------------------------------------------------------------- /08_modulo_list_comp.py: -------------------------------------------------------------------------------- 1 | # 08_modulo_list_comp.py 2 | 3 | print([x for x in range(10) if x % 2]) -------------------------------------------------------------------------------- /09_zipping_lists.py: -------------------------------------------------------------------------------- 1 | # 09_zipping_lists.py 2 | 3 | numbers = [1, 2, 3, 4, 5] 4 | letters = ["a", "b", "c"] 5 | print(list(zip(numbers, letters))) 6 | -------------------------------------------------------------------------------- /100_idiomatic_inheritance.py: -------------------------------------------------------------------------------- 1 | # 100_idiomatic_inheritance.py 2 | 3 | class Py: 4 | py = 1 5 | 6 | class Cy(Py): 7 | ... 8 | 9 | class Vy(Py): 10 | ... 11 | 12 | Cy.py = 3.14 13 | Py.py = 7 14 | print(f"{Py.py = } {Cy.py = } {Vy.py = }") -------------------------------------------------------------------------------- /101_maniacal_munging.py: -------------------------------------------------------------------------------- 1 | # 101_maniacal_munging.py 2 | 3 | class Dog: 4 | def __init__(self): 5 | self.__color = "blue" 6 | self.hair = "long" 7 | 8 | print(Dog().__color) -------------------------------------------------------------------------------- /102_plonking_pinnipeds.py: -------------------------------------------------------------------------------- 1 | # 102_plonking_pinnipeds.py 2 | 3 | print((a := 5, 10) == ((a := 5), 10)) -------------------------------------------------------------------------------- /103_dataclass_difficulties.py: -------------------------------------------------------------------------------- 1 | # 103_dataclass_difficulties.py 2 | 3 | from dataclasses import dataclass, field 4 | 5 | @dataclass 6 | class Ford: 7 | models: list = field(default_factory=["F-150", "Mustang"]) 8 | 9 | vehicles = Ford() -------------------------------------------------------------------------------- /104_cascading_comparisons.py: -------------------------------------------------------------------------------- 1 | # 104_cascading_comparisons.py 2 | 3 | print(False == False in [False]) -------------------------------------------------------------------------------- /105_methods_into_attrs.py: -------------------------------------------------------------------------------- 1 | # 105_methods_into_attrs.py 2 | 3 | class Total: 4 | 5 | def __init__(self): 6 | # private attribute 7 | self._amount = 10 8 | 9 | def amount(self): 10 | return self._amount -------------------------------------------------------------------------------- /105_methods_into_attrs_answer.py: -------------------------------------------------------------------------------- 1 | # 105_methods_into_attrs_answer.py 2 | 3 | class Total: 4 | 5 | def __init__(self): 6 | # private attribute 7 | self._amount = 10 8 | 9 | @property 10 | def amount(self): 11 | return self._amount -------------------------------------------------------------------------------- /106_hello_world.py: -------------------------------------------------------------------------------- 1 | # 106_hello_world.py 2 | 3 | def hello(name: str) -> None: 4 | print("Hello") 5 | print(name) 6 | 7 | # Expected output: 'Hello Mike' (on a single line) 8 | hello("Mike") -------------------------------------------------------------------------------- /106_hello_world_answer.py: -------------------------------------------------------------------------------- 1 | # 106_hello_world_answer.py 2 | 3 | def hello(name: str) -> None: 4 | print("Hello ", end="") 5 | print(name) 6 | 7 | # Expected output: 'Hello Mike' (on a single line) 8 | hello("Mike") -------------------------------------------------------------------------------- /107_string_methodology.py: -------------------------------------------------------------------------------- 1 | # 107_string_method_extravaganza.py 2 | 3 | my_str = "FaLse" 4 | 5 | # which string method do you use to get the expected output? 6 | print(my_str.???) 7 | 8 | # expected output: 9 | fAlSE -------------------------------------------------------------------------------- /108_matching_mayhem.py: -------------------------------------------------------------------------------- 1 | # 108_matching_mayhem.py 2 | 3 | return_code = 200 4 | match return_code: 5 | case NOT_FOUND: 6 | print("return code not found") 7 | 8 | print(f"{NOT_FOUND = }") -------------------------------------------------------------------------------- /109_unruly_unpacking.py: -------------------------------------------------------------------------------- 1 | # 109_unruly_unpacking.py 2 | 3 | author = "Mike", "Driscoll" 4 | *copy, = author 5 | print(copy) -------------------------------------------------------------------------------- /10_packing_variables.py: -------------------------------------------------------------------------------- 1 | # 10_packing_variables.py 2 | 3 | a, *b, c = [1, 2, 3, 4, 5] 4 | print(b) -------------------------------------------------------------------------------- /110_sorting_shutout.py: -------------------------------------------------------------------------------- 1 | # 110_sorting_shutout.py 2 | 3 | my_list = [3, 1, 10, 5] 4 | my_list = my_list.sort() 5 | print(my_list) -------------------------------------------------------------------------------- /11_lambdas_and_bools.py: -------------------------------------------------------------------------------- 1 | # 11_lambdas_and_bools.py 2 | 3 | print((lambda a, b: a * b)(5, 4) - True) -------------------------------------------------------------------------------- /12_animaniacal.py: -------------------------------------------------------------------------------- 1 | # 12_animaniacal.py 2 | 3 | names = {"Mike", "Pinky", "Brain", "Dot"} 4 | other_names = {"Brain", "Yakko", "Wacko", "Rita"} 5 | print(names & other_names) -------------------------------------------------------------------------------- /13_set_subtraction.py: -------------------------------------------------------------------------------- 1 | # 13_set_subtraction.py 2 | 3 | names = {"Mike", "Pinky", "Brain", "Dot"} 4 | other_names = {"Brain", "Yakko", "Wacko", "Rita"} 5 | print(names - other_names) -------------------------------------------------------------------------------- /14_nesting_ternary.py: -------------------------------------------------------------------------------- 1 | # 14_nesting_ternary.py 2 | 3 | A = False 4 | B = True 5 | print("one" if A else "Python" if B else "Ciao!") -------------------------------------------------------------------------------- /16_fstring_formatting.py: -------------------------------------------------------------------------------- 1 | # 16_fstring_formatting.py 2 | 3 | message = "hi" 4 | fill = "s" 5 | align = "<" 6 | width = 10 7 | print(f"{message:{fill}{align}{width}}") -------------------------------------------------------------------------------- /17_fstring_dates.py: -------------------------------------------------------------------------------- 1 | # 17_fstring_dates.py 2 | 3 | import datetime 4 | 5 | day = datetime.datetime(2021, 11, 20) 6 | print(f"{day} was a {day:%A}") -------------------------------------------------------------------------------- /18_fstring_rounding.py: -------------------------------------------------------------------------------- 1 | # 18_fstring_rounding.py 2 | 3 | number = 10.125 4 | print(f"{round(number):.2f}") -------------------------------------------------------------------------------- /19_boolean_math.py: -------------------------------------------------------------------------------- 1 | # 19_boolean_math.py 2 | 3 | print(True + True + False - True) -------------------------------------------------------------------------------- /20_dictionary_explosion.py: -------------------------------------------------------------------------------- 1 | # 20_dictionary_explosion.py 2 | 3 | my_dict = {1: "Charles", 2: "Babbage"} 4 | print(*my_dict) -------------------------------------------------------------------------------- /21_fun_with_walruses.py: -------------------------------------------------------------------------------- 1 | # 21_fun_with_walruses.py 2 | 3 | (a := 6, 9) 4 | (a, b := 16, 19) 5 | print(f"{a=} {b=}") -------------------------------------------------------------------------------- /22_fstring_justification.py: -------------------------------------------------------------------------------- 1 | # 22_fstring_justification.py 2 | 3 | language = "Python" 4 | print(f"{language:*^30}") -------------------------------------------------------------------------------- /23_whats_callable.py: -------------------------------------------------------------------------------- 1 | # 23_whats_callable.py 2 | 3 | objects = [int, "", 1, str] 4 | print([callable(obj) for obj in objects]) -------------------------------------------------------------------------------- /24_shadows.py: -------------------------------------------------------------------------------- 1 | # 24_shadows.py 2 | 3 | min = 0 4 | numbers = list(range(5)) 5 | print(min(numbers)) -------------------------------------------------------------------------------- /25_dictionary_keys.py: -------------------------------------------------------------------------------- 1 | # 25_dictionary_keys.py 2 | 3 | languages = {} 4 | languages[1.1] = "C++" 5 | languages[2.0] = "PHP" 6 | languages[2] = "Python" 7 | print(languages) -------------------------------------------------------------------------------- /26_list_mutation.py: -------------------------------------------------------------------------------- 1 | # 26_list_mutation.py 2 | 3 | my_list = list(range(1, 7)) 4 | my_list = my_list.append(8) 5 | print(my_list) -------------------------------------------------------------------------------- /27_fstring_numbers.py: -------------------------------------------------------------------------------- 1 | # 27_fstring_numbers.py 2 | 3 | number = 12 4 | print(f"int: {number:d}; hex: {number:02X}; oct: {number:o}; bin: {number:b} ") -------------------------------------------------------------------------------- /28_boolean_shenanigans.py: -------------------------------------------------------------------------------- 1 | # 28_boolean_shenanigans.py 2 | 3 | print(bool(bool((lambda a, b: a * b)(4, 5)) - bool(True))) -------------------------------------------------------------------------------- /29_string_slicing_fun.py: -------------------------------------------------------------------------------- 1 | # 29_string_slicing_fun.py 2 | 3 | print("Python"[::-1]) -------------------------------------------------------------------------------- /30_enumerate_and_dict.py: -------------------------------------------------------------------------------- 1 | # 30_enumerate_and_dict.py 2 | 3 | some_string = "Python" 4 | some_dict = {} 5 | for i, some_dict[i] in enumerate(some_string): 6 | i = 10 7 | 8 | print(some_dict) -------------------------------------------------------------------------------- /31_dynamic_docstrings.py: -------------------------------------------------------------------------------- 1 | # 31_dynamic_docstrings.py 2 | 3 | header = "Say hello in Python" 4 | 5 | def hello(name: str) -> str: 6 | """ 7 | %s 8 | 9 | Python is amazing! 10 | """ 11 | return f"Hello {name}. Nice to meet you!" 12 | 13 | hello.__doc__ %= header 14 | help(hello) -------------------------------------------------------------------------------- /32_magical_multipliers.py: -------------------------------------------------------------------------------- 1 | # 32_magical_multiplication.py 2 | 3 | multipliers = {"macbook": 600 .__mul__, 4 | "microbit": 5 .__mul__, 5 | "pico": 50 .__mul__} 6 | print(multipliers["microbit"](6)) -------------------------------------------------------------------------------- /33_deranged_generators.py: -------------------------------------------------------------------------------- 1 | # 33_deranged_generators.py 2 | 3 | array = [21, 49, 15] 4 | gen = (x for x in array if array.count(x) > 0) 5 | array = [0, 49, 88] 6 | print(list(gen)) -------------------------------------------------------------------------------- /33_deranged_generators_explainer.py: -------------------------------------------------------------------------------- 1 | # 33_deranged_generators_explainer.py 2 | 3 | array = [21, 49, 15] 4 | gen = ((x, print(x, array)) for x in array) 5 | array = [0, 49, 88] 6 | print(list(gen)) 7 | 8 | for item in [21, 49, 15]: 9 | print(f"{array=} {item=}") 10 | if array.count(item) > 0: 11 | print(f"Item found at least once: {item=}") -------------------------------------------------------------------------------- /34_what_makes_a_function.py: -------------------------------------------------------------------------------- 1 | # 34_what_makes_a_function.py 2 | 3 | def function(): 4 | # This is a function 5 | 6 | function() -------------------------------------------------------------------------------- /35_more_run_with_walruses.py: -------------------------------------------------------------------------------- 1 | # 35_more_fun_with_walruses.py 2 | 3 | (x := [1, 2, 3]).extend(x) 4 | print(x) -------------------------------------------------------------------------------- /36_dict_comp_trickery.py: -------------------------------------------------------------------------------- 1 | # 36_dict_comp_trickery.py 2 | 3 | print({key: value for key, value in enumerate("abcde")}) -------------------------------------------------------------------------------- /37_multiple_assignment_mania.py: -------------------------------------------------------------------------------- 1 | # 37_multiple_assignment_mania.py 2 | 3 | d = 0 4 | a = b = c = d 5 | print(a) -------------------------------------------------------------------------------- /38_exhasting_generators.py: -------------------------------------------------------------------------------- 1 | # 38_exhausting_genetators.py 2 | 3 | def numbers(): 4 | yield 1 5 | yield 2 6 | 7 | if __name__ == "__main__": 8 | x = numbers() 9 | next(x) 10 | next(x) 11 | next(x) 12 | -------------------------------------------------------------------------------- /39_list_o_functions.py: -------------------------------------------------------------------------------- 1 | # 39_list_o_functions.py 2 | 3 | functions = [] 4 | 5 | for number in range(8): 6 | def my_function(): 7 | return number 8 | functions.append(my_function) 9 | 10 | results = [function() for function in functions] 11 | print(results) -------------------------------------------------------------------------------- /40_fixing_the_math.py: -------------------------------------------------------------------------------- 1 | # 40_fixing_the_math.py 2 | 3 | from math import sq_root 4 | 5 | 6 | def get_the_root(number); 7 | return sq_root(number) 8 | 9 | 10 | if name == main: 11 | get_the_root(64) -------------------------------------------------------------------------------- /40_fixing_the_math_answer.py: -------------------------------------------------------------------------------- 1 | # 40_fixing_the_math_answer.py 2 | 3 | from math import sqrt 4 | 5 | 6 | def get_the_root(number): 7 | return sqrt(number) 8 | 9 | 10 | if __name__ == "__main__": 11 | print(get_the_root(64)) -------------------------------------------------------------------------------- /40_fixing_the_math_answer2.py: -------------------------------------------------------------------------------- 1 | # 40_fixing_the_math_answer2.py 2 | 3 | from math import sqrt as get_the_root 4 | 5 | 6 | if __name__ == "__main__": 7 | print(get_the_root(64)) -------------------------------------------------------------------------------- /41_fun_with_filenames.py: -------------------------------------------------------------------------------- 1 | # 41_fun_with_filenames.py 2 | 3 | path = "C:\Program Files\turtle game" 4 | print(path) -------------------------------------------------------------------------------- /42_truthy_falsy2.py: -------------------------------------------------------------------------------- 1 | # 42_truthy_falsy_2.py 2 | 3 | print(all([[]])) -------------------------------------------------------------------------------- /43_more_fstring_formatting.py: -------------------------------------------------------------------------------- 1 | # 43_more_fstring_formatting.py 2 | 3 | align = "^" 4 | fill_char = "*" 5 | width = 25 6 | snake = "Python" 7 | print(f"{snake:{fill_char}{align}{width}}") -------------------------------------------------------------------------------- /44_fun_with_types.py: -------------------------------------------------------------------------------- 1 | # 44_fun_with_types.py 2 | 3 | print(type({*{}})) -------------------------------------------------------------------------------- /45_boolean_equality.py: -------------------------------------------------------------------------------- 1 | # 45_boolean_equality.py 2 | 3 | x = True 4 | y = False 5 | print(x == not y) -------------------------------------------------------------------------------- /46_manic_multistrings.py: -------------------------------------------------------------------------------- 1 | # 46_manic_multistrings.py 2 | 3 | print("Python""") -------------------------------------------------------------------------------- /47_slicing_and_dicing.py: -------------------------------------------------------------------------------- 1 | # 47_slicing_and_dicing.py 2 | 3 | # Note the following code must be run in the REPL 4 | 5 | >>> slice(1,3) 6 | >>> my_list = [10, 3, 12, 30, 77] 7 | >>> print(my_list[_]) -------------------------------------------------------------------------------- /48_text_finding_adventures.py: -------------------------------------------------------------------------------- 1 | # 48_text_finding_adventures.py 2 | 3 | text = "Python is amazing!" 4 | if text.find("C++"): 5 | print("Found C++!") 6 | else: 7 | print("C++ not found!") -------------------------------------------------------------------------------- /49_puzzling_shadows.py: -------------------------------------------------------------------------------- 1 | # 49_puzzling_shadows.py 2 | 3 | import math 4 | 5 | def math(number): 6 | return math.sqrt(number) 7 | 8 | def main(number): 9 | print(f"The square root of {number} is {math(number)}") 10 | 11 | main(8) -------------------------------------------------------------------------------- /50_a_print_puzzle.py: -------------------------------------------------------------------------------- 1 | # 50_a_print_puzzle.py 2 | 3 | print("Python" "is" "amazing") 4 | -------------------------------------------------------------------------------- /51_ellipsis_conditions.py: -------------------------------------------------------------------------------- 1 | # 51_elipsis_conditions.py 2 | 3 | age = 17 4 | 5 | if age >= 18 or ...: 6 | print("I'm going to drive on my own!") 7 | else: 8 | print("I need a driver!") -------------------------------------------------------------------------------- /52_crazy_exception_handling.py: -------------------------------------------------------------------------------- 1 | # 52_crazy_exception_handling.py 2 | 3 | try: 4 | for i in range(3): 5 | try: 6 | 1 / 0 7 | except ZeroDivisionError: 8 | raise ZeroDivisionError("Error: You divided by zero!") 9 | finally: 10 | print("Finally executed") 11 | return 12 | except ZeroDivisionError: 13 | print("Outer ZeroDivisionError exception caught") 14 | -------------------------------------------------------------------------------- /53_mixed_up_code.py: -------------------------------------------------------------------------------- 1 | # 53_mixed_up_code.py 2 | 3 | def type_checker(variable); 4 | if isinstance(variable, [float, integer]): 5 | print(f"{variable} is a number") 6 | elif isinstance(variable, string): 7 | print(f"{variable} is a string") 8 | elif ...: 9 | print("{variable} is something else".format(variable)) 10 | else: 11 | break 12 | 13 | if __name__ == "_main_": 14 | typ_checker(variable="Python") -------------------------------------------------------------------------------- /53_mixed_up_code_answer.py: -------------------------------------------------------------------------------- 1 | # 53_mixed_up_code_answer.py 2 | 3 | def type_checker(variable): # <-- Replace semicolon 4 | if isinstance(variable, (float, int)): # <-- Change integer to int and change to tuple 5 | print(f"{variable} is a number") 6 | elif isinstance(variable, str): # <-- Change string to str 7 | print(f"{variable} is a string") 8 | elif ...: 9 | print("{variable} is something else".format(variable)) 10 | else: 11 | print("Default") # Remove the break statement 12 | 13 | if __name__ == "__main__": # <-- Fix "_main_" to "__main__" 14 | type_checker(variable="Python") # <-- Call the right function name -------------------------------------------------------------------------------- /54_return_vs_yield.py: -------------------------------------------------------------------------------- 1 | # 54_return_vs_yield.py 2 | 3 | def my_func(value): 4 | if value == 5: 5 | return ["Python"] 6 | else: 7 | yield from range(value) 8 | 9 | print(list(my_func(5))) -------------------------------------------------------------------------------- /55_more_shadows.py: -------------------------------------------------------------------------------- 1 | # 55_more_shadows.py 2 | 3 | def greetings(): 4 | return "Hi there!" 5 | 6 | def greetings(name): 7 | return f"Hi {name}!" 8 | 9 | print(greetings()) 10 | -------------------------------------------------------------------------------- /56_the_scope_of_the_matter.py: -------------------------------------------------------------------------------- 1 | # 56_the_scope_of_the_matter.py 2 | 3 | number = 8 4 | 5 | def adder(integer): 6 | print(number) 7 | number = 10 8 | print(number + integer) 9 | 10 | adder(5) -------------------------------------------------------------------------------- /57_nanny_addition.py: -------------------------------------------------------------------------------- 1 | # 57_nanny_addition.py 2 | 3 | print(23 + float('nan')) -------------------------------------------------------------------------------- /58_tuple_augmented_assignment.py: -------------------------------------------------------------------------------- 1 | # 58_tuple_augmented_assignment.py 2 | 3 | 4 | # Note: This should be run in a REPL 5 | silly_tuple = (["one", "two"], ["three"]) 6 | silly_tuple[1] += ["four"] 7 | print(silly_tuple) -------------------------------------------------------------------------------- /59_exception_shadowing.py: -------------------------------------------------------------------------------- 1 | # 59_exception_shadowing.py 2 | 3 | e = 10 4 | 5 | try: 6 | raise ZeroDivisionError 7 | except ZeroDivisionError as e: 8 | pass 9 | 10 | print(e) -------------------------------------------------------------------------------- /60_subclassing_silliness.py: -------------------------------------------------------------------------------- 1 | # 60_subclassing_silliness.py 2 | 3 | class MyClass(str): 4 | pass 5 | 6 | 7 | silly_dict = {"py": "amazing"} 8 | p = MyClass("py") 9 | silly_dict[p] = 10 10 | print(silly_dict) -------------------------------------------------------------------------------- /61_loopy_variables.py: -------------------------------------------------------------------------------- 1 | # 61_loopy_variables.py 2 | 3 | number = "zero" 4 | for number in range(10): 5 | print(number * 2) 6 | 7 | print(number) -------------------------------------------------------------------------------- /62_more_loopy_variables.py: -------------------------------------------------------------------------------- 1 | # 62_more_loopy_variables.py 2 | 3 | number = 5 4 | lots_of_numbers = [number for number in range(5, 50, 2)] 5 | print(number) -------------------------------------------------------------------------------- /63_dictionary_madness.py: -------------------------------------------------------------------------------- 1 | # 63_dictionary_madness.py 2 | 3 | x, y = x[y] = {}, 10 4 | print(x) -------------------------------------------------------------------------------- /64_silly_lists.py: -------------------------------------------------------------------------------- 1 | # 64_silly_lists.py 2 | 3 | some_list = some_list[0] = [0] 4 | print(some_list[0][0][0][0][0][0] == some_list) -------------------------------------------------------------------------------- /65_modifying_lists.py: -------------------------------------------------------------------------------- 1 | # 65_modifying_lists.py 2 | 3 | animals = {1: "Python"} 4 | loops = 1 5 | for key in animals: 6 | del animals[key] 7 | animals[key + 1] = None 8 | print(f"{loops = }") 9 | loops += 1 -------------------------------------------------------------------------------- /66_garbage_collection.py: -------------------------------------------------------------------------------- 1 | # 66_garbage_collection.py 2 | 3 | class Spam: 4 | 5 | def __del__(self): 6 | print("Deleted!") 7 | 8 | x = Spam() 9 | y = x 10 | del x -------------------------------------------------------------------------------- /67_details_matter.py: -------------------------------------------------------------------------------- 1 | # 67_details_matter.py 2 | 3 | my_list = ["uno", 4 | "dos" 5 | "tres", 6 | "quatro" 7 | "cinco"] 8 | 9 | print(len(my_list)) -------------------------------------------------------------------------------- /68_range_rules.py: -------------------------------------------------------------------------------- 1 | # 68_range_rules.py 2 | 3 | print([number for number in range(25, 35, 2)]) -------------------------------------------------------------------------------- /69_equality_vs_identity.py: -------------------------------------------------------------------------------- 1 | # 69_equality_vs_identity.py 2 | 3 | # In a CPython REPL session, which of the following values 4 | # does not return True? 5 | 6 | A - 10 7 | B - 200 8 | C - 256 9 | D - 257 10 | 11 | >>> a = 1 12 | >>> b = 1 13 | >>> a is b 14 | True -------------------------------------------------------------------------------- /70_list_insanity.py: -------------------------------------------------------------------------------- 1 | # 70_list_insanity.py 2 | 3 | snakes = ["Python", "Garter", "Anaconda"] 4 | 5 | def add_snake(snake_type): 6 | snakes.extend(snake_type) 7 | print(snakes) 8 | 9 | add_snake("Boa") -------------------------------------------------------------------------------- /71_enumerate_enigma.py: -------------------------------------------------------------------------------- 1 | # 71_enumerate_enigma.py 2 | 3 | my_list = [1, 2, 3, 4] 4 | for index, item in enumerate(my_list): 5 | del item 6 | 7 | print(my_list) -------------------------------------------------------------------------------- /72_walrus_comprehension.py: -------------------------------------------------------------------------------- 1 | # 72_walrus_comprehension.py 2 | 3 | number = 10 4 | lots_of_numbers = [number for x in 5 | range(5, 100, 2) 6 | if (number := x)] 7 | print(number) -------------------------------------------------------------------------------- /73_indexing_indignation.py: -------------------------------------------------------------------------------- 1 | # 73_indexing_indignation.py 2 | 3 | class Number: 4 | integer = 0 5 | def __index__(self): 6 | internal_int = Number.integer 7 | Number.integer += 10 8 | return internal_int 9 | 10 | print([x for x in range(Number(), Number())]) -------------------------------------------------------------------------------- /74_list_defaults.py: -------------------------------------------------------------------------------- 1 | # 74_list_defaults.py 2 | 3 | def my_function(default=[]): 4 | default.append("Python") 5 | return default 6 | 7 | my_function() 8 | print(my_function()) 9 | -------------------------------------------------------------------------------- /75_counting_letters.py: -------------------------------------------------------------------------------- 1 | # 75_counting_letters.py 2 | 3 | # Find the top 3 letter counts in the following string: 4 | 5 | words = "The little red fox jumped over a fence and bit a python" -------------------------------------------------------------------------------- /75_counting_letters_answer.py: -------------------------------------------------------------------------------- 1 | # 75_counting_letters_answer.py 2 | 3 | import collections 4 | 5 | def solution_one(letters): 6 | letters = letters.lower() 7 | count = collections.Counter(letters) 8 | return count.most_common(3) 9 | 10 | 11 | def solution_two(letters): 12 | letters = letters.lower() 13 | my_dict = {} 14 | for letter in letters: 15 | if letter in my_dict: 16 | my_dict[letter] += 1 17 | else: 18 | my_dict[letter] = 1 19 | sorted_by_value = dict(sorted(my_dict.items(), key=lambda item: item[1])) 20 | return list(sorted_by_value.items())[-3:] 21 | 22 | if __name__ == "__main__": 23 | # Find the top 3 letter counts in the following string: 24 | words = "The little red fox jumped over a fence and bit a python" 25 | print(f"Counter solution: {solution_one(words)}") 26 | print(f"Regular dict solution: {solution_two(words)}") -------------------------------------------------------------------------------- /76_veritable_variables.py: -------------------------------------------------------------------------------- 1 | # 76_veritable_variables.py 2 | 3 | def area(width, height): 4 | print(f"{width = } {height =}") 5 | return width * height 6 | 7 | if __name__ == "__main__": 8 | width: int = 10 9 | height = 15 10 | area(width, height) -------------------------------------------------------------------------------- /77_tuples_are_immutable.py: -------------------------------------------------------------------------------- 1 | # 77_tuples_are_immutable.py 2 | 3 | my_tuple = ([1, 2], ["three", "four"]) 4 | my_tuple[1].append("five") 5 | print(my_tuple) -------------------------------------------------------------------------------- /78_tuple_addition.py: -------------------------------------------------------------------------------- 1 | # 78_tuple_addition.py 2 | 3 | my_tuple = ("Python", "cobra") 4 | my_tuple += ("boa", "anaconda") 5 | print(my_tuple) -------------------------------------------------------------------------------- /79_exacerbated_exceptions.py: -------------------------------------------------------------------------------- 1 | # 79_exacerbated_exceptions.py 2 | 3 | my_list = ["Python", "Boa", "Anaconda"] 4 | try: 5 | print(my_list[4]) 6 | except IndexError, ValueError: 7 | print("Caught an error!") 8 | -------------------------------------------------------------------------------- /80_tuple_enumeration.py: -------------------------------------------------------------------------------- 1 | # 80_tuple_enumeration.py 2 | 3 | # Which of the following is the correct way to enumerate the tuple? 4 | 5 | list_of_tuples = [("snake", "Python"), ("rodent", "hamster")] 6 | 7 | # A) 8 | for i, genus, animal in enumerate(list_of_tuples): 9 | print(f"{i} {genus = } {animal =}") 10 | 11 | # B) 12 | for i, (genus, animal) in enumerate(list_of_tuples): 13 | print(f"{i} {genus = } {animal =}") 14 | 15 | # C) 16 | for genus, animal in enumerate(list_of_tuples): 17 | print(f"{i} {genus = } {animal =}") 18 | 19 | -------------------------------------------------------------------------------- /81_lists_and_strings.py: -------------------------------------------------------------------------------- 1 | # 81_lists_and_strings.py 2 | 3 | my_list = [] 4 | my_list += "Python" 5 | print(my_list) -------------------------------------------------------------------------------- /82_multireference_anarchy.py: -------------------------------------------------------------------------------- 1 | # 82_multireference_anarchy.py 2 | 3 | numbers = [1, 2, 3] 4 | integers = numbers 5 | numbers = numbers + [4, 5, 6] 6 | print(integers) -------------------------------------------------------------------------------- /83_tuples_and_dictionaries.py: -------------------------------------------------------------------------------- 1 | # 83_tuples_and_dictionaries.py 2 | 3 | print(dict(("py", "th", "on"))) -------------------------------------------------------------------------------- /84_ridiculous_rounding.py: -------------------------------------------------------------------------------- 1 | # 84_ridiculous_rounding.py 2 | 3 | # True or False? 4 | 5 | print(round(1.5) == round(2.5)) -------------------------------------------------------------------------------- /85_conditional_unpacking.py: -------------------------------------------------------------------------------- 1 | # 85_conditional_unpacking.py 2 | 3 | x, y = (0, 1) if True else None, None 4 | print(x) -------------------------------------------------------------------------------- /86_lengthy_lists.py: -------------------------------------------------------------------------------- 1 | # 86_lengthy_lists.py 2 | 3 | languages = [ 4 | "Python", 5 | "C++" 6 | "JavaScript", 7 | "Ruby" 8 | "PHP", 9 | ] 10 | print(len(languages)) -------------------------------------------------------------------------------- /87_list_addition.py: -------------------------------------------------------------------------------- 1 | # 87_list_addition.py 2 | 3 | i = j = [3] 4 | i += j 5 | print(i, j) -------------------------------------------------------------------------------- /88_asserts_essentials.py: -------------------------------------------------------------------------------- 1 | # 88_asserts_essentials.py 2 | 3 | a = "python" 4 | b = "javascript" 5 | assert(a==b, "Languages are different") -------------------------------------------------------------------------------- /89_string_silliness.py: -------------------------------------------------------------------------------- 1 | # 89_string_silliness.py 2 | 3 | x = y = "Python" 4 | x += "rocks!" 5 | print(x, y) -------------------------------------------------------------------------------- /90_list_insertion.py: -------------------------------------------------------------------------------- 1 | # 90_list_insertion.py 2 | 3 | my_list = list("python") 4 | my_list.insert(100, "!") 5 | print(my_list) -------------------------------------------------------------------------------- /91_letter_splitting.py: -------------------------------------------------------------------------------- 1 | # 91_letter_splitting.py 2 | 3 | print("a".split()) -------------------------------------------------------------------------------- /92_class_attributes.py: -------------------------------------------------------------------------------- 1 | # 92_class_attributes.py 2 | 3 | letters = ["a"] 4 | 5 | class L: 6 | letters = ["b"] 7 | letters = letters + ["c"] 8 | 9 | print(letters[0], L.letters) -------------------------------------------------------------------------------- /93_class_for_loop.py: -------------------------------------------------------------------------------- 1 | # 93_class_for_loop.py 2 | 3 | class Number: 4 | integers = [5, 6, 7] 5 | for i in integers: 6 | i * 2 7 | 8 | print(Number.i) -------------------------------------------------------------------------------- /94_split_length.py: -------------------------------------------------------------------------------- 1 | # 94_split_length.py 2 | 3 | print(len("".split(" "))) -------------------------------------------------------------------------------- /95_senseless_sorting.py: -------------------------------------------------------------------------------- 1 | # 95_senseless_sorting.py 2 | 3 | x = 7, 8, 9 4 | print(sorted(x) == x) -------------------------------------------------------------------------------- /96_eclectic_ellipses.py: -------------------------------------------------------------------------------- 1 | # 96_eclectic_ellipses.py 2 | 3 | def my_function(): 4 | Ellipsis 5 | 6 | print(my_function()) -------------------------------------------------------------------------------- /97_mindboggling_matrices.py: -------------------------------------------------------------------------------- 1 | # 97_mindboggling_matrices.py 2 | 3 | matrix = [[0] * 3] * 3 4 | matrix[1][1] = "python" 5 | print(matrix) -------------------------------------------------------------------------------- /98_diabolical_decorator.py: -------------------------------------------------------------------------------- 1 | # 98_diabolical_decorator.py 2 | 3 | class dog: 4 | ... 5 | 6 | @(lambda f:setattr(dog, "on_leash", f)) 7 | def walk(): 8 | print("bark bark!") 9 | 10 | print(dog.on_leash()) -------------------------------------------------------------------------------- /98_diabolical_decorator_alternative.py: -------------------------------------------------------------------------------- 1 | # 98_diabolical_decorator_alternate.py 2 | 3 | class dog: 4 | ... 5 | 6 | 7 | def enhance_dog(func): 8 | setattr(dog, "on_leash", func) 9 | 10 | @enhance_dog 11 | def walk(): 12 | print("bark bark!") 13 | 14 | print(dog.on_leash()) -------------------------------------------------------------------------------- /98_diabolical_decorator_generic_answer.py: -------------------------------------------------------------------------------- 1 | # 98_diabolical_decorotor_generic_answer.py 2 | 3 | class dog: 4 | ... 5 | 6 | class add_cls_method: 7 | def __init__(self, cls): 8 | self.cls = cls 9 | def __call__(self, func): 10 | setattr(self.cls, func.__name__, func) 11 | 12 | @add_cls_method(dog) 13 | def walk(): 14 | print("bark bark!") 15 | 16 | print(dog.walk()) -------------------------------------------------------------------------------- /99_tuple_comparison_controversy.py: -------------------------------------------------------------------------------- 1 | # 99_tuple_comparision_controversy.py 2 | 3 | x = 7, 8, 9 4 | print(x == 7, 8, 9) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Python Quiz Book 2 | 3 | The Python Quiz Book 4 | 5 | **The Python Quiz Book** is a book of quizzes by Michael Driscoll. 6 | 7 | This repository contains the quiz code for the book. 8 | 9 | ## What's Covered 10 | 11 | You will learn about the following topics: 12 | 13 | - f-strings 14 | - generators 15 | - assignment expressions 16 | - unpacking gneralizations 17 | - sets 18 | - Python built-in functions 19 | - ternary expression 20 | - shadowing 21 | - and much, much more! 22 | 23 | ## Audience 24 | 25 | This book is for beginners and intermediate level Python developers who want to grow their knowledge about the Python programming language through quizzes. 26 | 27 | ## Where to Buy the Book 28 | 29 | - [Leanpub](https://leanpub.com/pyquiz) - PDF, mobi and epub 30 | 31 | ## About the Author 32 | 33 | Michael Driscoll has been an application developer using Python for over a decade. He is the author of the popular Python blog, [The Mouse Vs. the Python](https://www.blog.pythonlibrary.org/) as well as several other Python books including which you an find [here](https://driscollis.gumroad.com/). You can follow Mike on Twitter [@driscollis](https://twitter.com/driscollis). 34 | --------------------------------------------------------------------------------