├── mp58_urlspy_order ├── pianos │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── admin.py │ ├── tests.py │ ├── apps.py │ ├── urls.py │ └── views.py ├── synths │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── admin.py │ ├── tests.py │ ├── apps.py │ ├── urls.py │ └── views.py ├── piano_store │ ├── __init__.py │ ├── urls.py │ ├── asgi.py │ └── wsgi.py ├── .gitignore ├── synths_ursl_tried.txt └── manage.py ├── mp23_grounding_part_2 ├── hello.txt ├── willie_mountains.png └── partial_programs │ ├── add_border_1.py │ ├── add_border_3.py │ ├── add_border_2.py │ ├── add_border_4.py │ ├── add_border_5.py │ └── add_border_6.py ├── mp149_debugging_8 ├── requirements.in ├── card_data.py └── card_models.py ├── mp150_debugging_9 ├── requirements.in ├── card_data.py └── demo_cards.py ├── mp154_debugging_11 ├── requirements.in ├── card_data.py ├── demo_cards.py └── go_fish_utils.py ├── mp156_debugging_13 ├── requirements.in ├── .gitignore ├── card_data.py └── demo_cards.py ├── mp55_oop13_serialization_abc ├── robot.json ├── robot_dict.py ├── robot_class.py ├── robot_class_write.py └── robot_class_read.py ├── mp143_debugging_4 ├── requirements.in ├── .gitignore ├── tests │ └── e2e_tests │ │ └── conftest.py ├── die.py ├── dice_battle.py └── utils.py ├── mp151_debugging_10 ├── cards_with_error │ ├── requirements.in │ ├── card_data.py │ └── demo_cards.py ├── go_fish_fixed │ ├── requirements.in │ ├── card_data.py │ ├── demo_cards.py │ └── go_fish.py └── go_fish_with_error │ ├── requirements.in │ ├── card_data.py │ ├── demo_cards.py │ └── go_fish.py ├── mp155_debugging_12 ├── go_fish_bugfix │ ├── requirements.in │ ├── .gitignore │ ├── card_data.py │ └── demo_cards.py └── go_fish_seeded │ ├── requirements.in │ ├── .gitignore │ ├── card_data.py │ └── demo_cards.py ├── mp24_grounding_part_3 ├── tests │ ├── source_images │ │ ├── hello.txt │ │ ├── bear_scratching.jpg │ │ ├── bear_scratching_bordered.jpg │ │ └── bear_scratching_original_size.jpg │ └── reference_images │ │ ├── bear_scratching_default.jpg │ │ ├── bear_scratching_15px_border.jpg │ │ ├── bear_scratching_15px_padding.jpg │ │ ├── bear_scratching_black_border.jpg │ │ └── bear_scratching_20px_border_15px_padding.jpg ├── partial_programs │ ├── tests_0 │ │ ├── source_images │ │ │ ├── hello.txt │ │ │ └── bear_scratching.jpg │ │ └── reference_images │ │ │ ├── bear_scratching_bordered_default.jpg │ │ │ └── bear_scratching_bordered_default_15px_border.jpg │ ├── tests_10 │ │ ├── source_images │ │ │ ├── hello.txt │ │ │ ├── bear_scratching.jpg │ │ │ └── bear_scratching_original_size.jpg │ │ └── reference_images │ │ │ ├── bear_scratching_default.jpg │ │ │ ├── bear_scratching_15px_border.jpg │ │ │ ├── bear_scratching_15px_padding.jpg │ │ │ ├── bear_scratching_black_border.jpg │ │ │ └── bear_scratching_20px_border_15px_padding.jpg │ ├── tests_4 │ │ ├── source_images │ │ │ ├── hello.txt │ │ │ └── bear_scratching.jpg │ │ └── reference_images │ │ │ ├── bear_scratching_bordered_default.jpg │ │ │ └── bear_scratching_bordered_default_15px_border.jpg │ ├── add_border_11.py │ ├── add_border_9.py │ ├── cli_5.py │ ├── add_border_5.py │ ├── image_functions_9.py │ ├── cli_11.py │ ├── add_border_6.py │ ├── cli_10.py │ └── add_border_7.py ├── bear_scratching.jpg ├── bear_scratching_bordered.jpg ├── add_border.py └── image_functions.py ├── mp26_grounding_part_4 ├── tests │ ├── source_images │ │ ├── hello.txt │ │ ├── bear_scratching.jpg │ │ └── bear_scratching_original_size.jpg │ └── reference_images │ │ ├── bear_scratching_default.jpg │ │ ├── bear_scratching_15px_border.jpg │ │ ├── bear_scratching_15px_padding.jpg │ │ ├── bear_scratching_black_border.jpg │ │ └── bear_scratching_20px_border_15px_padding.jpg ├── partial_programs │ ├── tests_0 │ │ ├── source_images │ │ │ ├── hello.txt │ │ │ └── bear_scratching.jpg │ │ └── reference_images │ │ │ ├── bear_scratching_default.jpg │ │ │ ├── bear_scratching_15px_border.jpg │ │ │ ├── bear_scratching_15px_padding.jpg │ │ │ ├── bear_scratching_black_border.jpg │ │ │ └── bear_scratching_20px_border_15px_padding.jpg │ ├── tests_2 │ │ ├── source_images │ │ │ ├── hello.txt │ │ │ └── bear_scratching.jpg │ │ └── reference_images │ │ │ ├── bear_scratching_default.jpg │ │ │ ├── bear_scratching_15px_border.jpg │ │ │ ├── bear_scratching_15px_padding.jpg │ │ │ ├── bear_scratching_black_border.jpg │ │ │ └── bear_scratching_20px_border_15px_padding.jpg │ ├── tests_4 │ │ ├── source_images │ │ │ ├── hello.txt │ │ │ └── bear_scratching.jpg │ │ └── reference_images │ │ │ ├── bear_scratching_default.jpg │ │ │ ├── bear_scratching_15px_border.jpg │ │ │ ├── bear_scratching_15px_padding.jpg │ │ │ ├── bear_scratching_black_border.jpg │ │ │ └── bear_scratching_20px_border_15px_padding.jpg │ ├── main_3.py │ ├── cli_args_1.py │ ├── cli_args_2.py │ ├── main_2.py │ ├── main_1.py │ ├── cli_args_3.py │ ├── image_processing_1.py │ ├── image_processing_3.py │ └── cli_args_4.py ├── willie_sideeye.jpg ├── willie_sideeye_original.jpg ├── full_gpt_session_refactoring_add_border.png ├── main.py ├── image_processing.py └── cli_args.py ├── mp85_calc_file_paths ├── coffees.txt ├── dunder_file_demo.py ├── dunder_file_demo_2_parent.py ├── coffee_reader.py ├── coffee_reader_3_dunder_file.py ├── coffee_reader_2_absolute_path.py └── coffee_reader_4_project_root.py ├── mp5_lists_closer_look ├── squares_twenty_million.py ├── squares_comprehension.py ├── squares_twenty_million_genexpr.py ├── squares_twenty_million_append.py ├── squares.py └── squares_twenty_million_append_tempvar.py ├── mp148_min_rep_example ├── open_python_org.py └── rolling_dice │ ├── die.py │ └── die_visual.py ├── mp124_real_estate_images ├── output_images │ └── placeholder.txt ├── image_archiver_0_naive.py ├── image_archiver_1_selenium.py ├── image_archiver_2_click_first_image.py └── image_archiver_3_first_full_image.py ├── assets └── dice_battle_mp143.zip ├── mp130_door_codes ├── key_code_0_one_liner.py ├── key_code_1_sequence.py ├── key_code_2_cli.py ├── key_code_3_repeated_digits.py └── key_code_4_refactored.py ├── mp16_ending_while_loops ├── ten_squares.py ├── ten_squares_break.py └── ten_squares_flag.py ├── mp65_october_wx ├── october_highs.png ├── october_highs_lows.png ├── october_rolling_temps.png ├── october_temps.py ├── october_temps_2_october_data.py └── october_temps_3_plot_highs.py ├── mp8_lists_closer_look_lists_tuples ├── straight_cards_list.py ├── straight_cards_tuple.py ├── primes_list.py ├── primes_tuple.py ├── poker_hands.py ├── poker_hands_check_ace_high_4_using_all.py ├── poker_hands_check_ace_high.py ├── poker_hands_check_ace_high_2_all_cards_tuple.py ├── poker_hands_check_ace_high_3_hand_as_tuple.py └── list_tuple_size_comparison.py ├── mp128_checking_attributes ├── wx_observer.py ├── wx_observer_wind.py ├── wx_model.py ├── wx_model_wind.py ├── wx_reporter.py ├── wx_reporter_3_hasattr.py └── wx_reporter_2_try_except.py ├── mp78_streamlit_basics ├── roller.py ├── roller_st_write.py ├── roller_button.py ├── roller_radio.py ├── roller_num_dice_slider.py ├── roller_chart.py └── roller_sidebar.py ├── mp31_importance_profiling ├── output │ ├── high_temps.png │ ├── high_temps_1_year_moving_average.png │ ├── high_temps_3_year_moving_average.png │ ├── high_temps_5_year_moving_average.png │ ├── high_temps_10_year_moving_average.png │ └── high_temps_30_year_moving_average.png └── high_temp_trends.py ├── mp32_importance_profiling ├── output │ ├── high_temps.png │ ├── high_temps_1_year_moving_average.png │ ├── high_temps_3_year_moving_average.png │ ├── high_temps_5_year_moving_average.png │ ├── high_temps_10_year_moving_average.png │ └── high_temps_30_year_moving_average.png └── high_temp_trends.py ├── mp57_exception_hierarchy ├── bad_list.py ├── bad_list_2_help.py ├── bad_list_5_mro.py ├── bad_list_4_catch_lookuperror.py └── bad_list_3_isinstance.py ├── mp97_snippets ├── processed_snippets │ └── plot_data.png ├── raw_snippets │ └── plot_data.py └── pygparser.py ├── README.md ├── mp34_popular_projects ├── git-sim-merge_06-11-23_15-58-27.jpg └── git-sim-merge_06-11-23_16-00-42.mp4 ├── mp89_breakpoint ├── subscriber_ids.csv ├── subscribers.csv ├── generate_import_file.py ├── generate_import_file_2_read_csv.py ├── generate_import_file_3_breakpoint.py └── generate_import_file_4_fill_datacass.py ├── mp20_list_gotchas ├── wild_cards.py ├── card_game_one_player.py ├── dealer.py ├── fixed │ ├── dealer.py │ ├── card_game_two_players.py │ └── player.py ├── card_game_two_players.py └── player.py ├── mp9_chatgpt_not_reliable_teacher ├── winners.py ├── winners_ranked.py └── winners_bizarre_chatgpt_loop.py ├── mp33_using_pandas ├── output │ ├── high_temps_10_year_moving_average.png │ ├── high_temps_1_year_moving_average.png │ ├── high_temps_30_year_moving_average.png │ ├── high_temps_3_year_moving_average.png │ └── high_temps_5_year_moving_average.png ├── high_temp_trends.py └── high_temp_trends_show_invalid.py ├── mp47_oop8_comparison_methods ├── river.py ├── river_2_greater_than.py └── river_3_lt_eq.py ├── mp39_oop3_init ├── greeter.py ├── greeter_4_initialize_object.py ├── greeter_2_tone.py └── greeter_3_misspelled.py ├── mp6_searching_quick_answers ├── my_great_ide.py ├── my_great_ide_index.py └── my_great_ide_enumerate.py ├── .gitignore ├── mp37_oop2_self ├── squares.py ├── robot.py ├── squares_dict.py ├── robot_print_self.py ├── robot_army.py ├── robot_potato.py ├── robot_print_self_2.py ├── robot_print_self_3.py ├── robot_expanded.py ├── robot_self_dict.py └── robot_no_self.py ├── mp49_oop9_helper_methods ├── chessboard.py ├── chessboard_2.py ├── chessboard_3.py └── chessboard_4.py ├── mp13_lists_sets ├── explore_responses.py ├── explore_responses_set.py └── explore_responses_naive.py ├── mp2_lists_closer_look ├── bookshelf.py └── bookshelf.c ├── mp15_lists_arguments ├── generate_requests.py ├── process_requests.py └── process_requests_protected.py ├── mp46_oop7_new ├── nonzero_list.py ├── nonzero_tuple.py ├── nonzero_tuple_2.py └── nonzero_list_2.py ├── mp19_improving_code_blocks ├── partial_programs │ ├── email_parser_1.py │ ├── email_parser_2.py │ ├── email_parser_3.py │ └── email_parser_4.py ├── raw_post_without_title.html ├── raw_post.html └── highlighting_lines │ └── raw_post.html ├── mp29_settings ├── small_examples.py ├── alien.py ├── partial_programs │ ├── alien_3.py │ ├── alien_1.py │ ├── game_0.py │ ├── game_1.py │ ├── game_2.py │ └── game_3.py └── game.py ├── mp126_function_checklist ├── fn_checklist_0_parse_file.py ├── fn_checklist_1_no_comprehension.py ├── fn_checklist_6_simpler_approach.py ├── fn_checklist_2_all_fn_names.py ├── fn_checklist_3_no_comprehension.py ├── fn_checklist_4_task_list.py └── fn_checklist_5_pass_filename.py ├── mp12_lists_arrays └── best_sequence.py ├── mp44_oop6_str_repr ├── bonsai.py ├── bonsai_2.py └── bonsai_3.py ├── mp10_lists_profiling ├── sum_squares_optimize_get_sum.py ├── sum_squares_optimize_get_squares.py └── sum_squares.py ├── mp42_oop5_class_methods ├── trees.py ├── trees_2.py ├── trees_5.py ├── trees_4.py ├── trees_3_tracking_instances.py ├── trees_7.py ├── trees_6.py └── trees_8_doesnt_work.py ├── mp41_static_methods ├── mountains.py ├── mountains_5_call_from_class.py ├── mountains_2_disclaimer.py ├── mountains_3_disclaimer_no_self_error.py └── mountains_4_static_method.py ├── mp7_tracking_down_a_bug ├── die.py └── die_visual.py ├── mp61_oop16 ├── triangle_nums.py ├── triangle_nums_2_print_fig_ax.py ├── triangle_nums_3_facecolor.py └── triangle_nums_4_text.py ├── mp3_lists_closer_look ├── random_numbers_insert.py ├── list_memory.py ├── random_numbers_deque.py ├── random_numbers.py └── list_memory_visual.py ├── mp43_substack_notes_cguo ├── main.py └── main_2.py ├── mp17_lists_modifying_in_loop ├── process_requests_good.py ├── process_requests_gotcha.py ├── process_requests_good_multiline.py ├── process_requests_good_full_loop.py └── process_requests_gotcha_diagnostic.py ├── oop_18 ├── partial_versions │ ├── climbing_library_0.py │ ├── climbing_library_1_lend_book.py │ ├── library_models_0.py │ └── library_models_1_get_status.py └── climbing_library.py ├── oop_19 ├── office_hours_monitor.py └── office_hours_monitor_oop.py ├── mp145_debugging_6 └── strat_players.py ├── mp120_lotteries ├── nc_powerball.py └── nc_powerball_2_30_plays.py ├── mp48_radians_function ├── squares_degrees.py └── squares_radians.py ├── mp52_oop11_inheritance ├── account.py ├── account_2_free.py ├── account_4_account_hardcoded.py └── account_3_print_super.py ├── mp68_gift_exchange └── gift_exchange_2_check_match.py ├── mp21_list_deepcopy ├── locations.py └── locations_deepcopy.py ├── mp123_mortgages ├── mortgage_analysis_0.py └── mortgage_analysis_1.py ├── oop_17 └── library.py └── mp53_oop12_abc ├── account_4_invisible.py ├── account_3_not_well_behaved.py ├── account.py └── account_5_assertive_account.py /mp58_urlspy_order/pianos/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mp58_urlspy_order/synths/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mp23_grounding_part_2/hello.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /mp58_urlspy_order/piano_store/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mp149_debugging_8/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /mp150_debugging_9/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /mp154_debugging_11/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /mp156_debugging_13/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /mp58_urlspy_order/pianos/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mp58_urlspy_order/synths/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mp55_oop13_serialization_abc/robot.json: -------------------------------------------------------------------------------- 1 | {"name": "Marvin"} -------------------------------------------------------------------------------- /mp143_debugging_4/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | python-bugger 3 | -------------------------------------------------------------------------------- /mp151_debugging_10/cards_with_error/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /mp151_debugging_10/go_fish_fixed/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /mp155_debugging_12/go_fish_bugfix/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /mp155_debugging_12/go_fish_seeded/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /mp24_grounding_part_3/tests/source_images/hello.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /mp26_grounding_part_4/tests/source_images/hello.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /mp151_debugging_10/go_fish_with_error/requirements.in: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_0/source_images/hello.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_10/source_images/hello.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_4/source_images/hello.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_0/source_images/hello.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_2/source_images/hello.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_4/source_images/hello.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | -------------------------------------------------------------------------------- /mp85_calc_file_paths/coffees.txt: -------------------------------------------------------------------------------- 1 | Hair Bender 2 | El Inierto Bourbon 3 | Trapper Creek -------------------------------------------------------------------------------- /mp143_debugging_4/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .venv/ 3 | *.pyc 4 | 5 | .DS_Store 6 | 7 | -------------------------------------------------------------------------------- /mp5_lists_closer_look/squares_twenty_million.py: -------------------------------------------------------------------------------- 1 | squares = [x**2 for x in range(20_000_000)] -------------------------------------------------------------------------------- /mp156_debugging_13/.gitignore: -------------------------------------------------------------------------------- 1 | .venv/ 2 | __pycache__/ 3 | 4 | .DS_Store 5 | 6 | *.egg-info/ 7 | -------------------------------------------------------------------------------- /mp148_min_rep_example/open_python_org.py: -------------------------------------------------------------------------------- 1 | import webbrowser 2 | webbrowser.open("https://python.org") -------------------------------------------------------------------------------- /mp58_urlspy_order/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | 3 | *.sqlite3 4 | 5 | .venv/ 6 | 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /mp58_urlspy_order/pianos/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /mp58_urlspy_order/synths/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /mp58_urlspy_order/pianos/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /mp58_urlspy_order/pianos/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /mp58_urlspy_order/synths/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /mp58_urlspy_order/synths/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /mp5_lists_closer_look/squares_comprehension.py: -------------------------------------------------------------------------------- 1 | squares = [x**2 for x in range(1, 101)] 2 | print(squares) -------------------------------------------------------------------------------- /mp5_lists_closer_look/squares_twenty_million_genexpr.py: -------------------------------------------------------------------------------- 1 | squares_genexpr = (x**2 for x in range(20_000_000)) -------------------------------------------------------------------------------- /mp124_real_estate_images/output_images/placeholder.txt: -------------------------------------------------------------------------------- 1 | Placeholder file to include output_images/ in repository. -------------------------------------------------------------------------------- /mp155_debugging_12/go_fish_bugfix/.gitignore: -------------------------------------------------------------------------------- 1 | .venv/ 2 | __pycache__/ 3 | 4 | .DS_Store 5 | 6 | *.egg-info/ 7 | -------------------------------------------------------------------------------- /mp155_debugging_12/go_fish_seeded/.gitignore: -------------------------------------------------------------------------------- 1 | .venv/ 2 | __pycache__/ 3 | 4 | .DS_Store 5 | 6 | *.egg-info/ 7 | -------------------------------------------------------------------------------- /mp85_calc_file_paths/dunder_file_demo.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | path = Path(__file__) 4 | print(path) -------------------------------------------------------------------------------- /assets/dice_battle_mp143.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/assets/dice_battle_mp143.zip -------------------------------------------------------------------------------- /mp130_door_codes/key_code_0_one_liner.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | keycode = randint(0,999999) 4 | print(keycode) 5 | -------------------------------------------------------------------------------- /mp16_ending_while_loops/ten_squares.py: -------------------------------------------------------------------------------- 1 | x = 1 2 | while x < 11: 3 | square = x**2 4 | print(square) 5 | 6 | x += 1 -------------------------------------------------------------------------------- /mp5_lists_closer_look/squares_twenty_million_append.py: -------------------------------------------------------------------------------- 1 | squares = [] 2 | for x in range(20_000_000): 3 | squares.append(x**2) -------------------------------------------------------------------------------- /mp65_october_wx/october_highs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp65_october_wx/october_highs.png -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/straight_cards_list.py: -------------------------------------------------------------------------------- 1 | for _ in range(5000000): 2 | cards = [10, 'j', 'q', 'k', 'a'] 3 | -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/straight_cards_tuple.py: -------------------------------------------------------------------------------- 1 | for _ in range(5000000): 2 | cards = (10, 'j', 'q', 'k', 'a') 3 | -------------------------------------------------------------------------------- /mp128_checking_attributes/wx_observer.py: -------------------------------------------------------------------------------- 1 | from wx_model import WeatherObservation 2 | 3 | wx_obs = WeatherObservation(2.5, 1.5) 4 | -------------------------------------------------------------------------------- /mp65_october_wx/october_highs_lows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp65_october_wx/october_highs_lows.png -------------------------------------------------------------------------------- /mp23_grounding_part_2/willie_mountains.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp23_grounding_part_2/willie_mountains.png -------------------------------------------------------------------------------- /mp24_grounding_part_3/bear_scratching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/bear_scratching.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/willie_sideeye.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/willie_sideeye.jpg -------------------------------------------------------------------------------- /mp65_october_wx/october_rolling_temps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp65_october_wx/october_rolling_temps.png -------------------------------------------------------------------------------- /mp85_calc_file_paths/dunder_file_demo_2_parent.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | path = Path(__file__).parent / "coffees.txt" 4 | print(path) -------------------------------------------------------------------------------- /mp128_checking_attributes/wx_observer_wind.py: -------------------------------------------------------------------------------- 1 | from wx_model_wind import WeatherObservation 2 | 3 | wx_obs = WeatherObservation(0.5, 23.0, 15.0) 4 | -------------------------------------------------------------------------------- /mp78_streamlit_basics/roller.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | import streamlit as st 3 | 4 | roll = randint(1, 6) 5 | 6 | f"You rolled a {roll}." -------------------------------------------------------------------------------- /mp31_importance_profiling/output/high_temps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp31_importance_profiling/output/high_temps.png -------------------------------------------------------------------------------- /mp32_importance_profiling/output/high_temps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp32_importance_profiling/output/high_temps.png -------------------------------------------------------------------------------- /mp57_exception_hierarchy/bad_list.py: -------------------------------------------------------------------------------- 1 | python_exceptions = [ 2 | "SyntaxError", 3 | "NameError", 4 | ] 5 | 6 | my_exception = python_exceptions[2] -------------------------------------------------------------------------------- /mp5_lists_closer_look/squares.py: -------------------------------------------------------------------------------- 1 | squares = [] 2 | for x in range(1, 101): 3 | square = x**2 4 | squares.append(square) 5 | 6 | print(squares) -------------------------------------------------------------------------------- /mp97_snippets/processed_snippets/plot_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp97_snippets/processed_snippets/plot_data.png -------------------------------------------------------------------------------- /mp26_grounding_part_4/willie_sideeye_original.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/willie_sideeye_original.jpg -------------------------------------------------------------------------------- /mp85_calc_file_paths/coffee_reader.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | path = Path("coffees.txt") 4 | contents = path.read_text() 5 | 6 | print(contents) -------------------------------------------------------------------------------- /mp24_grounding_part_3/bear_scratching_bordered.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/bear_scratching_bordered.jpg -------------------------------------------------------------------------------- /mp5_lists_closer_look/squares_twenty_million_append_tempvar.py: -------------------------------------------------------------------------------- 1 | squares = [] 2 | for x in range(20_000_000): 3 | square = x**2 4 | squares.append(square) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Mostly Python 2 | === 3 | 4 | This is a repository for code files mentioned in the [Mostly Python](https://mostlypython.substack.com) newsletter. 5 | 6 | -------------------------------------------------------------------------------- /mp128_checking_attributes/wx_model.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | @dataclass 4 | class WeatherObservation: 5 | precip: float 6 | temp: float 7 | -------------------------------------------------------------------------------- /mp16_ending_while_loops/ten_squares_break.py: -------------------------------------------------------------------------------- 1 | x = 1 2 | while True: 3 | square = x**2 4 | print(square) 5 | 6 | x += 1 7 | if x > 10: 8 | break -------------------------------------------------------------------------------- /mp78_streamlit_basics/roller_st_write.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | import streamlit as st 3 | 4 | roll = randint(1, 6) 5 | 6 | st.write(f"You rolled a {roll}.") -------------------------------------------------------------------------------- /mp130_door_codes/key_code_1_sequence.py: -------------------------------------------------------------------------------- 1 | from random import choices 2 | 3 | keycode = choices("0123456789", k=6) 4 | keycode = "".join(keycode) 5 | 6 | print(keycode) 7 | -------------------------------------------------------------------------------- /mp34_popular_projects/git-sim-merge_06-11-23_15-58-27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp34_popular_projects/git-sim-merge_06-11-23_15-58-27.jpg -------------------------------------------------------------------------------- /mp34_popular_projects/git-sim-merge_06-11-23_16-00-42.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp34_popular_projects/git-sim-merge_06-11-23_16-00-42.mp4 -------------------------------------------------------------------------------- /mp89_breakpoint/subscriber_ids.csv: -------------------------------------------------------------------------------- 1 | email,subscriber_id 2 | mitchell_lewis@example.org,5eb63b 3 | nathan_smith@example.com,d4ab93 4 | megan_gardner@example.gov,1f9996 5 | -------------------------------------------------------------------------------- /mp20_list_gotchas/wild_cards.py: -------------------------------------------------------------------------------- 1 | hand = ['5♦', '4♣', 'w', '5♦', 'A♣', 'w', '3♥', 'w'] 2 | print(hand) 3 | 4 | while 'w' in hand: 5 | hand.remove('w') 6 | 7 | print(hand) -------------------------------------------------------------------------------- /mp89_breakpoint/subscribers.csv: -------------------------------------------------------------------------------- 1 | email,name 2 | mitchell_lewis@example.org,Mitchell Lewis 3 | nathan_smith@example.com,Nathan Smith 4 | megan_gardner@example.gov,Megan Gardner 5 | -------------------------------------------------------------------------------- /mp9_chatgpt_not_reliable_teacher/winners.py: -------------------------------------------------------------------------------- 1 | winners = ["elizabeth", "ryan", "kayla"] 2 | 3 | print("The winners are:") 4 | for winner in winners: 5 | print(winner.title()) -------------------------------------------------------------------------------- /mp24_grounding_part_3/tests/source_images/bear_scratching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/tests/source_images/bear_scratching.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/tests/source_images/bear_scratching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/tests/source_images/bear_scratching.jpg -------------------------------------------------------------------------------- /mp33_using_pandas/output/high_temps_10_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp33_using_pandas/output/high_temps_10_year_moving_average.png -------------------------------------------------------------------------------- /mp33_using_pandas/output/high_temps_1_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp33_using_pandas/output/high_temps_1_year_moving_average.png -------------------------------------------------------------------------------- /mp33_using_pandas/output/high_temps_30_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp33_using_pandas/output/high_temps_30_year_moving_average.png -------------------------------------------------------------------------------- /mp33_using_pandas/output/high_temps_3_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp33_using_pandas/output/high_temps_3_year_moving_average.png -------------------------------------------------------------------------------- /mp33_using_pandas/output/high_temps_5_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp33_using_pandas/output/high_temps_5_year_moving_average.png -------------------------------------------------------------------------------- /mp47_oop8_comparison_methods/river.py: -------------------------------------------------------------------------------- 1 | class River: 2 | 3 | def __init__(self, name, length=0): 4 | self.name = name 5 | # Length in km. 6 | self.length = length -------------------------------------------------------------------------------- /mp85_calc_file_paths/coffee_reader_3_dunder_file.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | path = Path(__file__).parent / "coffees.txt" 4 | contents = path.read_text() 5 | 6 | print(contents) -------------------------------------------------------------------------------- /mp89_breakpoint/generate_import_file.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | @dataclass 4 | class Member: 5 | email: str = "" 6 | member_id: str = "" 7 | name: str = "" -------------------------------------------------------------------------------- /mp128_checking_attributes/wx_model_wind.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | @dataclass 4 | class WeatherObservation: 5 | precip: float 6 | temp: float 7 | wind: float 8 | -------------------------------------------------------------------------------- /mp26_grounding_part_4/full_gpt_session_refactoring_add_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/full_gpt_session_refactoring_add_border.png -------------------------------------------------------------------------------- /mp78_streamlit_basics/roller_button.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | import streamlit as st 3 | 4 | st.button("Roll") 5 | 6 | roll = randint(1, 6) 7 | 8 | st.write(f"You rolled a {roll}.") -------------------------------------------------------------------------------- /mp16_ending_while_loops/ten_squares_flag.py: -------------------------------------------------------------------------------- 1 | x = 1 2 | active = True 3 | while active: 4 | square = x**2 5 | print(square) 6 | 7 | x += 1 8 | if x > 10: 9 | active = False -------------------------------------------------------------------------------- /mp31_importance_profiling/output/high_temps_1_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp31_importance_profiling/output/high_temps_1_year_moving_average.png -------------------------------------------------------------------------------- /mp31_importance_profiling/output/high_temps_3_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp31_importance_profiling/output/high_temps_3_year_moving_average.png -------------------------------------------------------------------------------- /mp31_importance_profiling/output/high_temps_5_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp31_importance_profiling/output/high_temps_5_year_moving_average.png -------------------------------------------------------------------------------- /mp32_importance_profiling/output/high_temps_1_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp32_importance_profiling/output/high_temps_1_year_moving_average.png -------------------------------------------------------------------------------- /mp32_importance_profiling/output/high_temps_3_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp32_importance_profiling/output/high_temps_3_year_moving_average.png -------------------------------------------------------------------------------- /mp32_importance_profiling/output/high_temps_5_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp32_importance_profiling/output/high_temps_5_year_moving_average.png -------------------------------------------------------------------------------- /mp24_grounding_part_3/tests/reference_images/bear_scratching_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/tests/reference_images/bear_scratching_default.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/tests/source_images/bear_scratching_bordered.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/tests/source_images/bear_scratching_bordered.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/tests/reference_images/bear_scratching_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/tests/reference_images/bear_scratching_default.jpg -------------------------------------------------------------------------------- /mp31_importance_profiling/output/high_temps_10_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp31_importance_profiling/output/high_temps_10_year_moving_average.png -------------------------------------------------------------------------------- /mp31_importance_profiling/output/high_temps_30_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp31_importance_profiling/output/high_temps_30_year_moving_average.png -------------------------------------------------------------------------------- /mp32_importance_profiling/output/high_temps_10_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp32_importance_profiling/output/high_temps_10_year_moving_average.png -------------------------------------------------------------------------------- /mp32_importance_profiling/output/high_temps_30_year_moving_average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp32_importance_profiling/output/high_temps_30_year_moving_average.png -------------------------------------------------------------------------------- /mp39_oop3_init/greeter.py: -------------------------------------------------------------------------------- 1 | class Greeter: 2 | """Greet people in a variety of ways.""" 3 | 4 | def say_hello(self): 5 | print("Hi.") 6 | 7 | greeter = Greeter() 8 | greeter.say_hello() -------------------------------------------------------------------------------- /mp58_urlspy_order/pianos/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class PianosConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "pianos" 7 | -------------------------------------------------------------------------------- /mp58_urlspy_order/synths/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class SynthsConfig(AppConfig): 5 | default_auto_field = "django.db.models.BigAutoField" 6 | name = "synths" 7 | -------------------------------------------------------------------------------- /mp24_grounding_part_3/tests/reference_images/bear_scratching_15px_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/tests/reference_images/bear_scratching_15px_border.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/tests/reference_images/bear_scratching_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/tests/reference_images/bear_scratching_15px_padding.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/tests/reference_images/bear_scratching_black_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/tests/reference_images/bear_scratching_black_border.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/tests/source_images/bear_scratching_original_size.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/tests/source_images/bear_scratching_original_size.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/tests/reference_images/bear_scratching_15px_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/tests/reference_images/bear_scratching_15px_border.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/tests/reference_images/bear_scratching_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/tests/reference_images/bear_scratching_15px_padding.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/tests/reference_images/bear_scratching_black_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/tests/reference_images/bear_scratching_black_border.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/tests/source_images/bear_scratching_original_size.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/tests/source_images/bear_scratching_original_size.jpg -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/primes_list.py: -------------------------------------------------------------------------------- 1 | primes = [2, 3, 5, 7, 11] 2 | primes_id = id(primes) 3 | print(primes_id, primes) 4 | 5 | primes.append(13) 6 | primes_id = id(primes) 7 | print(primes_id, primes) -------------------------------------------------------------------------------- /mp85_calc_file_paths/coffee_reader_2_absolute_path.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | path = Path( 4 | "/Users/eric/projects/coffee_project/coffees.txt") 5 | contents = path.read_text() 6 | 7 | print(contents) -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_0/source_images/bear_scratching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_0/source_images/bear_scratching.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_10/source_images/bear_scratching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_10/source_images/bear_scratching.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_4/source_images/bear_scratching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_4/source_images/bear_scratching.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_0/source_images/bear_scratching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_0/source_images/bear_scratching.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_2/source_images/bear_scratching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_2/source_images/bear_scratching.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_4/source_images/bear_scratching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_4/source_images/bear_scratching.jpg -------------------------------------------------------------------------------- /mp55_oop13_serialization_abc/robot_dict.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import json 3 | 4 | robot = {'name': 'Marvin'} 5 | 6 | robot_data = json.dumps(robot) 7 | path = Path("robot.json") 8 | path.write_text(robot_data) -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/primes_tuple.py: -------------------------------------------------------------------------------- 1 | primes = (2, 3, 5, 7, 11) 2 | primes_id = id(primes) 3 | print(primes_id, primes) 4 | 5 | primes = (2, 3, 5, 7, 11, 13) 6 | primes_id = id(primes) 7 | print(primes_id, primes) -------------------------------------------------------------------------------- /mp6_searching_quick_answers/my_great_ide.py: -------------------------------------------------------------------------------- 1 | lines = [ 2 | '"""A simple Hello World program."""', 3 | "", 4 | 'msg = "Hello Python world!"', 5 | 'print(msg)' 6 | ] 7 | 8 | for line in lines: 9 | print(line) -------------------------------------------------------------------------------- /mp85_calc_file_paths/coffee_reader_4_project_root.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | project_root = Path(__file__).parent 4 | path = project_root / "coffees" / "coffees.txt" 5 | contents = path.read_text() 6 | 7 | print(contents) -------------------------------------------------------------------------------- /mp24_grounding_part_3/tests/reference_images/bear_scratching_20px_border_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/tests/reference_images/bear_scratching_20px_border_15px_padding.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/tests/reference_images/bear_scratching_20px_border_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/tests/reference_images/bear_scratching_20px_border_15px_padding.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_default.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_default.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_default.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_default.jpg -------------------------------------------------------------------------------- /mp57_exception_hierarchy/bad_list_2_help.py: -------------------------------------------------------------------------------- 1 | python_exceptions = [ 2 | "SyntaxError", 3 | "NameError", 4 | ] 5 | 6 | try: 7 | my_exception = python_exceptions[2] 8 | except IndexError as e: 9 | help(e) 10 | raise e -------------------------------------------------------------------------------- /mp9_chatgpt_not_reliable_teacher/winners_ranked.py: -------------------------------------------------------------------------------- 1 | winners = ["elizabeth", "ryan", "kayla"] 2 | 3 | print("The winners are:") 4 | for index, winner in enumerate(winners): 5 | place = index + 1 6 | print(f"{place}. {winner.title()}") -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.pyc 3 | 4 | .DS_Store 5 | 6 | .venv/ 7 | 8 | .ipynb_checkpoints/ 9 | 10 | git-sim_media/ 11 | 12 | # Files associated with specific posts. 13 | mp23_grounding_part_2/willie_mountains_bordered.png 14 | -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_15px_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_15px_border.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_15px_padding.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_black_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_black_border.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_10/source_images/bear_scratching_original_size.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_10/source_images/bear_scratching_original_size.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_15px_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_15px_border.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_15px_padding.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_black_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_black_border.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_15px_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_15px_border.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_15px_padding.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_black_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_black_border.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_15px_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_15px_border.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_15px_padding.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_black_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_black_border.jpg -------------------------------------------------------------------------------- /mp37_oop2_self/squares.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | x_vals = list(range(100)) 4 | squares = [x**2 for x in x_vals] 5 | 6 | plt.style.use('classic') 7 | fig, ax = plt.subplots() 8 | ax.scatter(x_vals, squares) 9 | 10 | plt.show() -------------------------------------------------------------------------------- /mp57_exception_hierarchy/bad_list_5_mro.py: -------------------------------------------------------------------------------- 1 | python_exceptions = [ 2 | "SyntaxError", 3 | "NameError", 4 | ] 5 | 6 | try: 7 | my_exception = python_exceptions[2] 8 | except LookupError as e: 9 | print(type(e).mro()) 10 | raise e -------------------------------------------------------------------------------- /mp97_snippets/raw_snippets/plot_data.py: -------------------------------------------------------------------------------- 1 | for reading_set in reading_sets: 2 | ph.plot_data_static( 3 | reading_set, 4 | known_slides=known_slides, 5 | critical_points=critical_points 6 | ) 7 | 8 | a_utils.summarize_results() -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_0/reference_images/bear_scratching_bordered_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_0/reference_images/bear_scratching_bordered_default.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_4/reference_images/bear_scratching_bordered_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_4/reference_images/bear_scratching_bordered_default.jpg -------------------------------------------------------------------------------- /mp57_exception_hierarchy/bad_list_4_catch_lookuperror.py: -------------------------------------------------------------------------------- 1 | python_exceptions = [ 2 | "SyntaxError", 3 | "NameError", 4 | ] 5 | 6 | try: 7 | my_exception = python_exceptions[2] 8 | except LookupError as e: 9 | print(type(e)) 10 | raise e -------------------------------------------------------------------------------- /mp49_oop9_helper_methods/chessboard.py: -------------------------------------------------------------------------------- 1 | class ChessBoard: 2 | 3 | def __init__(self): 4 | self.position = "RNBQKBNR" 5 | 6 | def show_position(self): 7 | print(self.position) 8 | 9 | board = ChessBoard() 10 | board.show_position() -------------------------------------------------------------------------------- /mp128_checking_attributes/wx_reporter.py: -------------------------------------------------------------------------------- 1 | import wx_observer 2 | 3 | def show_summary(obs): 4 | print("\nObservation summary:") 5 | print(f" Precipitation: {obs.precip}cm") 6 | print(f" Temp: {obs.temp}C") 7 | 8 | show_summary(wx_observer.wx_obs) -------------------------------------------------------------------------------- /mp13_lists_sets/explore_responses.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import json 3 | 4 | path = Path('responses.json') 5 | contents = path.read_text() 6 | responses = json.loads(contents) 7 | 8 | num_responses = len(responses) 9 | print(f"Found {num_responses:,} responses.") -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_20px_border_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_10/reference_images/bear_scratching_20px_border_15px_padding.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_20px_border_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_0/reference_images/bear_scratching_20px_border_15px_padding.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_20px_border_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_2/reference_images/bear_scratching_20px_border_15px_padding.jpg -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_20px_border_15px_padding.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp26_grounding_part_4/partial_programs/tests_4/reference_images/bear_scratching_20px_border_15px_padding.jpg -------------------------------------------------------------------------------- /mp57_exception_hierarchy/bad_list_3_isinstance.py: -------------------------------------------------------------------------------- 1 | python_exceptions = [ 2 | "SyntaxError", 3 | "NameError", 4 | ] 5 | 6 | try: 7 | my_exception = python_exceptions[2] 8 | except IndexError as e: 9 | print(isinstance(e, LookupError)) 10 | raise e -------------------------------------------------------------------------------- /mp9_chatgpt_not_reliable_teacher/winners_bizarre_chatgpt_loop.py: -------------------------------------------------------------------------------- 1 | winners = ["elizabeth", "ryan", "kayla"] 2 | 3 | print("The winners are:") 4 | for i, winner in [(i, winner) for i, winner in enumerate(winners)]: 5 | place = i + 1 6 | print(f"{place}. {winner.title()}") -------------------------------------------------------------------------------- /mp20_list_gotchas/card_game_one_player.py: -------------------------------------------------------------------------------- 1 | from player import Player 2 | from dealer import get_card 3 | 4 | eric = Player('Eric') 5 | eric.show_cards() 6 | 7 | for _ in range(5): 8 | new_card = get_card() 9 | eric.hand.append(new_card) 10 | 11 | eric.show_cards() -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_0/reference_images/bear_scratching_bordered_default_15px_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_0/reference_images/bear_scratching_bordered_default_15px_border.jpg -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/tests_4/reference_images/bear_scratching_bordered_default_15px_border.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehmatthes/mostly_python/HEAD/mp24_grounding_part_3/partial_programs/tests_4/reference_images/bear_scratching_bordered_default_15px_border.jpg -------------------------------------------------------------------------------- /mp2_lists_closer_look/bookshelf.py: -------------------------------------------------------------------------------- 1 | books = [ 2 | "Python Crash Course", 3 | "Serious Python", 4 | "Fluent Python", 5 | "Mastering Regular Expressions", 6 | "Fundamentals of Data Visualization", 7 | ] 8 | 9 | for book in books: 10 | print(book) 11 | -------------------------------------------------------------------------------- /mp37_oop2_self/robot.py: -------------------------------------------------------------------------------- 1 | class Robot: 2 | """A class representing simple robots.""" 3 | 4 | def __init__(self, name=""): 5 | self.name = name 6 | 7 | def say_hello(self): 8 | print(f"Hi, I'm {self.name}!") 9 | 10 | my_robot = Robot("William") -------------------------------------------------------------------------------- /mp15_lists_arguments/generate_requests.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | 3 | requests = [] 4 | for r_num in range(12): 5 | request = f"request_{r_num}" 6 | if choice([True, False]): 7 | request += "_bad" 8 | requests.append(request) 9 | 10 | print(requests) -------------------------------------------------------------------------------- /mp58_urlspy_order/synths/urls.py: -------------------------------------------------------------------------------- 1 | """URL patterns for synths.""" 2 | 3 | from django.urls import path 4 | from . import views 5 | 6 | app_name = 'synths' 7 | urlpatterns = [ 8 | path('about/', views.about, name='about'), 9 | path('faq/', views.faq, name='faq'), 10 | ] -------------------------------------------------------------------------------- /mp130_door_codes/key_code_2_cli.py: -------------------------------------------------------------------------------- 1 | from random import choices 2 | import sys 3 | 4 | try: 5 | length = int(sys.argv[1]) 6 | except IndexError: 7 | length = 6 8 | 9 | keycode = choices("0123456789", k=length) 10 | keycode = "".join(keycode) 11 | 12 | print(keycode) 13 | -------------------------------------------------------------------------------- /mp46_oop7_new/nonzero_list.py: -------------------------------------------------------------------------------- 1 | class NonZeroList(list): 2 | 3 | def __init__(self, values): 4 | """Only keep nonzero values.""" 5 | values = [v for v in values if v] 6 | super().__init__(values) 7 | 8 | my_list = NonZeroList((1, 2, 0, 3, 5, 0)) 9 | print(my_list) -------------------------------------------------------------------------------- /mp47_oop8_comparison_methods/river_2_greater_than.py: -------------------------------------------------------------------------------- 1 | class River: 2 | 3 | def __init__(self, name, length=0): 4 | self.name = name 5 | # Length in km. 6 | self.length = length 7 | 8 | def __gt__(self, river_2): 9 | return self.length > river_2.length -------------------------------------------------------------------------------- /mp46_oop7_new/nonzero_tuple.py: -------------------------------------------------------------------------------- 1 | class NonZeroTuple(tuple): 2 | 3 | def __init__(self, values): 4 | """Only keep nonzero values.""" 5 | values = [v for v in values if v] 6 | super().__init__(values) 7 | 8 | my_tuple = NonZeroTuple((1, 2, 0, 3, 5, 0)) 9 | print(my_tuple) -------------------------------------------------------------------------------- /mp46_oop7_new/nonzero_tuple_2.py: -------------------------------------------------------------------------------- 1 | class NonZeroTuple(tuple): 2 | 3 | def __new__(cls, *values): 4 | """Only keep nonzero values.""" 5 | values = [v for v in values if v] 6 | return super().__new__(cls, values) 7 | 8 | my_tuple = NonZeroTuple(1, 2, 0, 3, 5, 0) 9 | print(my_tuple) -------------------------------------------------------------------------------- /mp65_october_wx/october_temps.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import pandas as pd 3 | 4 | path = Path('wx_data/sitka_temps_1983_2023.csv') 5 | df = pd.read_csv(path) 6 | df['DATE'] = pd.to_datetime(df['DATE']) 7 | 8 | dates = df['DATE'] 9 | highs = df['TMAX'] 10 | 11 | print(dates[:5], highs[:5]) -------------------------------------------------------------------------------- /mp6_searching_quick_answers/my_great_ide_index.py: -------------------------------------------------------------------------------- 1 | lines = [ 2 | '"""A simple Hello World program."""', 3 | "", 4 | 'msg = "Hello Python world!"', 5 | 'print(msg)' 6 | ] 7 | 8 | for i in range(len(lines)): 9 | line_num = i + 1 10 | print(f"{line_num}\t{lines[i]}") -------------------------------------------------------------------------------- /mp78_streamlit_basics/roller_radio.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | import streamlit as st 3 | 4 | side_options = [6, 10, 12, 20] 5 | num_sides = st.radio("Number of sides:", side_options) 6 | 7 | st.button("Roll") 8 | 9 | roll = randint(1, num_sides) 10 | 11 | st.write(f"You rolled a {roll}.") -------------------------------------------------------------------------------- /mp37_oop2_self/squares_dict.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | x_vals = list(range(100)) 4 | squares = [x**2 for x in x_vals] 5 | 6 | plt.style.use('classic') 7 | fig, ax = plt.subplots() 8 | ax.scatter(x_vals, squares) 9 | 10 | plt.show() 11 | 12 | print(type(ax)) 13 | print(ax.__dict__) -------------------------------------------------------------------------------- /mp37_oop2_self/robot_print_self.py: -------------------------------------------------------------------------------- 1 | class Robot: 2 | """A class representing simple robots.""" 3 | 4 | def __init__(self, name=""): 5 | self.name = name 6 | print(self) 7 | 8 | def say_hello(self): 9 | print(f"Hi, I'm {self.name}!") 10 | 11 | my_robot = Robot("William") -------------------------------------------------------------------------------- /mp6_searching_quick_answers/my_great_ide_enumerate.py: -------------------------------------------------------------------------------- 1 | lines = [ 2 | '"""A simple Hello World program."""', 3 | "", 4 | 'msg = "Hello Python world!"', 5 | 'print(msg)' 6 | ] 7 | 8 | for index, line in enumerate(lines): 9 | line_num = index + 1 10 | print(f"{line_num}\t{line}") -------------------------------------------------------------------------------- /mp19_improving_code_blocks/partial_programs/email_parser_1.py: -------------------------------------------------------------------------------- 1 | """Parse raw post data, and generate neatly formatted 2 | code block titles. 3 | """ 4 | 5 | from pathlib import Path 6 | 7 | # Read post file and template file. 8 | post = Path('raw_post.html').read_text() 9 | template = Path('my_template.eml').read_text() -------------------------------------------------------------------------------- /mp29_settings/small_examples.py: -------------------------------------------------------------------------------- 1 | x = 5 2 | y = x 3 | x += 1 4 | 5 | print(f'{x = }') 6 | print(f'{y = }') 7 | 8 | x = 'Hello' 9 | y = x 10 | x += ' everyone!' 11 | 12 | print(f'{x = }') 13 | print(f'{y = }') 14 | 15 | x = [1, 2, 3] 16 | y = x 17 | x.append(4) 18 | 19 | print(f'{x = }') 20 | print(f'{y = }') -------------------------------------------------------------------------------- /mp37_oop2_self/robot_army.py: -------------------------------------------------------------------------------- 1 | class Robot: 2 | """A class representing simple robots.""" 3 | 4 | def __init__(self, name=""): 5 | self.name = name 6 | print(self) 7 | 8 | def say_hello(self): 9 | print(f"Hi, I'm {self.name}!") 10 | 11 | my_army = [Robot() for _ in range(3)] -------------------------------------------------------------------------------- /mp37_oop2_self/robot_potato.py: -------------------------------------------------------------------------------- 1 | class Robot: 2 | """A class representing simple robots.""" 3 | 4 | def __init__(potato, name=""): 5 | potato.name = name 6 | 7 | def say_hello(potato): 8 | print(f"Hi, I'm {potato.name}!") 9 | 10 | my_robot = Robot("William") 11 | my_robot.say_hello() -------------------------------------------------------------------------------- /mp126_function_checklist/fn_checklist_0_parse_file.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | path = Path(__file__).parent / "deploy.py" 4 | 5 | # Get all lines with a function definition. 6 | lines = [ 7 | line 8 | for line in path.read_text().splitlines() 9 | if ' def ' in line 10 | ] 11 | 12 | breakpoint() -------------------------------------------------------------------------------- /mp29_settings/alien.py: -------------------------------------------------------------------------------- 1 | class Alien: 2 | 3 | def __init__(self, game): 4 | self.settings = game.settings 5 | 6 | def show_settings(self): 7 | print("\nIn Alien:") 8 | print(f" alien speed: {self.settings['alien_speed']}") 9 | print(f" alien direction: {self.settings['alien_direction']}") -------------------------------------------------------------------------------- /mp124_real_estate_images/image_archiver_0_naive.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import httpx 3 | 4 | url = "https://www.zillow.com/homedetails/" 5 | url += "432-Park-Ave-PENTHOUSE-New-York-NY-10022/2069500049_zpid/" 6 | r = httpx.get(url) 7 | 8 | path = Path(__file__).parent / "output_file.html" 9 | path.write_text(r.text) 10 | -------------------------------------------------------------------------------- /mp126_function_checklist/fn_checklist_1_no_comprehension.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | path = Path(__file__).parent / "deploy.py" 4 | 5 | # Get all lines with a function definition. 6 | lines = [] 7 | for line in path.read_text().splitlines(): 8 | if ' def ' in line: 9 | lines.append(line) 10 | 11 | breakpoint() -------------------------------------------------------------------------------- /mp37_oop2_self/robot_print_self_2.py: -------------------------------------------------------------------------------- 1 | class Robot: 2 | """A class representing simple robots.""" 3 | 4 | def __init__(self, name=""): 5 | self.name = name 6 | print(self) 7 | 8 | def say_hello(self): 9 | print(f"Hi, I'm {self.name}!") 10 | 11 | my_robot = Robot("William") 12 | print(my_robot) -------------------------------------------------------------------------------- /mp20_list_gotchas/dealer.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | 3 | def get_card(): 4 | """Return a random card.""" 5 | suits = ('\u2660', '\u2663', '\u2665', '\u2666') 6 | values = ( 7 | '2', '3', '4', '5', '6', '7', '8', '9', '10', 8 | 'J', 'Q', 'K', 'A' 9 | ) 10 | return choice(values) + choice(suits) -------------------------------------------------------------------------------- /mp58_urlspy_order/piano_store/urls.py: -------------------------------------------------------------------------------- 1 | """URL configuration for piano_store project.""" 2 | 3 | from django.contrib import admin 4 | from django.urls import path, include 5 | 6 | urlpatterns = [ 7 | path('admin/', admin.site.urls), 8 | path('', include('pianos.urls')), 9 | path('synths/', include('synths.urls')), 10 | ] 11 | -------------------------------------------------------------------------------- /mp89_breakpoint/generate_import_file_2_read_csv.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from pathlib import Path 3 | 4 | import pandas as pd 5 | 6 | @dataclass 7 | class Member: 8 | email: str = "" 9 | member_id: str = "" 10 | name: str = "" 11 | 12 | path = Path("subscribers.csv") 13 | subscriber_data = pd.read_csv(path) -------------------------------------------------------------------------------- /mp19_improving_code_blocks/raw_post_without_title.html: -------------------------------------------------------------------------------- 1 |

Here's a simple code block:

2 |
message = "Hello newsletter world!"
3 | print(message)
4 | 
5 | message = "This could really be formatted better. :/"
6 | print(message)
7 |

It would be nice to separate the filename from the code, and add some line numbers.

-------------------------------------------------------------------------------- /mp20_list_gotchas/fixed/dealer.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | 3 | def get_card(): 4 | """Return a random card.""" 5 | suits = ('\u2660', '\u2663', '\u2665', '\u2666') 6 | values = ( 7 | '2', '3', '4', '5', '6', '7', '8', '9', '10', 8 | 'J', 'Q', 'K', 'A' 9 | ) 10 | return choice(values) + choice(suits) -------------------------------------------------------------------------------- /mp24_grounding_part_3/add_border.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | from cli import process_cli_args 4 | import image_functions as img_fns 5 | 6 | 7 | # Process image. 8 | path, options = process_cli_args() 9 | img = img_fns.load_image(path) 10 | new_img = img_fns.process_image(img, options) 11 | img_fns.save_image(path, new_img) -------------------------------------------------------------------------------- /mp29_settings/partial_programs/alien_3.py: -------------------------------------------------------------------------------- 1 | class Alien: 2 | 3 | def __init__(self, game): 4 | self.settings = game.settings 5 | 6 | def show_settings(self): 7 | print("\nIn Alien:") 8 | print(f" alien speed: {self.settings['alien_speed']}") 9 | print(f" alien direction: {self.settings['alien_direction']}") -------------------------------------------------------------------------------- /mp12_lists_arrays/best_sequence.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | def get_flips(num_flips=10): 4 | """Return a random sequence of coin flips.""" 5 | outcomes = ('H', 'T') 6 | return random.choices(outcomes, k=num_flips) 7 | 8 | # Generate flips. 9 | all_flips = get_flips() 10 | print(f"Generated {len(all_flips):,} flips.") 11 | print(all_flips) -------------------------------------------------------------------------------- /mp19_improving_code_blocks/raw_post.html: -------------------------------------------------------------------------------- 1 |

Here's a simple code block:

2 |
### title="hello.py"
3 | message = "Hello newsletter world!"
4 | print(message)
5 | 
6 | message = "This could really be formatted better. :/"
7 | print(message)
8 |

It would be nice to separate the filename from the code, and add some line numbers.

-------------------------------------------------------------------------------- /mp44_oop6_str_repr/bonsai.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | def __init__(self, name, description=""): 4 | self.name = name 5 | self.description = description 6 | 7 | def describe_tree(self): 8 | msg = f"{self.name}: {self.description}" 9 | print(msg) 10 | 11 | tree = BonsaiTree("Winged Elm") 12 | print(tree) 13 | -------------------------------------------------------------------------------- /mp46_oop7_new/nonzero_list_2.py: -------------------------------------------------------------------------------- 1 | class NonZeroList(list): 2 | 3 | def __init__(self, values): 4 | """Only keep nonzero values.""" 5 | values = [v for v in values if v] 6 | super().__init__(values) 7 | 8 | my_list = NonZeroList((1, 2, 0, 3, 5, 0)) 9 | print(my_list) 10 | 11 | print(type(my_list)) 12 | help(my_list) 13 | -------------------------------------------------------------------------------- /mp58_urlspy_order/synths/views.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponse 2 | 3 | def about(request): 4 | for pattern in request.resolver_match.tried: 5 | print(pattern) 6 | 7 | msg = "About our synths" 8 | return HttpResponse(msg) 9 | 10 | def faq(request): 11 | msg = "Synthesizer FAQ" 12 | return HttpResponse(msg) -------------------------------------------------------------------------------- /mp10_lists_profiling/sum_squares_optimize_get_sum.py: -------------------------------------------------------------------------------- 1 | def get_squares(): 2 | """Return a list of square numbers.""" 3 | return [x**2 for x in range(50_000_000)] 4 | 5 | def get_sum(squares): 6 | """Return the sum of all squares.""" 7 | return sum(squares) 8 | 9 | squares = get_squares() 10 | sum = get_sum(squares) 11 | print(f"Sum: {sum:,}") -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/add_border_11.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | from cli import process_cli_args 4 | import image_functions as img_fns 5 | 6 | 7 | # Process image. 8 | path, options = process_cli_args() 9 | img = img_fns.load_image(path) 10 | new_img = img_fns.process_image(img, options) 11 | img_fns.save_image(path, new_img) -------------------------------------------------------------------------------- /mp29_settings/partial_programs/alien_1.py: -------------------------------------------------------------------------------- 1 | class Alien: 2 | 3 | def __init__(self, game): 4 | self.speed = game.alien_speed 5 | self.direction = game.alien_direction 6 | 7 | def show_settings(self): 8 | print("\nIn Alien:") 9 | print(f" alien speed: {self.speed}") 10 | print(f" alien direction: {self.direction}") -------------------------------------------------------------------------------- /mp19_improving_code_blocks/highlighting_lines/raw_post.html: -------------------------------------------------------------------------------- 1 |

Here's a simple code block:

2 |
### hl_lines="3,4"
3 | message = "Hello newsletter world!"
4 | print(message)
5 | 
6 | message = "This could really be formatted better. :/"
7 | print(message)
8 |

It would be nice to separate the filename from the code, and add some line numbers.

-------------------------------------------------------------------------------- /mp130_door_codes/key_code_3_repeated_digits.py: -------------------------------------------------------------------------------- 1 | from random import choices 2 | import sys 3 | 4 | try: 5 | length = int(sys.argv[1]) 6 | except IndexError: 7 | length = 6 8 | 9 | while True: 10 | keycode = choices("0123456789", k=length) 11 | if len(set(keycode)) == length - 1: 12 | break 13 | 14 | keycode = "".join(keycode) 15 | print(keycode) 16 | -------------------------------------------------------------------------------- /mp143_debugging_4/tests/e2e_tests/conftest.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import pytest 4 | 5 | 6 | # --- Fixtures --- 7 | 8 | 9 | @pytest.fixture(autouse=True, scope="session") 10 | def set_random_seed_env(): 11 | """Make random selections repeatable.""" 12 | # To verify a random action, set autouse to False and run one test. 13 | os.environ["DICE_BATTLE_RANDOM_SEED"] = "10" -------------------------------------------------------------------------------- /mp58_urlspy_order/pianos/urls.py: -------------------------------------------------------------------------------- 1 | """URL patterns for pianos.""" 2 | 3 | from django.urls import path 4 | from . import views 5 | 6 | app_name = 'pianos' 7 | urlpatterns = [ 8 | path('', views.index, name='index'), 9 | path('about/', views.about, name='about'), 10 | path('contact/', views.contact, name='contact'), 11 | path('faq/', views.faq, name='faq'), 12 | ] -------------------------------------------------------------------------------- /mp37_oop2_self/robot_print_self_3.py: -------------------------------------------------------------------------------- 1 | class Robot: 2 | """A class representing simple robots.""" 3 | 4 | def __init__(self, name=""): 5 | self.name = name 6 | print(self) 7 | 8 | def say_hello(self): 9 | print(f"Hi, I'm {self.name}!") 10 | print(self) 11 | 12 | my_robot = Robot("William") 13 | print(my_robot) 14 | 15 | my_robot.say_hello() -------------------------------------------------------------------------------- /mp89_breakpoint/generate_import_file_3_breakpoint.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from pathlib import Path 3 | import pdb 4 | 5 | import pandas as pd 6 | 7 | @dataclass 8 | class Member: 9 | email: str = "" 10 | member_id: str = "" 11 | name: str = "" 12 | 13 | path = Path("subscribers.csv") 14 | subscriber_data = pd.read_csv(path) 15 | 16 | breakpoint() 17 | -------------------------------------------------------------------------------- /mp42_oop5_class_methods/trees.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | def __init__(self, name, description=""): 4 | self.name = name 5 | self.description = description 6 | 7 | def describe_tree(self): 8 | msg = f"{self.name}: {self.description}" 9 | print(msg) 10 | 11 | tree = BonsaiTree("Winged Elm") 12 | tree.description = "tall, solid trunk" 13 | tree.describe_tree() -------------------------------------------------------------------------------- /mp41_static_methods/mountains.py: -------------------------------------------------------------------------------- 1 | class Mountain: 2 | 3 | def __init__(self, name="", elev_meters=0): 4 | self.name = name 5 | self.elev_meters = elev_meters 6 | 7 | def describe_mountain(self): 8 | msg = f"{self.name} is {self.elev_meters:,} meters tall." 9 | print(msg) 10 | 11 | my_mountain = Mountain("Mt. Verstovia", 1022) 12 | my_mountain.describe_mountain() -------------------------------------------------------------------------------- /mp148_min_rep_example/rolling_dice/die.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | class Die: 4 | """A class representing a single die.""" 5 | 6 | def __init__(self, num_sides=6): 7 | """Assume a six-sided die.""" 8 | self.num_sides = num_sides 9 | 10 | def roll(self): 11 | """"Return a random value between 1 and number of sides.""" 12 | return randint(1, self.num_sides) -------------------------------------------------------------------------------- /mp7_tracking_down_a_bug/die.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | class Die: 4 | """A class representing a single die.""" 5 | 6 | def __init__(self, num_sides=6): 7 | """Assume a six-sided die.""" 8 | self.num_sides = num_sides 9 | 10 | def roll(self): 11 | """"Return a random value between 1 and number of sides.""" 12 | return randint(1, self.num_sides) -------------------------------------------------------------------------------- /mp44_oop6_str_repr/bonsai_2.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | def __init__(self, name, description=""): 4 | self.name = name 5 | self.description = description 6 | 7 | def describe_tree(self): 8 | msg = f"{self.name}: {self.description}" 9 | print(msg) 10 | 11 | def __str__(self): 12 | return self.name 13 | 14 | tree = BonsaiTree("Winged Elm") 15 | print(tree) 16 | -------------------------------------------------------------------------------- /mp20_list_gotchas/card_game_two_players.py: -------------------------------------------------------------------------------- 1 | from player import Player 2 | from dealer import get_card 3 | 4 | eric = Player('Eric') 5 | kyle = Player('Kyle') 6 | 7 | eric.show_cards() 8 | kyle.show_cards() 9 | 10 | for _ in range(5): 11 | new_card = get_card() 12 | eric.hand.append(new_card) 13 | 14 | new_card = get_card() 15 | kyle.hand.append(new_card) 16 | 17 | eric.show_cards() 18 | kyle.show_cards() -------------------------------------------------------------------------------- /mp61_oop16/triangle_nums.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | # Generate data. 4 | triangle_nums = [1, 3, 6, 10, 15, 21] 5 | x_values = [1, 2, 3, 4, 5, 6] 6 | 7 | # Generate plot. 8 | fig, ax = plt.subplots() 9 | ax.scatter(x_values, triangle_nums) 10 | 11 | # Format plot. 12 | ax.set_title("Triangle Numbers") 13 | ax.set_xlabel("N") 14 | ax.set_ylabel("Nth Triangle Number") 15 | 16 | # Show plot. 17 | plt.show() -------------------------------------------------------------------------------- /mp149_debugging_8/card_data.py: -------------------------------------------------------------------------------- 1 | suits_symbols = { 2 | "spades": "\u2660", 3 | "hearts": "\u2665", 4 | "diamonds": "\u2666", 5 | "clubs": "\u2663", 6 | } 7 | 8 | ranks_values = { 9 | "2": 2, 10 | "3": 3, 11 | "4": 4, 12 | "5": 5, 13 | "6": 6, 14 | "7": 7, 15 | "8": 8, 16 | "9": 9, 17 | "10": 10, 18 | "J": 11, 19 | "Q": 12, 20 | "K": 13, 21 | "A": 14, 22 | } 23 | -------------------------------------------------------------------------------- /mp150_debugging_9/card_data.py: -------------------------------------------------------------------------------- 1 | suits_symbols = { 2 | "spades": "\u2660", 3 | "hearts": "\u2665", 4 | "diamonds": "\u2666", 5 | "clubs": "\u2663", 6 | } 7 | 8 | ranks_values = { 9 | "2": 2, 10 | "3": 3, 11 | "4": 4, 12 | "5": 5, 13 | "6": 6, 14 | "7": 7, 15 | "8": 8, 16 | "9": 9, 17 | "10": 10, 18 | "J": 11, 19 | "Q": 12, 20 | "K": 13, 21 | "A": 14, 22 | } 23 | -------------------------------------------------------------------------------- /mp20_list_gotchas/fixed/card_game_two_players.py: -------------------------------------------------------------------------------- 1 | from player import Player 2 | from dealer import get_card 3 | 4 | eric = Player('Eric') 5 | kyle = Player('Kyle') 6 | 7 | eric.show_cards() 8 | kyle.show_cards() 9 | 10 | for _ in range(5): 11 | new_card = get_card() 12 | eric.hand.append(new_card) 13 | 14 | new_card = get_card() 15 | kyle.hand.append(new_card) 16 | 17 | eric.show_cards() 18 | kyle.show_cards() -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/poker_hands.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | 3 | all_cards = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'j', 'q', 'k', 'a'] 4 | 5 | def get_hand(hand_size=5): 6 | """Return a hand of cards.""" 7 | return [choice(all_cards) for _ in range(hand_size)] 8 | 9 | num_hands = 10 10 | hands = [get_hand() for _ in range(num_hands)] 11 | 12 | print(f"\nGenerated {len(hands):,} hands.") 13 | print(hands[0]) -------------------------------------------------------------------------------- /mp10_lists_profiling/sum_squares_optimize_get_squares.py: -------------------------------------------------------------------------------- 1 | def get_squares(): 2 | """Return a list of square numbers.""" 3 | return [x**2 for x in range(50_000_000)] 4 | 5 | def get_sum(squares): 6 | """Return the sum of all squares.""" 7 | sum = 0 8 | for square in squares: 9 | sum += square 10 | 11 | return sum 12 | 13 | squares = get_squares() 14 | sum = get_sum(squares) 15 | print(f"Sum: {sum:,}") -------------------------------------------------------------------------------- /mp154_debugging_11/card_data.py: -------------------------------------------------------------------------------- 1 | suits_symbols = { 2 | "spades": "\u2660", 3 | "hearts": "\u2665", 4 | "diamonds": "\u2666", 5 | "clubs": "\u2663", 6 | } 7 | 8 | ranks_values = { 9 | "2": 2, 10 | "3": 3, 11 | "4": 4, 12 | "5": 5, 13 | "6": 6, 14 | "7": 7, 15 | "8": 8, 16 | "9": 9, 17 | "10": 10, 18 | "J": 11, 19 | "Q": 12, 20 | "K": 13, 21 | "A": 14, 22 | } 23 | -------------------------------------------------------------------------------- /mp156_debugging_13/card_data.py: -------------------------------------------------------------------------------- 1 | suits_symbols = { 2 | "spades": "\u2660", 3 | "hearts": "\u2665", 4 | "diamonds": "\u2666", 5 | "clubs": "\u2663", 6 | } 7 | 8 | ranks_values = { 9 | "2": 2, 10 | "3": 3, 11 | "4": 4, 12 | "5": 5, 13 | "6": 6, 14 | "7": 7, 15 | "8": 8, 16 | "9": 9, 17 | "10": 10, 18 | "J": 11, 19 | "Q": 12, 20 | "K": 13, 21 | "A": 14, 22 | } 23 | -------------------------------------------------------------------------------- /mp26_grounding_part_4/main.py: -------------------------------------------------------------------------------- 1 | from cli_args import parse_cli_args 2 | from image_processing import add_border_to_image 3 | 4 | def main(): 5 | # Get the filename and optional CLI args. 6 | args = parse_cli_args() 7 | 8 | # Add border to image and save the new image. 9 | new_img_path = add_border_to_image(args) 10 | print(f"New image saved at {new_img_path}") 11 | 12 | if __name__ == "__main__": 13 | main() -------------------------------------------------------------------------------- /mp29_settings/partial_programs/game_0.py: -------------------------------------------------------------------------------- 1 | class Game: 2 | 3 | def __init__(self): 4 | self.alien_speed = 5 5 | self.alien_direction = 1 6 | 7 | def show_settings(self): 8 | print("\nIn Game:") 9 | print(f" alien speed: {self.alien_speed}") 10 | print(f" alien direction: {self.alien_direction}") 11 | 12 | if __name__ == '__main__': 13 | game = Game() 14 | game.show_settings() -------------------------------------------------------------------------------- /mp3_lists_closer_look/random_numbers_insert.py: -------------------------------------------------------------------------------- 1 | # random_numbers_insert.py 2 | 3 | from random import randint 4 | 5 | # Build a list of random numbers, to simulate rolling a die. 6 | # The most recent roll is always first in the list. 7 | rolls = [] 8 | for _ in range(220_000): 9 | roll = randint(1,6) 10 | rolls.insert(0, roll) 11 | 12 | # Verify how many rolls were generated. 13 | print(f"Generated {len(rolls):,} rolls.") -------------------------------------------------------------------------------- /mp43_substack_notes_cguo/main.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | session = requests.Session() 4 | 5 | # Log in, using the existing session. 6 | login_url = "https://substack.com/api/v1/login" 7 | login_data = { 8 | "redirect": "", 9 | "for_pub": "PUBLICATION", 10 | "email": "MY_EMAIL", 11 | "password": "MY_PASSWORD", 12 | "captcha_response": None, 13 | } 14 | 15 | login_response = session.post(login_url, json=login_data) -------------------------------------------------------------------------------- /mp151_debugging_10/go_fish_fixed/card_data.py: -------------------------------------------------------------------------------- 1 | suits_symbols = { 2 | "spades": "\u2660", 3 | "hearts": "\u2665", 4 | "diamonds": "\u2666", 5 | "clubs": "\u2663", 6 | } 7 | 8 | ranks_values = { 9 | "2": 2, 10 | "3": 3, 11 | "4": 4, 12 | "5": 5, 13 | "6": 6, 14 | "7": 7, 15 | "8": 8, 16 | "9": 9, 17 | "10": 10, 18 | "J": 11, 19 | "Q": 12, 20 | "K": 13, 21 | "A": 14, 22 | } 23 | -------------------------------------------------------------------------------- /mp128_checking_attributes/wx_reporter_3_hasattr.py: -------------------------------------------------------------------------------- 1 | import wx_observer 2 | import wx_observer_wind 3 | 4 | def show_summary(obs): 5 | print("\nObservation summary:") 6 | print(f" Precipitation: {obs.precip}cm") 7 | print(f" Temp: {obs.temp}C") 8 | 9 | if hasattr(obs, "wind"): 10 | print(f" Wind: {obs.wind}kph") 11 | 12 | show_summary(wx_observer.wx_obs) 13 | show_summary(wx_observer_wind.wx_obs) 14 | -------------------------------------------------------------------------------- /mp151_debugging_10/cards_with_error/card_data.py: -------------------------------------------------------------------------------- 1 | suits_symbols = { 2 | "spades": "\u2660", 3 | "hearts": "\u2665", 4 | "diamonds": "\u2666", 5 | "clubs": "\u2663", 6 | } 7 | 8 | ranks_values = { 9 | "2": 2, 10 | "3": 3, 11 | "4": 4, 12 | "5": 5, 13 | "6": 6, 14 | "7": 7, 15 | "8": 8, 16 | "9": 9, 17 | "10": 10, 18 | "J": 11, 19 | "Q": 12, 20 | "K": 13, 21 | "A": 14, 22 | } 23 | -------------------------------------------------------------------------------- /mp151_debugging_10/go_fish_with_error/card_data.py: -------------------------------------------------------------------------------- 1 | suits_symbols = { 2 | "spades": "\u2660", 3 | "hearts": "\u2665", 4 | "diamonds": "\u2666", 5 | "clubs": "\u2663", 6 | } 7 | 8 | ranks_values = { 9 | "2": 2, 10 | "3": 3, 11 | "4": 4, 12 | "5": 5, 13 | "6": 6, 14 | "7": 7, 15 | "8": 8, 16 | "9": 9, 17 | "10": 10, 18 | "J": 11, 19 | "Q": 12, 20 | "K": 13, 21 | "A": 14, 22 | } 23 | -------------------------------------------------------------------------------- /mp155_debugging_12/go_fish_bugfix/card_data.py: -------------------------------------------------------------------------------- 1 | suits_symbols = { 2 | "spades": "\u2660", 3 | "hearts": "\u2665", 4 | "diamonds": "\u2666", 5 | "clubs": "\u2663", 6 | } 7 | 8 | ranks_values = { 9 | "2": 2, 10 | "3": 3, 11 | "4": 4, 12 | "5": 5, 13 | "6": 6, 14 | "7": 7, 15 | "8": 8, 16 | "9": 9, 17 | "10": 10, 18 | "J": 11, 19 | "Q": 12, 20 | "K": 13, 21 | "A": 14, 22 | } 23 | -------------------------------------------------------------------------------- /mp155_debugging_12/go_fish_seeded/card_data.py: -------------------------------------------------------------------------------- 1 | suits_symbols = { 2 | "spades": "\u2660", 3 | "hearts": "\u2665", 4 | "diamonds": "\u2666", 5 | "clubs": "\u2663", 6 | } 7 | 8 | ranks_values = { 9 | "2": 2, 10 | "3": 3, 11 | "4": 4, 12 | "5": 5, 13 | "6": 6, 14 | "7": 7, 15 | "8": 8, 16 | "9": 9, 17 | "10": 10, 18 | "J": 11, 19 | "Q": 12, 20 | "K": 13, 21 | "A": 14, 22 | } 23 | -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/main_3.py: -------------------------------------------------------------------------------- 1 | from cli_args import parse_cli_args 2 | from image_processing import add_border_to_image 3 | 4 | def main(): 5 | # Get the filename and optional CLI args. 6 | args = parse_cli_args() 7 | 8 | # Add border to image and save the new image. 9 | new_img_path = add_border_to_image(args) 10 | print(f"New image saved at {new_img_path}") 11 | 12 | if __name__ == "__main__": 13 | main() -------------------------------------------------------------------------------- /mp65_october_wx/october_temps_2_october_data.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import pandas as pd 3 | 4 | path = Path('wx_data/sitka_temps_1983_2023.csv') 5 | df_all = pd.read_csv(path) 6 | df_all['DATE'] = pd.to_datetime(df_all['DATE']) 7 | 8 | # Keep only October's data for each year. 9 | df_october = df_all[df_all['DATE'].dt.month == 10] 10 | 11 | dates = df_october['DATE'] 12 | highs = df_october['TMAX'] 13 | 14 | print(dates[:5], highs[:5]) -------------------------------------------------------------------------------- /mp143_debugging_4/die.py: -------------------------------------------------------------------------------- 1 | import random 2 | import os 3 | from dataclasses import dataclass 4 | 5 | 6 | # Set a random seed when testing. 7 | if seed := os.environ.get("DICE_BATTLE_RANDOM_SEED"): 8 | random.seed(int(seed)) 9 | 10 | 11 | @dataclass 12 | class Die: 13 | """Model a single die.""" 14 | 15 | num_sides: int = 6 16 | 17 | def roll(self): 18 | """Roll the die.""" 19 | return random.randint(1, self.num_sides) -------------------------------------------------------------------------------- /mp39_oop3_init/greeter_4_initialize_object.py: -------------------------------------------------------------------------------- 1 | class Greeter: 2 | """Greet people in a variety of ways.""" 3 | 4 | def initialize_object(self, tone="casual"): 5 | self.tone = tone 6 | 7 | def say_hello(self): 8 | if self.tone == "casual": 9 | print("Hi.") 10 | elif self.tone == "formal": 11 | print("Hello.") 12 | 13 | greeter = Greeter() 14 | greeter.initialize_object() 15 | greeter.say_hello() -------------------------------------------------------------------------------- /mp126_function_checklist/fn_checklist_6_simpler_approach.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import re 3 | import sys 4 | 5 | # Read program file. 6 | path = Path(sys.argv[1]) 7 | contents = path.read_text() 8 | 9 | # Find all function names. 10 | fn_name_re = r".*def ([a-z_]*)\(" 11 | fn_names = re.findall(fn_name_re, contents) 12 | 13 | # Generate an issues task list. 14 | for name in fn_names: 15 | task = f"- [ ] `{name}()`" 16 | print(task) 17 | -------------------------------------------------------------------------------- /mp33_using_pandas/high_temp_trends.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import pandas as pd 4 | 5 | def get_data(path): 6 | """Extract dates and high temperatures.""" 7 | df = pd.read_csv(path) 8 | df['DATE'] = pd.to_datetime(df['DATE']) 9 | 10 | return df['DATE'], df['TMAX'] 11 | 12 | # Extract data. 13 | path = Path('wx_data/sitka_highs_1944_2023.csv') 14 | dates, highs = get_data(path) 15 | print(f"\nFound {len(highs):,} data points.") -------------------------------------------------------------------------------- /mp39_oop3_init/greeter_2_tone.py: -------------------------------------------------------------------------------- 1 | class Greeter: 2 | """Greet people in a variety of ways.""" 3 | 4 | def __init__(self, tone="casual"): 5 | self.tone = tone 6 | 7 | def say_hello(self): 8 | if self.tone == "casual": 9 | print("Hi.") 10 | elif self.tone == "formal": 11 | print("Hello.") 12 | 13 | greeter = Greeter() 14 | greeter.say_hello() 15 | 16 | greeter.tone = "formal" 17 | greeter.say_hello() -------------------------------------------------------------------------------- /mp3_lists_closer_look/list_memory.py: -------------------------------------------------------------------------------- 1 | # list_memory.py 2 | 3 | import sys 4 | from random import randint 5 | 6 | # Build a list of random numbers, to simulate rolling a die. 7 | rolls = [] 8 | for x in range(10): 9 | roll = randint(1,6) 10 | rolls.append(roll) 11 | 12 | # Examine the length and size of the list. 13 | list_length = len(rolls) 14 | list_size = sys.getsizeof(rolls) 15 | print(f"Items: {list_length}\tBytes: {list_size}") -------------------------------------------------------------------------------- /mp39_oop3_init/greeter_3_misspelled.py: -------------------------------------------------------------------------------- 1 | class Greeter: 2 | """Greet people in a variety of ways.""" 3 | 4 | def _init__(self, tone="casual"): 5 | self.tone = tone 6 | 7 | def say_hello(self): 8 | if self.tone == "casual": 9 | print("Hi.") 10 | elif self.tone == "formal": 11 | print("Hello.") 12 | 13 | greeter = Greeter() 14 | greeter.say_hello() 15 | 16 | greeter.tone = "formal" 17 | greeter.say_hello() -------------------------------------------------------------------------------- /mp47_oop8_comparison_methods/river_3_lt_eq.py: -------------------------------------------------------------------------------- 1 | class River: 2 | 3 | def __init__(self, name, length=0): 4 | self.name = name 5 | # Length in km. 6 | self.length = length 7 | 8 | def __gt__(self, river_2): 9 | return self.length > river_2.length 10 | 11 | def __lt__(self, river_2): 12 | return self.length < river_2.length 13 | 14 | def __eq__(self, river_2): 15 | return self.length == river_2.length -------------------------------------------------------------------------------- /mp37_oop2_self/robot_expanded.py: -------------------------------------------------------------------------------- 1 | class Robot: 2 | """A class representing simple robots.""" 3 | 4 | def __init__(self, name=""): 5 | self.name = name 6 | self.type = "drone" 7 | self.mass_grams = 249 8 | 9 | def say_hello(self): 10 | print(f"Hi, I'm {self.name}!") 11 | print(f"I'm a {self.type}.") 12 | print(f"I have a mass of {self.mass_grams}g.") 13 | 14 | my_robot = Robot("William") 15 | my_robot.say_hello() -------------------------------------------------------------------------------- /mp3_lists_closer_look/random_numbers_deque.py: -------------------------------------------------------------------------------- 1 | # random_numbers_deque.py 2 | 3 | from random import randint 4 | from collections import deque 5 | 6 | # Build a list of random numbers, to simulate rolling a die. 7 | # The most recent roll is always first in the list. 8 | rolls = deque() 9 | for _ in range(20_000_000): 10 | roll = randint(1,6) 11 | rolls.appendleft(roll) 12 | 13 | # Verify how many rolls were generated. 14 | print(f"Generated {len(rolls):,} rolls.") -------------------------------------------------------------------------------- /mp58_urlspy_order/pianos/views.py: -------------------------------------------------------------------------------- 1 | from django.http import HttpResponse 2 | 3 | def index(request): 4 | msg = "Welcome to the Piano Store!" 5 | return HttpResponse(msg) 6 | 7 | def about(request): 8 | msg = "About the Piano Store" 9 | return HttpResponse(msg) 10 | 11 | def contact(request): 12 | msg = "Contact the Piano Store" 13 | return HttpResponse(msg) 14 | 15 | def faq(request): 16 | msg = "Piano Store FAQ" 17 | return HttpResponse(msg) -------------------------------------------------------------------------------- /mp128_checking_attributes/wx_reporter_2_try_except.py: -------------------------------------------------------------------------------- 1 | import wx_observer 2 | import wx_observer_wind 3 | 4 | def show_summary(obs): 5 | print("\nObservation summary:") 6 | print(f" Precipitation: {obs.precip}cm") 7 | print(f" Temp: {obs.temp}C") 8 | 9 | try: 10 | print(f" Wind: {obs.wind}kph") 11 | except AttributeError: 12 | pass 13 | 14 | show_summary(wx_observer.wx_obs) 15 | show_summary(wx_observer_wind.wx_obs) 16 | -------------------------------------------------------------------------------- /mp130_door_codes/key_code_4_refactored.py: -------------------------------------------------------------------------------- 1 | from random import choices 2 | import sys 3 | 4 | try: 5 | length = int(sys.argv[1]) 6 | except IndexError: 7 | length = 6 8 | 9 | def get_keycode(): 10 | """Generate a reasonably secure keycode.""" 11 | while True: 12 | keycode = choices("0123456789", k=length) 13 | if len(set(keycode)) == length - 1: 14 | return "".join(keycode) 15 | 16 | keycode = get_keycode() 17 | print(keycode) 18 | -------------------------------------------------------------------------------- /mp13_lists_sets/explore_responses_set.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import json 3 | 4 | path = Path('responses.json') 5 | contents = path.read_text() 6 | responses = json.loads(contents) 7 | 8 | num_responses = len(responses) 9 | print(f"Found {num_responses:,} responses.") 10 | 11 | # Find the unique responses. 12 | unique_responses = set(responses) 13 | 14 | num_unique = len(unique_responses) 15 | print(f"Found {num_unique} unique responses.") 16 | print(unique_responses) -------------------------------------------------------------------------------- /mp55_oop13_serialization_abc/robot_class.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import json 3 | 4 | class Robot: 5 | 6 | def __init__(self, name=""): 7 | self.name = name 8 | 9 | def say_hi(self): 10 | print(f"Hi, I'm {self.name} the robot.") 11 | 12 | # Create an instance of Robot. 13 | robot = Robot('Marvin') 14 | 15 | # Convert the data to JSON, and save it. 16 | robot_data = json.dumps(robot) 17 | path = Path("robot.json") 18 | path.write_text(robot_data) -------------------------------------------------------------------------------- /mp61_oop16/triangle_nums_2_print_fig_ax.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | # Generate data. 4 | triangle_nums = [1, 3, 6, 10, 15, 21] 5 | x_values = [1, 2, 3, 4, 5, 6] 6 | 7 | # Generate plot. 8 | fig, ax = plt.subplots() 9 | ax.scatter(x_values, triangle_nums) 10 | print(type(fig)) 11 | print(type(ax)) 12 | 13 | # Format plot. 14 | ax.set_title("Triangle Numbers") 15 | ax.set_xlabel("N") 16 | ax.set_ylabel("Nth Triangle Number") 17 | 18 | # Show plot. 19 | plt.show() -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/cli_args_1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | def parse_cli_args(argv): 4 | try: 5 | path = Path(argv[1]) 6 | except IndexError: 7 | print("You must provide a target image.") 8 | sys.exit() 9 | 10 | border_width = int(argv[2]) if len(argv) > 2 else 2 11 | padding = int(argv[3]) if len(argv) > 3 else 0 12 | border_color = argv[4] if len(argv) > 4 else "lightgray" 13 | 14 | return path, border_width, padding, border_color -------------------------------------------------------------------------------- /mp61_oop16/triangle_nums_3_facecolor.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | # Generate data. 4 | triangle_nums = [1, 3, 6, 10, 15, 21] 5 | x_values = [1, 2, 3, 4, 5, 6] 6 | 7 | # Generate plot. 8 | fig, ax = plt.subplots(facecolor='#9ccbf0') 9 | ax.scatter(x_values, triangle_nums) 10 | print(type(fig)) 11 | print(type(ax)) 12 | 13 | # Format plot. 14 | ax.set_title("Triangle Numbers") 15 | ax.set_xlabel("N") 16 | ax.set_ylabel("Nth Triangle Number") 17 | 18 | # Show plot. 19 | plt.show() -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/add_border_9.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | from cli import process_cli_args 4 | import image_functions as img_fns 5 | 6 | 7 | # Set default options. 8 | options = { 9 | 'border_width': 2, 10 | 'padding': 0, 11 | 'border_color': 'lightgray' 12 | } 13 | 14 | # Process image. 15 | path = process_cli_args(options) 16 | img = img_fns.load_image(path) 17 | new_img = img_fns.process_image(img, options) 18 | img_fns.save_image(path, new_img) -------------------------------------------------------------------------------- /mp58_urlspy_order/piano_store/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for piano_store project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "piano_store.settings") 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /mp58_urlspy_order/piano_store/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for piano_store project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "piano_store.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /mp126_function_checklist/fn_checklist_2_all_fn_names.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import re 3 | 4 | path = Path(__file__).parent / "deploy.py" 5 | 6 | # Get all lines with a function definition. 7 | lines = [ 8 | line 9 | for line in path.read_text().splitlines() 10 | if ' def ' in line 11 | ] 12 | 13 | # Extract each function name. 14 | fn_name_re = r".*def ([a-z_]*)\(" 15 | fn_names = [ 16 | re.match(fn_name_re, line).group(1) 17 | for line in lines 18 | ] 19 | 20 | breakpoint() -------------------------------------------------------------------------------- /mp37_oop2_self/robot_self_dict.py: -------------------------------------------------------------------------------- 1 | class Robot: 2 | """A class representing simple robots.""" 3 | 4 | def __init__(self, name=""): 5 | self.name = name 6 | self.type = "drone" 7 | self.mass_grams = 249 8 | print(self.__dict__) 9 | 10 | def say_hello(self): 11 | print(f"Hi, I'm {self.name}!") 12 | print(f"I'm a {self.type}.") 13 | print(f"I have a mass of {self.mass_grams}g.") 14 | 15 | my_robot = Robot("William") 16 | my_robot.say_hello() -------------------------------------------------------------------------------- /mp10_lists_profiling/sum_squares.py: -------------------------------------------------------------------------------- 1 | def get_squares(): 2 | """Return a list of square numbers.""" 3 | squares = [] 4 | for x in range(50_000_000): 5 | square = x**2 6 | squares.append(square) 7 | 8 | return squares 9 | 10 | def get_sum(squares): 11 | """Return the sum of all squares.""" 12 | sum = 0 13 | for square in squares: 14 | sum += square 15 | 16 | return sum 17 | 18 | squares = get_squares() 19 | sum = get_sum(squares) 20 | print(f"Sum: {sum:,}") -------------------------------------------------------------------------------- /mp17_lists_modifying_in_loop/process_requests_good.py: -------------------------------------------------------------------------------- 1 | # process_requests_gotcha.py 2 | 3 | # Make a mix of valid and invalid requests. 4 | requests = [ 5 | 'request_0', 'request_1_bad', 'request_2', 6 | 'request_3_bad', 'request_4_bad', 'request_5', 7 | 'request_6', 'request_7_bad', 'request_8', 8 | 'request_9_bad', 'request_10', 'request_11_bad' 9 | ] 10 | 11 | # Keep only valid requests. 12 | requests = [r for r in requests if 'bad' not in r] 13 | 14 | # Show what's left. 15 | print(requests) -------------------------------------------------------------------------------- /mp3_lists_closer_look/random_numbers.py: -------------------------------------------------------------------------------- 1 | # random_numbers.py 2 | 3 | from random import randint 4 | 5 | # Build a list of random numbers, to simulate rolling a die. 6 | rolls = [] 7 | for _ in range(20_000_000): 8 | roll = randint(1,6) 9 | rolls.append(roll) 10 | 11 | # Verify how many rolls were generated. 12 | print(f"Generated {len(rolls):,} rolls.") 13 | 14 | # Print the first ten rolls, and the last ten rolls. 15 | print(f"First ten rolls: {rolls[:10]}") 16 | print(f"Last ten rolls: {rolls[-10:]}") -------------------------------------------------------------------------------- /mp78_streamlit_basics/roller_num_dice_slider.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | import streamlit as st 3 | 4 | # Input widgets 5 | side_options = [6, 10, 12, 20] 6 | num_sides = st.radio("Number of sides:", side_options) 7 | num_dice = st.slider("Number of dice:", 1, 10, value=2) 8 | 9 | st.button("Roll") 10 | 11 | # Roll calculation 12 | rolls = [randint(1, num_sides) for _ in range(num_dice)] 13 | roll = sum(rolls) 14 | 15 | # Output message 16 | st.write("---") 17 | st.subheader(roll) 18 | st.write(str(rolls)) -------------------------------------------------------------------------------- /oop_18/partial_versions/climbing_library_0.py: -------------------------------------------------------------------------------- 1 | from library_models import Library, Book, Patron 2 | 3 | # Create a library. 4 | library = Library(name="The Climber's Library") 5 | 6 | # Create some books. 7 | book = Book( 8 | title="Freedom of the Hills", 9 | author="The Mountaineers", 10 | ) 11 | library.resources.append(book) 12 | 13 | book = Book( 14 | title="Learning to Fly", 15 | author="Steph Davis", 16 | ) 17 | library.resources.append(book) 18 | 19 | # Show all books. 20 | library.show_books() -------------------------------------------------------------------------------- /mp2_lists_closer_look/bookshelf.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) { 4 | 5 | // Declare an array of 5 pointers. 6 | char *books[5] = { 7 | "Python Crash Course", 8 | "Serious Python", 9 | "Fluent Python", 10 | "Mastering Regular Expressions", 11 | "Fundamentals of Data Visualization" 12 | }; 13 | 14 | // Loop over the array, and print each element. 15 | for (int i=0; i<5; i++) { 16 | printf("%s\n", books[i]); 17 | } 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /mp37_oop2_self/robot_no_self.py: -------------------------------------------------------------------------------- 1 | def make_robot(name=""): 2 | """Make a robot.""" 3 | robot_dict = { 4 | "name": name, 5 | "type": "drone", 6 | "mass_grams": 249, 7 | } 8 | 9 | return robot_dict 10 | 11 | def say_hello(robot_dict): 12 | """Make a robot say hello.""" 13 | print(f"Hi, I'm {robot_dict['name']}.") 14 | print(f"I'm a {robot_dict['type']}.") 15 | print(f"I have a mass of {robot_dict['mass_grams']}g.") 16 | 17 | my_robot = make_robot("William") 18 | say_hello(my_robot) -------------------------------------------------------------------------------- /mp20_list_gotchas/player.py: -------------------------------------------------------------------------------- 1 | """Represent a player in a card game.""" 2 | 3 | class Player: 4 | 5 | def __init__(self, name, hand=[]): 6 | """Each player has a name, and a hand.""" 7 | self.name = name 8 | self.hand = hand 9 | 10 | def show_cards(self): 11 | """Show all the cards in the current hand.""" 12 | if self.hand: 13 | print(f"{self.name} has the following cards:") 14 | print(f"\t{self.hand}") 15 | else: 16 | print(f"{self.name} has no cards.") -------------------------------------------------------------------------------- /mp126_function_checklist/fn_checklist_3_no_comprehension.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import re 3 | 4 | path = Path(__file__).parent / "deploy.py" 5 | 6 | # Get all lines with a function definition. 7 | lines = [ 8 | line 9 | for line in path.read_text().splitlines() 10 | if ' def ' in line 11 | ] 12 | 13 | # Extract each function name. 14 | fn_name_re = r".*def ([a-z_]*)\(" 15 | fn_names = [] 16 | for line in lines: 17 | fn_name = re.match(fn_name_re, line).group(1) 18 | fn_names.append(fn_name) 19 | 20 | breakpoint() -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/cli_args_2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from pathlib import Path 3 | 4 | def parse_cli_args(): 5 | try: 6 | path = Path(sys.argv[1]) 7 | except IndexError: 8 | print("You must provide a target image.") 9 | sys.exit() 10 | 11 | border_width = int(sys.argv[2]) if len(sys.argv) > 2 else 2 12 | padding = int(sys.argv[3]) if len(sys.argv) > 3 else 0 13 | border_color = sys.argv[4] if len(sys.argv) > 4 else "lightgray" 14 | 15 | return path, border_width, padding, border_color -------------------------------------------------------------------------------- /mp61_oop16/triangle_nums_4_text.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | # Generate data. 4 | triangle_nums = [1, 3, 6, 10, 15, 21] 5 | x_values = [1, 2, 3, 4, 5, 6] 6 | 7 | # Generate plot. 8 | fig, ax = plt.subplots(facecolor='#9ccbf0') 9 | fig.text(x=0.82, y=0.025, s="mostlypython.substack") 10 | ax.scatter(x_values, triangle_nums) 11 | print(type(fig)) 12 | print(type(ax)) 13 | 14 | # Format plot. 15 | ax.set_title("Triangle Numbers") 16 | ax.set_xlabel("N") 17 | ax.set_ylabel("Nth Triangle Number") 18 | 19 | # Show plot. 20 | plt.show() -------------------------------------------------------------------------------- /mp29_settings/partial_programs/game_1.py: -------------------------------------------------------------------------------- 1 | from alien_1 import Alien 2 | 3 | class Game: 4 | 5 | def __init__(self): 6 | self.alien_speed = 5 7 | self.alien_direction = 1 8 | 9 | self.alien = Alien(self) 10 | 11 | def show_settings(self): 12 | print("\nIn Game:") 13 | print(f" alien speed: {self.alien_speed}") 14 | print(f" alien direction: {self.alien_direction}") 15 | 16 | if __name__ == '__main__': 17 | game = Game() 18 | game.show_settings() 19 | game.alien.show_settings() 20 | -------------------------------------------------------------------------------- /oop_19/office_hours_monitor.py: -------------------------------------------------------------------------------- 1 | import os, sys, time 2 | import requests 3 | 4 | url = "https://on.substack.com/s/office-hours" 5 | 6 | for attempt_num in range(90): 7 | r = requests.get(url) 8 | print(f"Attempt #{attempt_num}. Status: {r.status_code}") 9 | 10 | if " mins ago<" in r.text: 11 | cmd = f'open -a "Google Chrome" {url}' 12 | os.system(cmd) 13 | print(" Found a new post!") 14 | sys.exit() 15 | else: 16 | print(" No new post found. Waiting one minute...") 17 | time.sleep(60) -------------------------------------------------------------------------------- /mp17_lists_modifying_in_loop/process_requests_gotcha.py: -------------------------------------------------------------------------------- 1 | # process_requests_gotcha.py 2 | 3 | # Make a mix of valid and invalid requests. 4 | requests = [ 5 | 'request_0', 'request_1_bad', 'request_2', 6 | 'request_3_bad', 'request_4_bad', 'request_5', 7 | 'request_6', 'request_7_bad', 'request_8', 8 | 'request_9_bad', 'request_10', 'request_11_bad' 9 | ] 10 | 11 | # Remove invalid requests. 12 | for request in requests: 13 | if 'bad' in request: 14 | requests.remove(request) 15 | 16 | # Show what's left. 17 | print(requests) -------------------------------------------------------------------------------- /mp44_oop6_str_repr/bonsai_3.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | def __init__(self, name, description=""): 4 | self.name = name 5 | self.description = description 6 | 7 | def describe_tree(self): 8 | msg = f"{self.name}: {self.description}" 9 | print(msg) 10 | 11 | def __repr__(self): 12 | if self.description: 13 | return (f"BonsaiTree(name={self.name}, " 14 | f"description={self.description})") 15 | else: 16 | return(f"BonsaiTree(name={self.name})") 17 | -------------------------------------------------------------------------------- /mp145_debugging_6/strat_players.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | import plotly.express as px 4 | 5 | import player_data 6 | 7 | # Generate plot. 8 | fig = px.timeline( 9 | player_data.df, 10 | x_start="start", 11 | x_end="end", 12 | y="name", 13 | ) 14 | 15 | # Customize plot. 16 | fig.update_yaxes(autorange="reversed") 17 | 18 | fig.update_layout(title="Fender Strat players") 19 | fig.update_layout(yaxis_title=None) 20 | 21 | fig.update_traces(marker_color='SteelBlue') 22 | fig.update_traces(marker_opacity=0.6) 23 | 24 | fig.show() 25 | -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/main_2.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from cli_args import parse_cli_args 3 | from image_processing import add_border_to_image 4 | 5 | def main(): 6 | # Get the filename and optional CLI args. 7 | path, border_width, padding, border_color = parse_cli_args() 8 | 9 | # Add border to image and save the new image. 10 | new_img_path = add_border_to_image(path, border_width, 11 | padding, border_color) 12 | print(f"New image saved at {new_img_path}") 13 | 14 | if __name__ == "__main__": 15 | main() -------------------------------------------------------------------------------- /mp120_lotteries/nc_powerball.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | def get_ticket(ticket_size=5, max_value=69): 4 | """Get a ticket of ticket_size numbers. 5 | Numbers are picked from 1 through max_value). 6 | """ 7 | ticket = [] 8 | 9 | while len(ticket) < ticket_size: 10 | pulled_number = randint(1, max_value) 11 | 12 | # Don't reuse numbers. 13 | if pulled_number in ticket: 14 | continue 15 | 16 | ticket.append(pulled_number) 17 | 18 | ticket.sort() 19 | return ticket 20 | 21 | breakpoint() -------------------------------------------------------------------------------- /mp124_real_estate_images/image_archiver_1_selenium.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import httpx 4 | 5 | from selenium import webdriver 6 | from selenium.webdriver.chrome.service import Service 7 | from webdriver_manager.chrome import ChromeDriverManager 8 | 9 | 10 | url = "https://www.zillow.com/homedetails/" 11 | url += "432-Park-Ave-PENTHOUSE-New-York-NY-10022/2069500049_zpid/" 12 | 13 | driver = webdriver.Chrome( 14 | service=Service(ChromeDriverManager().install())) 15 | 16 | # Open main property page. 17 | driver.get(url) 18 | 19 | breakpoint() 20 | -------------------------------------------------------------------------------- /mp23_grounding_part_2/partial_programs/add_border_1.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | from pathlib import Path 4 | from PIL import Image, ImageOps 5 | 6 | # Load the image. 7 | path = Path("willie_mountains.png") 8 | img = Image.open(path) 9 | 10 | # Set the border width and color. 11 | border_width = 2 12 | border_color = "darkgray" 13 | 14 | # Add the border. 15 | new_img = ImageOps.expand(img, border=border_width, 16 | fill=border_color) 17 | 18 | # Save new image. 19 | new_path = Path("willie_mountains_bordered.png") 20 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp33_using_pandas/high_temp_trends_show_invalid.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import pandas as pd 4 | 5 | def get_data(path): 6 | """Extract dates and high temperatures.""" 7 | df = pd.read_csv(path) 8 | df['DATE'] = pd.to_datetime(df['DATE']) 9 | 10 | return df['DATE'], df['TMAX'] 11 | 12 | # Extract data. 13 | path = Path('wx_data/sitka_highs_1944_2023.csv') 14 | dates, highs = get_data(path) 15 | print(f"\nFound {len(highs):,} data points.") 16 | 17 | num_invalid = highs.isna().sum() 18 | print(f"There are {num_invalid} invalid readings.") -------------------------------------------------------------------------------- /mp17_lists_modifying_in_loop/process_requests_good_multiline.py: -------------------------------------------------------------------------------- 1 | # process_requests_gotcha.py 2 | 3 | # Make a mix of valid and invalid requests. 4 | requests = [ 5 | 'request_0', 'request_1_bad', 'request_2', 6 | 'request_3_bad', 'request_4_bad', 'request_5', 7 | 'request_6', 'request_7_bad', 'request_8', 8 | 'request_9_bad', 'request_10', 'request_11_bad' 9 | ] 10 | 11 | # Keep only valid requests. 12 | requests = [ 13 | request 14 | for request in requests 15 | if 'bad' not in request 16 | ] 17 | 18 | # Show what's left. 19 | print(requests) -------------------------------------------------------------------------------- /mp19_improving_code_blocks/partial_programs/email_parser_2.py: -------------------------------------------------------------------------------- 1 | """Parse raw post data, and generate neatly formatted 2 | code block titles. 3 | """ 4 | 5 | from pathlib import Path 6 | 7 | # Read post file and template file. 8 | post = Path('raw_post.html').read_text() 9 | template = Path('my_template.eml').read_text() 10 | 11 | # Loop over the lines in the raw post. 12 | # When we get to a code block, look for a title. 13 | # If we find a title, rewrite that line and the 14 | # next line. 15 | modified_lines = [] 16 | lines = post.split("\n") 17 | lines_iter = iter(lines) -------------------------------------------------------------------------------- /mp49_oop9_helper_methods/chessboard_2.py: -------------------------------------------------------------------------------- 1 | from random import shuffle 2 | 3 | class ChessBoard: 4 | 5 | def __init__(self, variant=""): 6 | self.variant = variant 7 | 8 | if self.variant == "fischer960": 9 | pieces = ["R", "N", "B", "Q", "K", "B", "N", "R"] 10 | shuffle(pieces) 11 | self.position = ''.join(pieces) 12 | else: 13 | self.position = "RNBQKBNR" 14 | 15 | def show_position(self): 16 | print(self.position) 17 | 18 | board = ChessBoard(variant="fischer960") 19 | board.show_position() -------------------------------------------------------------------------------- /mp13_lists_sets/explore_responses_naive.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import json 3 | 4 | path = Path('responses.json') 5 | contents = path.read_text() 6 | responses = json.loads(contents) 7 | 8 | num_responses = len(responses) 9 | print(f"Found {num_responses:,} responses.") 10 | 11 | # Find the unique responses. 12 | unique_responses = [] 13 | for response in responses: 14 | if response not in unique_responses: 15 | unique_responses.append(response) 16 | 17 | num_unique = len(unique_responses) 18 | print(f"Found {num_unique} unique responses.") 19 | print(unique_responses) -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/main_1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from pathlib import Path 3 | from cli_args import parse_cli_args 4 | from image_processing import add_border_to_image 5 | 6 | def main(): 7 | # Get the filename and optional CLI args. 8 | path, border_width, padding, border_color = parse_cli_args(sys.argv) 9 | 10 | # Add border to image and save the new image. 11 | new_img_path = add_border_to_image(path, border_width, 12 | padding, border_color) 13 | print(f"New image saved at {new_img_path}") 14 | 15 | if __name__ == "__main__": 16 | main() -------------------------------------------------------------------------------- /mp126_function_checklist/fn_checklist_4_task_list.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import re 3 | 4 | path = Path(__file__).parent / "deploy.py" 5 | 6 | # Get all lines with a function definition. 7 | lines = [ 8 | line 9 | for line in path.read_text().splitlines() 10 | if ' def ' in line 11 | ] 12 | 13 | # Extract each function name. 14 | fn_name_re = r".*def ([a-z_]*)\(" 15 | fn_names = [ 16 | re.match(fn_name_re, line).group(1) 17 | for line in lines 18 | ] 19 | 20 | # Generate an issues task list. 21 | for name in fn_names: 22 | task = f"- [ ] `{name}()`" 23 | print(task) 24 | -------------------------------------------------------------------------------- /mp126_function_checklist/fn_checklist_5_pass_filename.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import re 3 | import sys 4 | 5 | path = Path(sys.argv[1]) 6 | 7 | # Get all lines with a function definition. 8 | lines = [ 9 | line 10 | for line in path.read_text().splitlines() 11 | if ' def ' in line 12 | ] 13 | 14 | # Extract each function name. 15 | fn_name_re = r".*def ([a-z_]*)\(" 16 | fn_names = [ 17 | re.match(fn_name_re, line).group(1) 18 | for line in lines 19 | ] 20 | 21 | # Generate an issues task list. 22 | for name in fn_names: 23 | task = f"- [ ] `{name}()`" 24 | print(task) 25 | -------------------------------------------------------------------------------- /mp23_grounding_part_2/partial_programs/add_border_3.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | import sys 4 | from pathlib import Path 5 | from PIL import Image, ImageOps 6 | 7 | # Load the image. 8 | path = Path(sys.argv[1]) 9 | img = Image.open(path) 10 | 11 | # Set the border width and color. 12 | border_width = 2 13 | border_color = "darkgray" 14 | 15 | # Add the border. 16 | new_img = ImageOps.expand(img, border=border_width, 17 | fill=border_color) 18 | 19 | # Save new image. 20 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 21 | print(new_path) 22 | # new_img.save(new_path) -------------------------------------------------------------------------------- /mp55_oop13_serialization_abc/robot_class_write.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from marshmallow import Schema, fields 4 | 5 | class Robot: 6 | 7 | def __init__(self, name=""): 8 | self.name = name 9 | 10 | def say_hi(self): 11 | print(f"Hi, I'm {self.name} the robot.") 12 | 13 | class RobotSchema(Schema): 14 | name = fields.Str() 15 | 16 | # Create an instance of Robot. 17 | robot = Robot('Marvin') 18 | 19 | # Use RobotSchema to serialize the data. 20 | schema = RobotSchema() 21 | robot_data = schema.dumps(robot) 22 | 23 | path = Path("robot.json") 24 | path.write_text(robot_data) -------------------------------------------------------------------------------- /mp143_debugging_4/dice_battle.py: -------------------------------------------------------------------------------- 1 | """Simulate a game of rolling dice. 2 | 3 | Two players take turns rolling dice, and see who 4 | rolls a higher number. 5 | """ 6 | 7 | import utils 8 | 9 | 10 | # Simulate some battles between players A and B. 11 | num_battles = 10 12 | results = { 13 | "wins_a": 0, 14 | "wins_b": 0, 15 | "ties": 0, 16 | } 17 | 18 | for _ in range(num_battles): 19 | a_result, b_result = utils.battle() 20 | print(f"\nPlayer A: {a_result}") 21 | print(f"Player B: {b_result}") 22 | 23 | utils.update_results(a_result, b_result, results) 24 | 25 | utils.show_summary(results) 26 | -------------------------------------------------------------------------------- /mp20_list_gotchas/fixed/player.py: -------------------------------------------------------------------------------- 1 | """Represent a player in a card game.""" 2 | 3 | class Player: 4 | 5 | def __init__(self, name, hand=None): 6 | """Each player has a name, and a hand.""" 7 | self.name = name 8 | if not hand: 9 | self.hand = [] 10 | else: 11 | self.hand = hand 12 | 13 | def show_cards(self): 14 | """Show all the cards in the current hand.""" 15 | if self.hand: 16 | print(f"{self.name} has the following cards:") 17 | print(f"\t{self.hand}") 18 | else: 19 | print(f"{self.name} has no cards.") -------------------------------------------------------------------------------- /mp17_lists_modifying_in_loop/process_requests_good_full_loop.py: -------------------------------------------------------------------------------- 1 | # process_requests_gotcha.py 2 | 3 | # Make a mix of valid and invalid requests. 4 | requests = [ 5 | 'request_0', 'request_1_bad', 'request_2', 6 | 'request_3_bad', 'request_4_bad', 'request_5', 7 | 'request_6', 'request_7_bad', 'request_8', 8 | 'request_9_bad', 'request_10', 'request_11_bad' 9 | ] 10 | 11 | # Keep only valid requests. 12 | # Keep only valid requests. 13 | valid_requests = [] 14 | for request in requests: 15 | if 'bad' not in request: 16 | valid_requests.append(request) 17 | 18 | # Show what's left. 19 | print(valid_requests) -------------------------------------------------------------------------------- /mp23_grounding_part_2/partial_programs/add_border_2.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | import sys 4 | from pathlib import Path 5 | from PIL import Image, ImageOps 6 | 7 | # Get the filename. 8 | print(sys.argv) 9 | 10 | # Load the image. 11 | path = Path("willie_mountains.png") 12 | img = Image.open(path) 13 | 14 | # Set the border width and color. 15 | border_width = 2 16 | border_color = "darkgray" 17 | 18 | # Add the border. 19 | new_img = ImageOps.expand(img, border=border_width, 20 | fill=border_color) 21 | 22 | # Save new image. 23 | new_path = Path("willie_mountains_bordered.png") 24 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp17_lists_modifying_in_loop/process_requests_gotcha_diagnostic.py: -------------------------------------------------------------------------------- 1 | # process_requests_gotcha.py 2 | 3 | # Make a mix of valid and invalid requests. 4 | requests = [ 5 | 'request_0', 'request_1_bad', 'request_2', 6 | 'request_3_bad', 'request_4_bad', 'request_5', 7 | 'request_6', 'request_7_bad', 'request_8', 8 | 'request_9_bad', 'request_10', 'request_11_bad' 9 | ] 10 | 11 | # Remove invalid requests. 12 | for index, request in enumerate(requests): 13 | print(f"Examining request: {index} - {request}") 14 | if 'bad' in request: 15 | requests.remove(request) 16 | 17 | # Show what's left. 18 | print(requests) -------------------------------------------------------------------------------- /mp48_radians_function/squares_degrees.py: -------------------------------------------------------------------------------- 1 | import turtle as t 2 | 3 | # Set window size and drawing speed. 4 | t.screensize(700, 550) 5 | t.speed(10) 6 | 7 | def draw_square(size): 8 | t.pendown() 9 | for _ in range(4): 10 | t.forward(size) 11 | t.left(90) 12 | t.penup() 13 | 14 | # Make a pattern of squares. 15 | num_squares = 10 16 | for _ in range(num_squares): 17 | draw_square(250) 18 | # Turn an amount that will use all the squares 19 | # to complete one full revolution around 20 | # the center point. 21 | t.left(360/num_squares) 22 | 23 | # Keep the drawing window open. 24 | t.done() -------------------------------------------------------------------------------- /mp52_oop11_inheritance/account.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | """Model a user account on a site or app.""" 3 | 4 | def __init__(self, username, password=""): 5 | self.username = username 6 | self._store_password(password) 7 | 8 | def welcome_user(self): 9 | print(f"Welcome to the site, {self.username}!") 10 | 11 | def close_account(self): 12 | print(f"Closed account for {self.username}.") 13 | 14 | def _store_password(self, password): 15 | print(f"Stored password for {self.username}.") 16 | 17 | if __name__ == "__main__": 18 | account = Account("eric") 19 | account.welcome_user() -------------------------------------------------------------------------------- /mp49_oop9_helper_methods/chessboard_3.py: -------------------------------------------------------------------------------- 1 | from random import shuffle 2 | 3 | class ChessBoard: 4 | 5 | def __init__(self, variant=""): 6 | self.variant = variant 7 | self.position = self._get_starting_position() 8 | 9 | def show_position(self): 10 | print(self.position) 11 | 12 | def _get_starting_position(self): 13 | if self.variant == "fischer960": 14 | pieces = ["R", "N", "B", "Q", "K", "B", "N", "R"] 15 | shuffle(pieces) 16 | return ''.join(pieces) 17 | else: 18 | return "RNBQKBNR" 19 | 20 | board = ChessBoard(variant="fischer960") 21 | board.show_position() -------------------------------------------------------------------------------- /mp89_breakpoint/generate_import_file_4_fill_datacass.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from pathlib import Path 3 | import pdb 4 | 5 | import pandas as pd 6 | 7 | @dataclass 8 | class Member: 9 | email: str = "" 10 | member_id: str = "" 11 | name: str = "" 12 | 13 | path = Path("subscribers.csv") 14 | subscriber_data = pd.read_csv(path) 15 | 16 | emails = list(subscriber_data.email) 17 | names = list(subscriber_data.name) 18 | 19 | # Build a list of Members. 20 | members = [] 21 | for email, name in zip(emails, names): 22 | member = Member() 23 | member.email = email 24 | member.name = name 25 | 26 | members.append(member) 27 | 28 | breakpoint() 29 | -------------------------------------------------------------------------------- /mp41_static_methods/mountains_5_call_from_class.py: -------------------------------------------------------------------------------- 1 | class Mountain: 2 | 3 | def __init__(self, name="", elev_meters=0): 4 | self.name = name 5 | self.elev_meters = elev_meters 6 | 7 | def describe_mountain(self): 8 | msg = f"{self.name} is {self.elev_meters:,} meters tall." 9 | print(msg) 10 | 11 | @staticmethod 12 | def show_disclaimer(): 13 | msg = "\nClimbing steep mountains can be dangerous." 14 | msg += " If you are new to climbing," 15 | msg += " please seek out instruction from" 16 | msg += " a qualified guide or an" 17 | msg += " experienced mentor." 18 | print(msg) 19 | 20 | Mountain.show_disclaimer() -------------------------------------------------------------------------------- /mp68_gift_exchange/gift_exchange_2_check_match.py: -------------------------------------------------------------------------------- 1 | names = [ 2 | "Sherri", 3 | "Eric", 4 | "Terri", 5 | "Joel", 6 | "Joshua", 7 | "Catherine", 8 | "Jasmine", 9 | "Alexandra", 10 | "Jeremiah", 11 | ] 12 | 13 | partners = [ 14 | ("Sherri", "Eric"), 15 | ("Terri", "Joel"), 16 | ("Joshua", "Catherine"), 17 | ("Jasmine", "Alexandra"), 18 | ] 19 | 20 | def check_match(match): 21 | if match in partners: 22 | return False 23 | if tuple(reversed(match)) in partners: 24 | return False 25 | return True 26 | 27 | print(check_match(('Sherri', 'Eric'))) 28 | print(check_match(('Eric', 'Sherri'))) 29 | print(check_match(('Sherri', 'Terri'))) -------------------------------------------------------------------------------- /mp42_oop5_class_methods/trees_2.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | def __init__(self, name, description=""): 4 | self.name = name 5 | self.description = description 6 | 7 | def describe_tree(self): 8 | msg = f"{self.name}: {self.description}" 9 | print(msg) 10 | 11 | trees = [] 12 | 13 | tree = BonsaiTree("Winged Elm") 14 | tree.description = "tall, solid trunk" 15 | trees.append(tree) 16 | 17 | tree = BonsaiTree("El Arbol Murcielago") 18 | tree.description = "short, open trunk" 19 | trees.append(tree) 20 | 21 | tree = BonsaiTree("Mt. Mitchell") 22 | tree.description = "small mountain forest" 23 | trees.append(tree) 24 | 25 | for tree in trees: 26 | tree.describe_tree() -------------------------------------------------------------------------------- /oop_18/partial_versions/climbing_library_1_lend_book.py: -------------------------------------------------------------------------------- 1 | from library_models import Library, Book, Patron 2 | 3 | # Create a library. 4 | library = Library(name="The Climber's Library") 5 | 6 | # Create some books. 7 | book = Book( 8 | title="Freedom of the Hills", 9 | author="The Mountaineers", 10 | ) 11 | library.resources.append(book) 12 | 13 | book = Book( 14 | title="Learning to Fly", 15 | author="Steph Davis", 16 | ) 17 | library.resources.append(book) 18 | 19 | # Show all books. 20 | library.show_books() 21 | 22 | # Lend a book. 23 | birdie = Patron("Birdie") 24 | freedom_hills = library.get_books()[0] 25 | freedom_hills.lend(birdie) 26 | 27 | # Show all books. 28 | library.show_books() -------------------------------------------------------------------------------- /oop_18/partial_versions/library_models_0.py: -------------------------------------------------------------------------------- 1 | class Resource: 2 | def __init__(self, resource_type): 3 | self.resource_type = resource_type 4 | self.current_borrower = None 5 | 6 | def lend(self, patron): 7 | self.current_borrower = patron 8 | 9 | def return_resource(self): 10 | self.current_borrower = None 11 | 12 | class Book(Resource): 13 | def __init__(self, title="", author=""): 14 | self.title = title 15 | self.author = author 16 | super().__init__(resource_type="book") 17 | 18 | def get_info(self): 19 | return f"{self.title}, by {self.author}" 20 | 21 | class Patron: 22 | def __init__(self, name): 23 | self.name = name -------------------------------------------------------------------------------- /mp48_radians_function/squares_radians.py: -------------------------------------------------------------------------------- 1 | import turtle as t 2 | import math 3 | 4 | # Set window size and drawing speed. 5 | t.screensize(700, 550) 6 | t.speed(10) 7 | 8 | # Use radians for all angle measurements. 9 | t.radians() 10 | 11 | def draw_square(size): 12 | t.pendown() 13 | for _ in range(4): 14 | t.forward(size) 15 | t.left(math.pi/2) 16 | t.penup() 17 | 18 | # Make a pattern of squares. 19 | num_squares = 10 20 | for _ in range(num_squares): 21 | draw_square(250) 22 | # Turn an amount that will use all the squares 23 | # to complete one full revolution around 24 | # the center point. 25 | t.left((2*math.pi)/num_squares) 26 | 27 | # Keep the drawing window open. 28 | t.done() -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/cli_args_3.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from pathlib import Path 3 | from dataclasses import dataclass 4 | 5 | @dataclass 6 | class ImageBorderArgs: 7 | path: Path 8 | border_width: int 9 | padding: int 10 | border_color: str 11 | 12 | def parse_cli_args(): 13 | try: 14 | path = Path(sys.argv[1]) 15 | except IndexError: 16 | print("You must provide a target image.") 17 | sys.exit() 18 | 19 | border_width = int(sys.argv[2]) if len(sys.argv) > 2 else 2 20 | padding = int(sys.argv[3]) if len(sys.argv) > 3 else 0 21 | border_color = sys.argv[4] if len(sys.argv) > 4 else "lightgray" 22 | 23 | return ImageBorderArgs(path, border_width, padding, border_color) -------------------------------------------------------------------------------- /mp58_urlspy_order/synths_ursl_tried.txt: -------------------------------------------------------------------------------- 1 | [ (admin:admin) 'admin/'>] 2 | [ (pianos:pianos) ''>, ] 3 | [ (pianos:pianos) ''>, ] 4 | [ (pianos:pianos) ''>, ] 5 | [ (pianos:pianos) ''>, ] 6 | [ (synths:synths) 'synths/'>, ] -------------------------------------------------------------------------------- /mp21_list_deepcopy/locations.py: -------------------------------------------------------------------------------- 1 | class Location: 2 | 3 | def __init__(self, x=0, y=0): 4 | self.x = x 5 | self.y = y 6 | 7 | def __repr__(self): 8 | return f"({self.x}, {self.y})" 9 | 10 | location_1 = Location(0, 10) 11 | location_2 = Location(0, 20) 12 | location_3 = Location(0, 30) 13 | 14 | locations = [location_1, location_2, location_3] 15 | original_locations = locations.copy() 16 | 17 | print(f"current locations:\t{locations}") 18 | print(f"original locations:\t{original_locations}") 19 | 20 | # Shift all locations to the right. 21 | location_1.x += 10 22 | location_2.x += 10 23 | location_3.x += 10 24 | 25 | print(f"current locations:\t{locations}") 26 | print(f"original locations:\t{original_locations}") -------------------------------------------------------------------------------- /mp148_min_rep_example/rolling_dice/die_visual.py: -------------------------------------------------------------------------------- 1 | import plotly.express as px 2 | 3 | from die import Die 4 | 5 | 6 | # Create a D6. 7 | die = Die() 8 | 9 | # Make some rolls, and store results in a list. 10 | results = [] 11 | for roll_num in range(1000): 12 | result = die.roll() 13 | results.append(result) 14 | 15 | # Analyze the results. 16 | frequencies = [] 17 | poss_results = range(1, die.num_sides+1) 18 | for value in poss_results: 19 | frequency = results.count(value) 20 | frequencies.append(frequency) 21 | 22 | # Visualize the results. 23 | title = "Results of Rolling One D6 1,000 Times" 24 | labels = {'x': 'Result', 'y': 'Frequency of Result'} 25 | fig = px.bar(x=poss_results, y=frequencies, title=title, labels=labels) 26 | fig.show() -------------------------------------------------------------------------------- /mp19_improving_code_blocks/partial_programs/email_parser_3.py: -------------------------------------------------------------------------------- 1 | """Parse raw post data, and generate neatly formatted 2 | code block titles. 3 | """ 4 | 5 | from pathlib import Path 6 | 7 | # Read post file and template file. 8 | post = Path('raw_post.html').read_text() 9 | template = Path('my_template.eml').read_text() 10 | 11 | # Loop over the lines in the raw post. 12 | # When we get to a code block, look for a title. 13 | # If we find a title, rewrite that line and the 14 | # next line. 15 | modified_lines = [] 16 | lines = post.split("\n") 17 | lines_iter = iter(lines) 18 | 19 | while True: 20 | try: 21 | line = next(lines_iter) 22 | except StopIteration: 23 | break 24 | else: 25 | # Process lines here. 26 | pass -------------------------------------------------------------------------------- /mp41_static_methods/mountains_2_disclaimer.py: -------------------------------------------------------------------------------- 1 | class Mountain: 2 | 3 | def __init__(self, name="", elev_meters=0): 4 | self.name = name 5 | self.elev_meters = elev_meters 6 | 7 | def describe_mountain(self): 8 | msg = f"{self.name} is {self.elev_meters:,} meters tall." 9 | print(msg) 10 | 11 | def show_disclaimer(self): 12 | msg = "\nClimbing steep mountains can be dangerous." 13 | msg += " If you are new to climbing," 14 | msg += " please seek out instruction from" 15 | msg += " a qualified guide or an" 16 | msg += " experienced mentor." 17 | print(msg) 18 | 19 | my_mountain = Mountain("Mt. Verstovia", 1022) 20 | my_mountain.describe_mountain() 21 | 22 | my_mountain.show_disclaimer() -------------------------------------------------------------------------------- /mp49_oop9_helper_methods/chessboard_4.py: -------------------------------------------------------------------------------- 1 | from random import shuffle 2 | 3 | class ChessBoard: 4 | 5 | def __init__(self, variant=""): 6 | self.variant = variant 7 | self.position = self._get_starting_position() 8 | 9 | def show_position(self): 10 | print(self.position) 11 | 12 | def _get_starting_position(self): 13 | if self.variant == "fischer960": 14 | return self._get_fischer960_position() 15 | else: 16 | return "RNBQKBNR" 17 | 18 | @staticmethod 19 | def _get_fischer960_position(): 20 | pieces = ["R", "N", "B", "Q", "K", "B", "N", "R"] 21 | shuffle(pieces) 22 | return ''.join(pieces) 23 | 24 | board = ChessBoard(variant="fischer960") 25 | board.show_position() -------------------------------------------------------------------------------- /mp41_static_methods/mountains_3_disclaimer_no_self_error.py: -------------------------------------------------------------------------------- 1 | class Mountain: 2 | 3 | def __init__(self, name="", elev_meters=0): 4 | self.name = name 5 | self.elev_meters = elev_meters 6 | 7 | def describe_mountain(self): 8 | msg = f"{self.name} is {self.elev_meters:,} meters tall." 9 | print(msg) 10 | 11 | def show_disclaimer(): 12 | msg = "\nClimbing steep mountains can be dangerous." 13 | msg += " If you are new to climbing," 14 | msg += " please seek out instruction from" 15 | msg += " a qualified guide or an" 16 | msg += " experienced mentor." 17 | print(msg) 18 | 19 | my_mountain = Mountain("Mt. Verstovia", 1022) 20 | my_mountain.describe_mountain() 21 | 22 | my_mountain.show_disclaimer() -------------------------------------------------------------------------------- /mp58_urlspy_order/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "piano_store.settings") 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == "__main__": 22 | main() 23 | -------------------------------------------------------------------------------- /mp21_list_deepcopy/locations_deepcopy.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | 3 | class Location: 4 | 5 | def __init__(self, x=0, y=0): 6 | self.x = x 7 | self.y = y 8 | 9 | def __repr__(self): 10 | return f"({self.x}, {self.y})" 11 | 12 | location_1 = Location(0, 10) 13 | location_2 = Location(0, 20) 14 | location_3 = Location(0, 30) 15 | 16 | locations = [location_1, location_2, location_3] 17 | original_locations = deepcopy(locations) 18 | 19 | print(f"current locations:\t{locations}") 20 | print(f"original locations:\t{original_locations}") 21 | 22 | # Shift all locations to the right. 23 | location_1.x += 10 24 | location_2.x += 10 25 | location_3.x += 10 26 | 27 | print(f"current locations:\t{locations}") 28 | print(f"original locations:\t{original_locations}") -------------------------------------------------------------------------------- /mp41_static_methods/mountains_4_static_method.py: -------------------------------------------------------------------------------- 1 | class Mountain: 2 | 3 | def __init__(self, name="", elev_meters=0): 4 | self.name = name 5 | self.elev_meters = elev_meters 6 | 7 | def describe_mountain(self): 8 | msg = f"{self.name} is {self.elev_meters:,} meters tall." 9 | print(msg) 10 | 11 | @staticmethod 12 | def show_disclaimer(): 13 | msg = "\nClimbing steep mountains can be dangerous." 14 | msg += " If you are new to climbing," 15 | msg += " please seek out instruction from" 16 | msg += " a qualified guide or an" 17 | msg += " experienced mentor." 18 | print(msg) 19 | 20 | my_mountain = Mountain("Mt. Verstovia", 1022) 21 | my_mountain.describe_mountain() 22 | 23 | my_mountain.show_disclaimer() -------------------------------------------------------------------------------- /mp55_oop13_serialization_abc/robot_class_read.py: -------------------------------------------------------------------------------- 1 | import json 2 | from pathlib import Path 3 | 4 | from marshmallow import Schema, fields, post_load 5 | 6 | class Robot: 7 | 8 | def __init__(self, name=""): 9 | self.name = name 10 | 11 | def say_hi(self): 12 | print(f"Hi, I'm {self.name} the robot.") 13 | 14 | class RobotSchema(Schema): 15 | name = fields.Str() 16 | 17 | @post_load 18 | def make_robot(self, data, **kwargs): 19 | return Robot(**data) 20 | 21 | # Read in the data. 22 | path = Path("robot.json") 23 | robot_data = path.read_text() 24 | robot_data = json.loads(robot_data) 25 | 26 | # Use RobotSchema to deserialize the data. 27 | schema = RobotSchema() 28 | robot = schema.load(robot_data) 29 | 30 | # Use the robot. 31 | robot.say_hi() 32 | print(robot) -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/image_processing_1.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from PIL import Image, ImageOps, UnidentifiedImageError 3 | 4 | def add_border_to_image(path, border_width, padding, border_color): 5 | try: 6 | img = Image.open(path) 7 | except FileNotFoundError: 8 | print(f"{path} does not seem to exist.") 9 | sys.exit() 10 | except UnidentifiedImageError: 11 | print(f"{path} does not seem to be an image file.") 12 | sys.exit() 13 | 14 | new_img = ImageOps.expand(img, border=padding, fill="white") 15 | new_img = ImageOps.expand(new_img, border=border_width, 16 | fill=border_color) 17 | 18 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 19 | new_img.save(new_path) 20 | 21 | return new_path -------------------------------------------------------------------------------- /mp31_importance_profiling/high_temp_trends.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import csv 3 | from datetime import datetime 4 | 5 | def get_data(path): 6 | """Extract dates and high temperatures.""" 7 | lines = path.read_text().splitlines() 8 | reader = csv.reader(lines) 9 | header_row = next(reader) 10 | 11 | dates, highs = [], [] 12 | for row in reader: 13 | try: 14 | high = int(row[2]) 15 | highs.append(high) 16 | current_date = datetime.strptime(row[1], '%Y-%m-%d') 17 | dates.append(current_date) 18 | except ValueError: 19 | print(row) 20 | 21 | return dates, highs 22 | 23 | # Extract data. 24 | path = Path('wx_data/sitka_highs_1944_2012.csv') 25 | dates, highs = get_data(path) 26 | print(f"\nFound {len(highs):,} data points.") -------------------------------------------------------------------------------- /mp32_importance_profiling/high_temp_trends.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import csv 3 | from datetime import datetime 4 | 5 | def get_data(path): 6 | """Extract dates and high temperatures.""" 7 | lines = path.read_text().splitlines() 8 | reader = csv.reader(lines) 9 | header_row = next(reader) 10 | 11 | dates, highs = [], [] 12 | for row in reader: 13 | try: 14 | high = int(row[2]) 15 | highs.append(high) 16 | current_date = datetime.strptime(row[1], '%Y-%m-%d') 17 | dates.append(current_date) 18 | except ValueError: 19 | print(row) 20 | 21 | return dates, highs 22 | 23 | # Extract data. 24 | path = Path('wx_data/sitka_highs_1944_2012.csv') 25 | dates, highs = get_data(path) 26 | print(f"\nFound {len(highs):,} data points.") -------------------------------------------------------------------------------- /mp23_grounding_part_2/partial_programs/add_border_4.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | import sys 4 | from pathlib import Path 5 | from PIL import Image, ImageOps 6 | 7 | # Get the filename. 8 | try: 9 | path = Path(sys.argv[1]) 10 | except IndexError: 11 | print("You must provide a target image.") 12 | sys.exit() 13 | 14 | # Load the image. 15 | try: 16 | img = Image.open(path) 17 | except FileNotFoundError: 18 | print(f"{path} does not seem to exist.") 19 | sys.exit() 20 | 21 | # Set the border width and color. 22 | border_width = 2 23 | border_color = "darkgray" 24 | 25 | # Add the border. 26 | new_img = ImageOps.expand(img, border=border_width, 27 | fill=border_color) 28 | 29 | # Save new image. 30 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 31 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp29_settings/partial_programs/game_2.py: -------------------------------------------------------------------------------- 1 | from alien_1 import Alien 2 | 3 | class Game: 4 | 5 | def __init__(self): 6 | self.alien_speed = 5 7 | self.alien_direction = 1 8 | 9 | self.alien = Alien(self) 10 | 11 | def show_settings(self): 12 | print("\nIn Game:") 13 | print(f" alien speed: {self.alien_speed}") 14 | print(f" alien direction: {self.alien_direction}") 15 | 16 | def increase_speed(self): 17 | self.alien_speed += 1 18 | 19 | def change_direction(self): 20 | self.alien_direction *= -1 21 | 22 | if __name__ == '__main__': 23 | game = Game() 24 | game.show_settings() 25 | game.alien.show_settings() 26 | 27 | game.increase_speed() 28 | game.change_direction() 29 | 30 | game.show_settings() 31 | game.alien.show_settings() 32 | -------------------------------------------------------------------------------- /mp52_oop11_inheritance/account_2_free.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | """Model a user account on a site or app.""" 3 | 4 | def __init__(self, username, password=""): 5 | self.username = username 6 | self._store_password(password) 7 | 8 | def welcome_user(self): 9 | print(f"Welcome to the site, {self.username}!") 10 | 11 | def close_account(self): 12 | print(f"Closed account for {self.username}.") 13 | 14 | def _store_password(self, password): 15 | print(f"Stored password for {self.username}.") 16 | 17 | 18 | class FreeAccount(Account): 19 | 20 | def welcome_user(self): 21 | super().welcome_user() 22 | print("You'll have limited access on a free account.") 23 | 24 | 25 | if __name__ == "__main__": 26 | account = FreeAccount("eric") 27 | account.welcome_user() -------------------------------------------------------------------------------- /mp15_lists_arguments/process_requests.py: -------------------------------------------------------------------------------- 1 | def validate_requests(raw_requests, valid_requests): 2 | """Validate a sequence of requests.""" 3 | while raw_requests: 4 | request = raw_requests.pop(0) 5 | if "bad" not in request: 6 | valid_requests.append(request) 7 | 8 | # Make a list of raw requests, and a list to hold valid requests. 9 | my_raw_requests = [ 10 | 'request_0', 'request_1_bad', 'request_2', 11 | 'request_3_bad', 'request_4_bad', 'request_5', 12 | 'request_6', 'request_7_bad', 'request_8', 13 | 'request_9_bad', 'request_10', 'request_11_bad' 14 | ] 15 | my_valid_requests = [] 16 | 17 | # Validate requests, and see what has changed. 18 | validate_requests(my_raw_requests, my_valid_requests) 19 | 20 | print(f"My raw requests: {my_raw_requests}") 21 | print(f"My valid requests: {my_valid_requests}") -------------------------------------------------------------------------------- /mp52_oop11_inheritance/account_4_account_hardcoded.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | """Model a user account on a site or app.""" 3 | 4 | def __init__(self, username, password=""): 5 | self.username = username 6 | self._store_password(password) 7 | 8 | def welcome_user(self): 9 | print(f"Welcome to the site, {self.username}!") 10 | 11 | def close_account(self): 12 | print(f"Closed account for {self.username}.") 13 | 14 | def _store_password(self, password): 15 | print(f"Stored password for {self.username}.") 16 | 17 | 18 | class FreeAccount(Account): 19 | 20 | def welcome_user(self): 21 | Account.welcome_user(self) 22 | print("You'll have limited access on a free account.") 23 | 24 | 25 | if __name__ == "__main__": 26 | account = FreeAccount("eric") 27 | account.welcome_user() -------------------------------------------------------------------------------- /mp15_lists_arguments/process_requests_protected.py: -------------------------------------------------------------------------------- 1 | def validate_requests(raw_requests, valid_requests): 2 | """Validate a sequence of requests.""" 3 | while raw_requests: 4 | request = raw_requests.pop(0) 5 | if "bad" not in request: 6 | valid_requests.append(request) 7 | 8 | # Make a list of raw requests, and a list to hold valid requests. 9 | my_raw_requests = [ 10 | 'request_0', 'request_1_bad', 'request_2', 11 | 'request_3_bad', 'request_4_bad', 'request_5', 12 | 'request_6', 'request_7_bad', 'request_8', 13 | 'request_9_bad', 'request_10', 'request_11_bad' 14 | ] 15 | my_valid_requests = [] 16 | 17 | # Validate requests, and see what has changed. 18 | validate_requests(my_raw_requests[:], my_valid_requests) 19 | 20 | print(f"My raw requests: {my_raw_requests}") 21 | print(f"My valid requests: {my_valid_requests}") -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/cli_5.py: -------------------------------------------------------------------------------- 1 | """Process the CLI for add_border.py.""" 2 | 3 | import sys 4 | from pathlib import Path 5 | 6 | def process_cli_args(options): 7 | """Process all CLI arguments.""" 8 | # Get the filename. 9 | try: 10 | path = Path(sys.argv[1]) 11 | except IndexError: 12 | print("You must provide a target image.") 13 | sys.exit() 14 | 15 | # Make sure the file exists. 16 | if not path.exists(): 17 | print(f"{path} does not seem to exist.") 18 | sys.exit() 19 | 20 | # --- Get optional CLI args. --- 21 | if len(sys.argv) >= 3: 22 | options['border_width'] = int(sys.argv[2]) 23 | if len(sys.argv) >= 4: 24 | options['padding'] = int(sys.argv[3]) 25 | if len(sys.argv) >= 5: 26 | options['border_color'] = sys.argv[4] 27 | 28 | return path -------------------------------------------------------------------------------- /mp26_grounding_part_4/image_processing.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from PIL import Image, ImageOps, UnidentifiedImageError 3 | from cli_args import ImageBorderArgs 4 | 5 | def add_border_to_image(args: ImageBorderArgs): 6 | try: 7 | img = Image.open(args.path) 8 | except FileNotFoundError: 9 | print(f"{args.path} does not seem to exist.") 10 | sys.exit() 11 | except UnidentifiedImageError: 12 | print(f"{args.path} does not seem to be an image file.") 13 | sys.exit() 14 | 15 | new_img = ImageOps.expand(img, border=args.padding, fill="white") 16 | new_img = ImageOps.expand(new_img, border=args.border_width, 17 | fill=args.border_color) 18 | 19 | new_path = (args.path.parent / 20 | f"{args.path.stem}_bordered{args.path.suffix}") 21 | new_img.save(new_path) 22 | 23 | return new_path -------------------------------------------------------------------------------- /mp3_lists_closer_look/list_memory_visual.py: -------------------------------------------------------------------------------- 1 | # list_memory_visual.py 2 | 3 | import sys 4 | from random import randint 5 | 6 | import matplotlib.pyplot as plt 7 | 8 | # Build a list of random numbers, to simulate rolling a die. 9 | rolls = [] 10 | sizes = [] 11 | for x in range(100): 12 | roll = randint(1,6) 13 | rolls.append(roll) 14 | 15 | # Record the size of the list on each pass through the loop. 16 | list_size = sys.getsizeof(rolls) 17 | sizes.append(list_size) 18 | 19 | # Plot the size of the list vs the number of items. 20 | plt.style.use("seaborn") 21 | fig, ax = plt.subplots() 22 | 23 | x_values = list(range(1, 101)) 24 | ax.plot(x_values, sizes) 25 | 26 | ax.set_title("Size of list vs number of items in list", fontsize=24) 27 | ax.set_xlabel("Number of items", fontsize=14) 28 | ax.set_ylabel("Size of list (bytes)", fontsize=14) 29 | 30 | plt.show() -------------------------------------------------------------------------------- /oop_18/partial_versions/library_models_1_get_status.py: -------------------------------------------------------------------------------- 1 | class Resource: 2 | def __init__(self, resource_type): 3 | self.resource_type = resource_type 4 | self.current_borrower = None 5 | 6 | def lend(self, patron): 7 | self.current_borrower = patron 8 | 9 | def return_resource(self): 10 | self.current_borrower = None 11 | 12 | def get_status(self): 13 | if self.current_borrower: 14 | return "on loan" 15 | else: 16 | return "available" 17 | 18 | class Book(Resource): 19 | def __init__(self, title="", author=""): 20 | self.title = title 21 | self.author = author 22 | super().__init__(resource_type="book") 23 | 24 | def get_info(self): 25 | return f"{self.title}, by {self.author}" 26 | 27 | class Patron: 28 | def __init__(self, name): 29 | self.name = name -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/image_processing_3.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from PIL import Image, ImageOps, UnidentifiedImageError 3 | from cli_args import ImageBorderArgs 4 | 5 | def add_border_to_image(args: ImageBorderArgs): 6 | try: 7 | img = Image.open(args.path) 8 | except FileNotFoundError: 9 | print(f"{args.path} does not seem to exist.") 10 | sys.exit() 11 | except UnidentifiedImageError: 12 | print(f"{args.path} does not seem to be an image file.") 13 | sys.exit() 14 | 15 | new_img = ImageOps.expand(img, border=args.padding, fill="white") 16 | new_img = ImageOps.expand(new_img, border=args.border_width, 17 | fill=args.border_color) 18 | 19 | new_path = (args.path.parent / 20 | f"{args.path.stem}_bordered{args.path.suffix}") 21 | new_img.save(new_path) 22 | 23 | return new_path -------------------------------------------------------------------------------- /mp52_oop11_inheritance/account_3_print_super.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | """Model a user account on a site or app.""" 3 | 4 | def __init__(self, username, password=""): 5 | self.username = username 6 | self._store_password(password) 7 | 8 | def welcome_user(self): 9 | print(f"Welcome to the site, {self.username}!") 10 | 11 | def close_account(self): 12 | print(f"Closed account for {self.username}.") 13 | 14 | def _store_password(self, password): 15 | print(f"Stored password for {self.username}.") 16 | 17 | 18 | class FreeAccount(Account): 19 | 20 | def welcome_user(self): 21 | super().welcome_user() 22 | print("You'll have limited access on a free account.") 23 | print(super) 24 | print(super()) 25 | 26 | 27 | if __name__ == "__main__": 28 | account = FreeAccount("eric") 29 | account.welcome_user() -------------------------------------------------------------------------------- /mp29_settings/game.py: -------------------------------------------------------------------------------- 1 | from alien import Alien 2 | 3 | class Game: 4 | 5 | def __init__(self): 6 | self.settings = { 7 | 'alien_speed': 5, 8 | 'alien_direction': 1 9 | } 10 | 11 | self.alien = Alien(self) 12 | 13 | def show_settings(self): 14 | print("\nIn Game:") 15 | print(f" alien speed: {self.settings['alien_speed']}") 16 | print(f" alien direction: {self.settings['alien_direction']}") 17 | 18 | def increase_speed(self): 19 | self.settings['alien_speed'] += 1 20 | 21 | def change_direction(self): 22 | self.settings['alien_direction'] *= -1 23 | 24 | if __name__ == '__main__': 25 | game = Game() 26 | game.show_settings() 27 | game.alien.show_settings() 28 | 29 | game.increase_speed() 30 | game.change_direction() 31 | 32 | game.show_settings() 33 | game.alien.show_settings() 34 | -------------------------------------------------------------------------------- /mp150_debugging_9/demo_cards.py: -------------------------------------------------------------------------------- 1 | from card_models import Card, Hand, Deck 2 | 3 | cards = [ 4 | Card("A", "spades"), 5 | Card("A", "clubs"), 6 | Card("10", "spades"), 7 | Card("7", "diamonds"), 8 | Card("K", "clubs"), 9 | ] 10 | 11 | print("A simple hand:") 12 | hand = Hand(cards) 13 | hand.show() 14 | 15 | print("\nOrganized hand:") 16 | hand.organize() 17 | hand.show() 18 | 19 | print("\nA fresh deck:") 20 | deck = Deck() 21 | deck.show() 22 | 23 | print("\nA shuffled deck:") 24 | deck.shuffle() 25 | deck.show() 26 | 27 | print("\nDraw a single card:") 28 | card = deck.draw() 29 | print(card) 30 | 31 | print("\nDraw five cards to make a hand:") 32 | cards = deck.draw(5) 33 | hand = Hand(cards) 34 | hand.organize() 35 | hand.show() 36 | 37 | print("\nDealing two hands of seven cards:") 38 | hands = deck.deal(num_hands=2, num_cards=7) 39 | for hand in hands: 40 | hand.organize() 41 | hand.show() -------------------------------------------------------------------------------- /mp154_debugging_11/demo_cards.py: -------------------------------------------------------------------------------- 1 | from card_models import Card, Hand, Deck 2 | 3 | cards = [ 4 | Card("A", "spades"), 5 | Card("A", "clubs"), 6 | Card("10", "spades"), 7 | Card("7", "diamonds"), 8 | Card("K", "clubs"), 9 | ] 10 | 11 | print("A simple hand:") 12 | hand = Hand(cards) 13 | hand.show() 14 | 15 | print("\nOrganized hand:") 16 | hand.organize() 17 | hand.show() 18 | 19 | print("\nA fresh deck:") 20 | deck = Deck() 21 | deck.show() 22 | 23 | print("\nA shuffled deck:") 24 | deck.shuffle() 25 | deck.show() 26 | 27 | print("\nDraw a single card:") 28 | card = deck.draw() 29 | print(card) 30 | 31 | print("\nDraw five cards to make a hand:") 32 | cards = deck.draw(5) 33 | hand = Hand(cards) 34 | hand.organize() 35 | hand.show() 36 | 37 | print("\nDealing two hands of seven cards:") 38 | hands = deck.deal(num_hands=2, num_cards=7) 39 | for hand in hands: 40 | hand.organize() 41 | hand.show() -------------------------------------------------------------------------------- /mp156_debugging_13/demo_cards.py: -------------------------------------------------------------------------------- 1 | from card_models import Card, Hand, Deck 2 | 3 | cards = [ 4 | Card("A", "spades"), 5 | Card("A", "clubs"), 6 | Card("10", "spades"), 7 | Card("7", "diamonds"), 8 | Card("K", "clubs"), 9 | ] 10 | 11 | print("A simple hand:") 12 | hand = Hand(cards) 13 | hand.show() 14 | 15 | print("\nOrganized hand:") 16 | hand.organize() 17 | hand.show() 18 | 19 | print("\nA fresh deck:") 20 | deck = Deck() 21 | deck.show() 22 | 23 | print("\nA shuffled deck:") 24 | deck.shuffle() 25 | deck.show() 26 | 27 | print("\nDraw a single card:") 28 | card = deck.draw() 29 | print(card) 30 | 31 | print("\nDraw five cards to make a hand:") 32 | cards = deck.draw(5) 33 | hand = Hand(cards) 34 | hand.organize() 35 | hand.show() 36 | 37 | print("\nDealing two hands of seven cards:") 38 | hands = deck.deal(num_hands=2, num_cards=7) 39 | for hand in hands: 40 | hand.organize() 41 | hand.show() -------------------------------------------------------------------------------- /mp123_mortgages/mortgage_analysis_0.py: -------------------------------------------------------------------------------- 1 | """Analyze a mortgage loan.""" 2 | 3 | purchase_price = 500_000 4 | interest_rate = 0.075 5 | loan_term = 360 6 | 7 | # Find a monthly payment that pays off the loan. 8 | monthly_payment = 1.00 9 | principal = purchase_price 10 | 11 | while True: 12 | # Run the life of the loan with the current payment. 13 | for payment_num in range(loan_term): 14 | interest = (interest_rate/12) * principal 15 | towards_principal = monthly_payment - interest 16 | principal -= towards_principal 17 | 18 | # Summarize results. 19 | print(f"Tried {monthly_payment:,.2f}") 20 | print(f" Remaining principal: {principal:,.2f}") 21 | 22 | # Exit loop if loan is paid off. 23 | if principal <= 0: 24 | break 25 | 26 | # Loan was not paid off. Increase monthly payment, and reset loan. 27 | monthly_payment += 1.00 28 | principal = purchase_price 29 | -------------------------------------------------------------------------------- /mp151_debugging_10/go_fish_fixed/demo_cards.py: -------------------------------------------------------------------------------- 1 | from card_models import Card, Hand, Deck 2 | 3 | cards = [ 4 | Card("A", "spades"), 5 | Card("A", "clubs"), 6 | Card("10", "spades"), 7 | Card("7", "diamonds"), 8 | Card("K", "clubs"), 9 | ] 10 | 11 | print("A simple hand:") 12 | hand = Hand(cards) 13 | hand.show() 14 | 15 | print("\nOrganized hand:") 16 | hand.organize() 17 | hand.show() 18 | 19 | print("\nA fresh deck:") 20 | deck = Deck() 21 | deck.show() 22 | 23 | print("\nA shuffled deck:") 24 | deck.shuffle() 25 | deck.show() 26 | 27 | print("\nDraw a single card:") 28 | card = deck.draw() 29 | print(card) 30 | 31 | print("\nDraw five cards to make a hand:") 32 | cards = deck.draw(5) 33 | hand = Hand(cards) 34 | hand.organize() 35 | hand.show() 36 | 37 | print("\nDealing two hands of seven cards:") 38 | hands = deck.deal(num_hands=2, num_cards=7) 39 | for hand in hands: 40 | hand.organize() 41 | hand.show() -------------------------------------------------------------------------------- /mp155_debugging_12/go_fish_bugfix/demo_cards.py: -------------------------------------------------------------------------------- 1 | from card_models import Card, Hand, Deck 2 | 3 | cards = [ 4 | Card("A", "spades"), 5 | Card("A", "clubs"), 6 | Card("10", "spades"), 7 | Card("7", "diamonds"), 8 | Card("K", "clubs"), 9 | ] 10 | 11 | print("A simple hand:") 12 | hand = Hand(cards) 13 | hand.show() 14 | 15 | print("\nOrganized hand:") 16 | hand.organize() 17 | hand.show() 18 | 19 | print("\nA fresh deck:") 20 | deck = Deck() 21 | deck.show() 22 | 23 | print("\nA shuffled deck:") 24 | deck.shuffle() 25 | deck.show() 26 | 27 | print("\nDraw a single card:") 28 | card = deck.draw() 29 | print(card) 30 | 31 | print("\nDraw five cards to make a hand:") 32 | cards = deck.draw(5) 33 | hand = Hand(cards) 34 | hand.organize() 35 | hand.show() 36 | 37 | print("\nDealing two hands of seven cards:") 38 | hands = deck.deal(num_hands=2, num_cards=7) 39 | for hand in hands: 40 | hand.organize() 41 | hand.show() -------------------------------------------------------------------------------- /mp155_debugging_12/go_fish_seeded/demo_cards.py: -------------------------------------------------------------------------------- 1 | from card_models import Card, Hand, Deck 2 | 3 | cards = [ 4 | Card("A", "spades"), 5 | Card("A", "clubs"), 6 | Card("10", "spades"), 7 | Card("7", "diamonds"), 8 | Card("K", "clubs"), 9 | ] 10 | 11 | print("A simple hand:") 12 | hand = Hand(cards) 13 | hand.show() 14 | 15 | print("\nOrganized hand:") 16 | hand.organize() 17 | hand.show() 18 | 19 | print("\nA fresh deck:") 20 | deck = Deck() 21 | deck.show() 22 | 23 | print("\nA shuffled deck:") 24 | deck.shuffle() 25 | deck.show() 26 | 27 | print("\nDraw a single card:") 28 | card = deck.draw() 29 | print(card) 30 | 31 | print("\nDraw five cards to make a hand:") 32 | cards = deck.draw(5) 33 | hand = Hand(cards) 34 | hand.organize() 35 | hand.show() 36 | 37 | print("\nDealing two hands of seven cards:") 38 | hands = deck.deal(num_hands=2, num_cards=7) 39 | for hand in hands: 40 | hand.organize() 41 | hand.show() -------------------------------------------------------------------------------- /mp29_settings/partial_programs/game_3.py: -------------------------------------------------------------------------------- 1 | from alien_3 import Alien 2 | 3 | class Game: 4 | 5 | def __init__(self): 6 | self.settings = { 7 | 'alien_speed': 5, 8 | 'alien_direction': 1 9 | } 10 | 11 | self.alien = Alien(self) 12 | 13 | def show_settings(self): 14 | print("\nIn Game:") 15 | print(f" alien speed: {self.settings['alien_speed']}") 16 | print(f" alien direction: {self.settings['alien_direction']}") 17 | 18 | def increase_speed(self): 19 | self.settings['alien_speed'] += 1 20 | 21 | def change_direction(self): 22 | self.settings['alien_direction'] *= -1 23 | 24 | if __name__ == '__main__': 25 | game = Game() 26 | game.show_settings() 27 | game.alien.show_settings() 28 | 29 | game.increase_speed() 30 | game.change_direction() 31 | 32 | game.show_settings() 33 | game.alien.show_settings() 34 | -------------------------------------------------------------------------------- /mp151_debugging_10/cards_with_error/demo_cards.py: -------------------------------------------------------------------------------- 1 | from card_models import Card, Hand, Deck 2 | 3 | cards = [ 4 | Card("A", "spades"), 5 | Card("A", "clubs"), 6 | Card("10", "spades"), 7 | Card("7", "diamonds"), 8 | Card("K", "clubs"), 9 | ] 10 | 11 | print("A simple hand:") 12 | hand = Hand(cards) 13 | hand.show() 14 | 15 | print("\nOrganized hand:") 16 | hand.organize() 17 | hand.show() 18 | 19 | print("\nA fresh deck:") 20 | deck = Deck() 21 | deck.show() 22 | 23 | print("\nA shuffled deck:") 24 | deck.shuffle() 25 | deck.show() 26 | 27 | print("\nDraw a single card:") 28 | card = deck.draw() 29 | print(card) 30 | 31 | print("\nDraw five cards to make a hand:") 32 | cards = deck.draw(5) 33 | hand = Hand(cards) 34 | hand.organize() 35 | hand.show() 36 | 37 | print("\nDealing two hands of seven cards:") 38 | hands = deck.deal(num_hands=2, num_cards=7) 39 | for hand in hands: 40 | hand.organize() 41 | hand.show() -------------------------------------------------------------------------------- /mp151_debugging_10/go_fish_with_error/demo_cards.py: -------------------------------------------------------------------------------- 1 | from card_models import Card, Hand, Deck 2 | 3 | cards = [ 4 | Card("A", "spades"), 5 | Card("A", "clubs"), 6 | Card("10", "spades"), 7 | Card("7", "diamonds"), 8 | Card("K", "clubs"), 9 | ] 10 | 11 | print("A simple hand:") 12 | hand = Hand(cards) 13 | hand.show() 14 | 15 | print("\nOrganized hand:") 16 | hand.organize() 17 | hand.show() 18 | 19 | print("\nA fresh deck:") 20 | deck = Deck() 21 | deck.show() 22 | 23 | print("\nA shuffled deck:") 24 | deck.shuffle() 25 | deck.show() 26 | 27 | print("\nDraw a single card:") 28 | card = deck.draw() 29 | print(card) 30 | 31 | print("\nDraw five cards to make a hand:") 32 | cards = deck.draw(5) 33 | hand = Hand(cards) 34 | hand.organize() 35 | hand.show() 36 | 37 | print("\nDealing two hands of seven cards:") 38 | hands = deck.deal(num_hands=2, num_cards=7) 39 | for hand in hands: 40 | hand.organize() 41 | hand.show() -------------------------------------------------------------------------------- /mp7_tracking_down_a_bug/die_visual.py: -------------------------------------------------------------------------------- 1 | from plotly.graph_objs import Bar, Layout 2 | from plotly import offline 3 | 4 | from die import Die 5 | 6 | # Create a D6. 7 | die = Die() 8 | 9 | # Make some rolls, and store results in a list. 10 | results = [] 11 | for roll_num in range(1000): 12 | result = die.roll() 13 | results.append(result) 14 | 15 | # Analyze the results. 16 | frequencies = [] 17 | for value in range(1, die.num_sides+1): 18 | frequency = results.count(value) 19 | frequencies.append(frequency) 20 | 21 | # Visualize the results. 22 | x_values = list(range(1, die.num_sides+1)) 23 | data = [Bar(x=x_values, y=frequencies)] 24 | 25 | x_axis_config = {'title': 'Result'} 26 | y_axis_config = {'title': 'Frequency of Result'} 27 | my_layout = Layout(title='Results of rolling one D6 1000 times', 28 | xaxis=x_axis_config, yaxis=y_axis_config) 29 | offline.plot({'data': data, 'layout': my_layout}, filename='d6.html') -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/poker_hands_check_ace_high_4_using_all.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | 3 | all_cards = (2, 3, 4, 5, 6, 7, 8, 9, 10, 'j', 'q', 'k', 'a') 4 | 5 | def get_hand(hand_size=5): 6 | """Return a hand of cards.""" 7 | return tuple(choice(all_cards) for _ in range(hand_size)) 8 | 9 | def check_ace_high_straight(hand): 10 | """Check if hand is an ace-high straight.""" 11 | return all(card in (10, 'j', 'q', 'k', 'a') for card in hand) 12 | 13 | num_hands = 5_000_000 14 | hands = [get_hand() for _ in range(num_hands)] 15 | 16 | print(f"\nGenerated {len(hands):,} hands.") 17 | print(hands[0]) 18 | 19 | # Check for any ace-high straights. 20 | winners = [] 21 | for hand in hands: 22 | if check_ace_high_straight(hand): 23 | winners.append(hand) 24 | 25 | if winners: 26 | print(f"\nFound {len(winners)} winning hands.") 27 | print(winners[0]) 28 | else: 29 | print("\nNo winning hands found.") -------------------------------------------------------------------------------- /mp42_oop5_class_methods/trees_5.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | num_trees = 0 4 | 5 | @classmethod 6 | def count_trees(cls): 7 | msg = f"We have {cls.num_trees} trees in the collection." 8 | print(msg) 9 | 10 | def __init__(self, name, description=""): 11 | self.name = name 12 | self.description = description 13 | 14 | BonsaiTree.num_trees += 1 15 | 16 | def describe_tree(self): 17 | msg = f"{self.name}: {self.description}" 18 | print(msg) 19 | 20 | trees = [] 21 | 22 | tree = BonsaiTree("Winged Elm") 23 | tree.description = "tall, solid trunk" 24 | trees.append(tree) 25 | 26 | tree = BonsaiTree("El Arbol Murcielago") 27 | tree.description = "short, open trunk" 28 | trees.append(tree) 29 | 30 | tree = BonsaiTree("Mt. Mitchell") 31 | tree.description = "small mountain forest" 32 | trees.append(tree) 33 | 34 | for tree in trees: 35 | tree.describe_tree() 36 | 37 | tree.count_trees() -------------------------------------------------------------------------------- /mp23_grounding_part_2/partial_programs/add_border_5.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | import sys 4 | from pathlib import Path 5 | from PIL import Image, ImageOps, UnidentifiedImageError 6 | 7 | # Get the filename. 8 | try: 9 | path = Path(sys.argv[1]) 10 | except IndexError: 11 | print("You must provide a target image.") 12 | sys.exit() 13 | 14 | # Load the image. 15 | try: 16 | img = Image.open(path) 17 | except FileNotFoundError: 18 | print(f"{path} does not seem to exist.") 19 | sys.exit() 20 | except UnidentifiedImageError: 21 | print(f"{path} does not seem to be an image file.") 22 | sys.exit() 23 | 24 | # Set the border width and color. 25 | border_width = 2 26 | border_color = "darkgray" 27 | 28 | # Add the border. 29 | new_img = ImageOps.expand(img, border=border_width, 30 | fill=border_color) 31 | 32 | # Save new image. 33 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 34 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp42_oop5_class_methods/trees_4.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | num_trees = 0 4 | 5 | @classmethod 6 | def count_trees(cls): 7 | msg = f"We have {BonsaiTree.num_trees} trees in the collection." 8 | print(msg) 9 | 10 | def __init__(self, name, description=""): 11 | self.name = name 12 | self.description = description 13 | 14 | BonsaiTree.num_trees += 1 15 | 16 | def describe_tree(self): 17 | msg = f"{self.name}: {self.description}" 18 | print(msg) 19 | 20 | trees = [] 21 | 22 | tree = BonsaiTree("Winged Elm") 23 | tree.description = "tall, solid trunk" 24 | trees.append(tree) 25 | 26 | tree = BonsaiTree("El Arbol Murcielago") 27 | tree.description = "short, open trunk" 28 | trees.append(tree) 29 | 30 | tree = BonsaiTree("Mt. Mitchell") 31 | tree.description = "small mountain forest" 32 | trees.append(tree) 33 | 34 | for tree in trees: 35 | tree.describe_tree() 36 | 37 | BonsaiTree.count_trees() -------------------------------------------------------------------------------- /mp42_oop5_class_methods/trees_3_tracking_instances.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | num_trees = 0 4 | 5 | @classmethod 6 | def count_trees(cls): 7 | msg = f"We have {cls.num_trees} trees in the collection." 8 | print(msg) 9 | 10 | def __init__(self, name, description=""): 11 | self.name = name 12 | self.description = description 13 | 14 | BonsaiTree.num_trees += 1 15 | 16 | def describe_tree(self): 17 | msg = f"{self.name}: {self.description}" 18 | print(msg) 19 | 20 | trees = [] 21 | 22 | tree = BonsaiTree("Winged Elm") 23 | tree.description = "tall, solid trunk" 24 | trees.append(tree) 25 | 26 | tree = BonsaiTree("El Arbol Murcielago") 27 | tree.description = "short, open trunk" 28 | trees.append(tree) 29 | 30 | tree = BonsaiTree("Mt. Mitchell") 31 | tree.description = "small mountain forest" 32 | trees.append(tree) 33 | 34 | for tree in trees: 35 | tree.describe_tree() 36 | 37 | BonsaiTree.count_trees() -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/poker_hands_check_ace_high.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | 3 | all_cards = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'j', 'q', 'k', 'a'] 4 | 5 | def get_hand(hand_size=5): 6 | """Return a hand of cards.""" 7 | return [choice(all_cards) for _ in range(hand_size)] 8 | 9 | def check_ace_high_straight(hand): 10 | """Check if hand is an ace-high straight.""" 11 | for card in [10, 'j', 'q', 'k', 'a']: 12 | if card not in hand: 13 | return False 14 | return True 15 | 16 | num_hands = 5_000_000 17 | hands = [get_hand() for _ in range(num_hands)] 18 | 19 | print(f"\nGenerated {len(hands):,} hands.") 20 | print(hands[0]) 21 | 22 | # Check for any ace-high straights. 23 | winners = [] 24 | for hand in hands: 25 | if check_ace_high_straight(hand): 26 | winners.append(hand) 27 | 28 | if winners: 29 | print(f"\nFound {len(winners)} winning hands.") 30 | print(winners[0]) 31 | else: 32 | print("\nNo winning hands found.") -------------------------------------------------------------------------------- /mp42_oop5_class_methods/trees_7.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | num_trees = 0 4 | 5 | @classmethod 6 | def count_trees(cls): 7 | msg = f"We have {cls.num_trees} trees in the collection." 8 | print(msg) 9 | 10 | def __init__(self, name, description=""): 11 | self.name = name 12 | self.description = description 13 | 14 | BonsaiTree.num_trees += 1 15 | 16 | def describe_tree(self): 17 | msg = f"{self.name}: {self.description}" 18 | msg += f"\nThis is one of {self.num_trees} trees." 19 | print(msg) 20 | 21 | trees = [] 22 | 23 | tree = BonsaiTree("Winged Elm") 24 | tree.description = "tall, solid trunk" 25 | trees.append(tree) 26 | 27 | tree = BonsaiTree("El Arbol Murcielago") 28 | tree.description = "short, open trunk" 29 | trees.append(tree) 30 | 31 | tree = BonsaiTree("Mt. Mitchell") 32 | tree.description = "small mountain forest" 33 | trees.append(tree) 34 | 35 | for tree in trees: 36 | tree.describe_tree() 37 | -------------------------------------------------------------------------------- /mp42_oop5_class_methods/trees_6.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | num_trees = 0 4 | 5 | @classmethod 6 | def count_trees(cls): 7 | msg = f"We have {cls.num_trees} trees in the collection." 8 | print(msg) 9 | 10 | def __init__(self, name, description=""): 11 | self.name = name 12 | self.description = description 13 | 14 | BonsaiTree.num_trees += 1 15 | 16 | def describe_tree(self): 17 | msg = f"{self.name}: {self.description}" 18 | msg += f"\n This is one of {BonsaiTree.num_trees} trees." 19 | print(msg) 20 | 21 | trees = [] 22 | 23 | tree = BonsaiTree("Winged Elm") 24 | tree.description = "tall, solid trunk" 25 | trees.append(tree) 26 | 27 | tree = BonsaiTree("El Arbol Murcielago") 28 | tree.description = "short, open trunk" 29 | trees.append(tree) 30 | 31 | tree = BonsaiTree("Mt. Mitchell") 32 | tree.description = "small mountain forest" 33 | trees.append(tree) 34 | 35 | for tree in trees: 36 | tree.describe_tree() 37 | -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/poker_hands_check_ace_high_2_all_cards_tuple.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | 3 | all_cards = (2, 3, 4, 5, 6, 7, 8, 9, 10, 'j', 'q', 'k', 'a') 4 | 5 | def get_hand(hand_size=5): 6 | """Return a hand of cards.""" 7 | return [choice(all_cards) for _ in range(hand_size)] 8 | 9 | def check_ace_high_straight(hand): 10 | """Check if hand is an ace-high straight.""" 11 | for card in [10, 'j', 'q', 'k', 'a']: 12 | if card not in hand: 13 | return False 14 | return True 15 | 16 | num_hands = 5_000_000 17 | hands = [get_hand() for _ in range(num_hands)] 18 | 19 | print(f"\nGenerated {len(hands):,} hands.") 20 | print(hands[0]) 21 | 22 | # Check for any ace-high straights. 23 | winners = [] 24 | for hand in hands: 25 | if check_ace_high_straight(hand): 26 | winners.append(hand) 27 | 28 | if winners: 29 | print(f"\nFound {len(winners)} winning hands.") 30 | print(winners[0]) 31 | else: 32 | print("\nNo winning hands found.") -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/poker_hands_check_ace_high_3_hand_as_tuple.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | 3 | all_cards = (2, 3, 4, 5, 6, 7, 8, 9, 10, 'j', 'q', 'k', 'a') 4 | 5 | def get_hand(hand_size=5): 6 | """Return a hand of cards.""" 7 | return tuple(choice(all_cards) for _ in range(hand_size)) 8 | 9 | def check_ace_high_straight(hand): 10 | """Check if hand is an ace-high straight.""" 11 | for card in [10, 'j', 'q', 'k', 'a']: 12 | if card not in hand: 13 | return False 14 | return True 15 | 16 | num_hands = 5_000_000 17 | hands = [get_hand() for _ in range(num_hands)] 18 | 19 | print(f"\nGenerated {len(hands):,} hands.") 20 | print(hands[0]) 21 | 22 | # Check for any ace-high straights. 23 | winners = [] 24 | for hand in hands: 25 | if check_ace_high_straight(hand): 26 | winners.append(hand) 27 | 28 | if winners: 29 | print(f"\nFound {len(winners)} winning hands.") 30 | print(winners[0]) 31 | else: 32 | print("\nNo winning hands found.") -------------------------------------------------------------------------------- /mp124_real_estate_images/image_archiver_2_click_first_image.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import httpx 4 | 5 | from selenium import webdriver 6 | from selenium.webdriver.chrome.service import Service 7 | from webdriver_manager.chrome import ChromeDriverManager 8 | from selenium.webdriver.common.by import By 9 | from selenium.webdriver.support.ui import WebDriverWait 10 | from selenium.webdriver.support import expected_conditions as EC 11 | 12 | 13 | url = "https://www.zillow.com/homedetails/" 14 | url += "432-Park-Ave-PENTHOUSE-New-York-NY-10022/2069500049_zpid/" 15 | 16 | driver = webdriver.Chrome( 17 | service=Service(ChromeDriverManager().install())) 18 | 19 | # Open main property page. 20 | driver.get(url) 21 | 22 | # Click on first image in listing. 23 | button = WebDriverWait(driver, 10).until( 24 | EC.element_to_be_clickable(( 25 | By.CSS_SELECTOR, 26 | "button[aria-label='view larger view of the 1 photo of this home']" 27 | )) 28 | ) 29 | button.click() 30 | 31 | breakpoint() 32 | -------------------------------------------------------------------------------- /mp42_oop5_class_methods/trees_8_doesnt_work.py: -------------------------------------------------------------------------------- 1 | class BonsaiTree: 2 | 3 | num_trees = 0 4 | 5 | @classmethod 6 | def count_trees(cls): 7 | msg = f"We have {cls.num_trees} trees in the collection." 8 | print(msg) 9 | 10 | def __init__(self, name, description=""): 11 | self.name = name 12 | self.description = description 13 | 14 | self.num_trees += 1 15 | 16 | def describe_tree(self): 17 | msg = f"{self.name}: {self.description}" 18 | msg += f"\nThis is one of {self.num_trees} trees." 19 | print(msg) 20 | 21 | trees = [] 22 | 23 | tree = BonsaiTree("Winged Elm") 24 | tree.description = "tall, solid trunk" 25 | trees.append(tree) 26 | 27 | tree = BonsaiTree("El Arbol Murcielago") 28 | tree.description = "short, open trunk" 29 | trees.append(tree) 30 | 31 | tree = BonsaiTree("Mt. Mitchell") 32 | tree.description = "small mountain forest" 33 | trees.append(tree) 34 | 35 | for tree in trees: 36 | tree.describe_tree() 37 | 38 | BonsaiTree.count_trees() 39 | -------------------------------------------------------------------------------- /oop_18/climbing_library.py: -------------------------------------------------------------------------------- 1 | from library_models import Library, Book, Magazine, Patron 2 | 3 | # Create a library. 4 | library = Library(name="The Climber's Library") 5 | 6 | # Create some books. 7 | book = Book( 8 | title="Freedom of the Hills", 9 | author="The Mountaineers", 10 | ) 11 | library.resources.append(book) 12 | 13 | book = Book( 14 | title="Learning to Fly", 15 | author="Steph Davis", 16 | ) 17 | library.resources.append(book) 18 | 19 | # Show all books. 20 | library.show_books() 21 | 22 | # Lend a book. 23 | birdie = Patron("Birdie") 24 | freedom_hills = library.get_books()[0] 25 | freedom_hills.lend(birdie) 26 | 27 | # Show all books. 28 | library.show_books() 29 | 30 | # Create some magazines. 31 | for issue_num in range(70, 84): 32 | magazine = Magazine(title="Alpinist", issue=issue_num) 33 | library.resources.append(magazine) 34 | 35 | # Loan the latest issue. 36 | current_issue = library.get_magazines()[-1] 37 | current_issue.lend(birdie) 38 | 39 | # Show magazines. 40 | library.show_magazines() -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/add_border_5.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | from PIL import Image, ImageOps, UnidentifiedImageError 4 | 5 | from cli import process_cli_args 6 | 7 | 8 | # Set default options. 9 | options = { 10 | 'border_width': 2, 11 | 'padding': 0, 12 | 'border_color': 'lightgray' 13 | } 14 | path = process_cli_args(options) 15 | 16 | # Load the image. 17 | try: 18 | img = Image.open(path) 19 | except UnidentifiedImageError: 20 | print(f"{path} does not seem to be an image file.") 21 | sys.exit() 22 | 23 | # Add some padding before adding the border. 24 | # The padding is just a white border added before 25 | # the actual border. 26 | new_img = ImageOps.expand(img, border=options['padding'], 27 | fill="white") 28 | 29 | # Add the border. 30 | new_img = ImageOps.expand(new_img, 31 | border=options['border_width'], 32 | fill=options['border_color']) 33 | 34 | # Save new image. 35 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 36 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp24_grounding_part_3/image_functions.py: -------------------------------------------------------------------------------- 1 | """Functions to process the image.""" 2 | 3 | from PIL import Image, ImageOps, UnidentifiedImageError 4 | 5 | def load_image(path): 6 | """Load the image file.""" 7 | try: 8 | return Image.open(path) 9 | except UnidentifiedImageError: 10 | print(f"{path} does not seem to be an image file.") 11 | sys.exit() 12 | 13 | def process_image(img, options): 14 | """Modify the original image.""" 15 | 16 | # Add some padding before adding the border. 17 | # The padding is just a white border added before 18 | # the actual border. 19 | new_img = ImageOps.expand(img, border=options['padding'], 20 | fill="white") 21 | 22 | # Add the border. 23 | new_img = ImageOps.expand(new_img, 24 | border=options['border_width'], 25 | fill=options['border_color']) 26 | 27 | return new_img 28 | 29 | def save_image(path, new_img): 30 | """Save the new image.""" 31 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 32 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp26_grounding_part_4/cli_args.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import argparse 3 | from pathlib import Path 4 | from dataclasses import dataclass 5 | 6 | @dataclass 7 | class ImageBorderArgs: 8 | path: Path 9 | border_width: int 10 | padding: int 11 | border_color: str 12 | 13 | def parse_cli_args(): 14 | parser = argparse.ArgumentParser( 15 | description="Add a border to any image.") 16 | parser.add_argument("filename", type=Path, 17 | help="The target image.") 18 | parser.add_argument("border_width", type=int, 19 | nargs="?",default=2, 20 | help="The border width (default: 2).") 21 | parser.add_argument("--padding", type=int, default=0, 22 | help="The padding (default: 0).") 23 | parser.add_argument("--border-color", 24 | dest="border_color", default="lightgray", 25 | help="The border color (default: lightgray).") 26 | 27 | args = parser.parse_args() 28 | 29 | return ImageBorderArgs(args.filename, args.border_width, 30 | args.padding, args.border_color) -------------------------------------------------------------------------------- /oop_17/library.py: -------------------------------------------------------------------------------- 1 | class Book: 2 | def __init__(self, title="", author=""): 3 | self.title = title 4 | self.author = author 5 | 6 | def get_info(self): 7 | return f"{self.title}, by {self.author}" 8 | 9 | class Library: 10 | def __init__(self, name="", books=None): 11 | self.name = name 12 | 13 | if books is None: 14 | self.books = [] 15 | else: 16 | self.books = books 17 | 18 | def show_books(self): 19 | print(f"All books in {self.name}:") 20 | for book in self.books: 21 | info = book.get_info() 22 | print(f"- {info}") 23 | 24 | if __name__ == "__main__": 25 | library = Library(name="The Climber's Library") 26 | 27 | book = Book( 28 | title="Freedom of the Hills", 29 | author="The Mountaineers" 30 | ) 31 | library.books.append(book) 32 | 33 | book = Book( 34 | title = "Learning to Fly", 35 | author = "Steph Davis", 36 | ) 37 | library.books.append(book) 38 | 39 | library.show_books() -------------------------------------------------------------------------------- /mp23_grounding_part_2/partial_programs/add_border_6.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | import sys 4 | from pathlib import Path 5 | from PIL import Image, ImageOps, UnidentifiedImageError 6 | 7 | # Get the filename. 8 | try: 9 | path = Path(sys.argv[1]) 10 | except IndexError: 11 | print("You must provide a target image.") 12 | sys.exit() 13 | 14 | # --- Get optional CLI args. --- 15 | try: 16 | border_width = int(sys.argv[2]) 17 | except IndexError: 18 | border_width = 2 19 | 20 | # Load the image. 21 | try: 22 | img = Image.open(path) 23 | except FileNotFoundError: 24 | print(f"{path} does not seem to exist.") 25 | sys.exit() 26 | except UnidentifiedImageError: 27 | print(f"{path} does not seem to be an image file.") 28 | sys.exit() 29 | 30 | # Set the border width and color. 31 | border_color = "darkgray" 32 | 33 | # Add the border. 34 | new_img = ImageOps.expand(img, border=border_width, 35 | fill=border_color) 36 | 37 | # Save new image. 38 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 39 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/image_functions_9.py: -------------------------------------------------------------------------------- 1 | """Functions to process the image.""" 2 | 3 | from PIL import Image, ImageOps, UnidentifiedImageError 4 | 5 | def load_image(path): 6 | """Load the image file.""" 7 | try: 8 | return Image.open(path) 9 | except UnidentifiedImageError: 10 | print(f"{path} does not seem to be an image file.") 11 | sys.exit() 12 | 13 | def process_image(img, options): 14 | """Modify the original image.""" 15 | 16 | # Add some padding before adding the border. 17 | # The padding is just a white border added before 18 | # the actual border. 19 | new_img = ImageOps.expand(img, border=options['padding'], 20 | fill="white") 21 | 22 | # Add the border. 23 | new_img = ImageOps.expand(new_img, 24 | border=options['border_width'], 25 | fill=options['border_color']) 26 | 27 | return new_img 28 | 29 | def save_image(path, new_img): 30 | """Save the new image.""" 31 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 32 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp26_grounding_part_4/partial_programs/cli_args_4.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import argparse 3 | from pathlib import Path 4 | from dataclasses import dataclass 5 | 6 | @dataclass 7 | class ImageBorderArgs: 8 | path: Path 9 | border_width: int 10 | padding: int 11 | border_color: str 12 | 13 | def parse_cli_args(): 14 | parser = argparse.ArgumentParser( 15 | description="Add a border to any image.") 16 | parser.add_argument("filename", type=Path, 17 | help="The target image.") 18 | parser.add_argument("border_width", type=int, 19 | nargs="?",default=2, 20 | help="The border width (default: 2).") 21 | parser.add_argument("--padding", type=int, default=0, 22 | help="The padding (default: 0).") 23 | parser.add_argument("--border-color", 24 | dest="border_color", default="lightgray", 25 | help="The border color (default: lightgray).") 26 | 27 | args = parser.parse_args() 28 | 29 | return ImageBorderArgs(args.filename, args.border_width, 30 | args.padding, args.border_color) -------------------------------------------------------------------------------- /oop_19/office_hours_monitor_oop.py: -------------------------------------------------------------------------------- 1 | import os, sys, time 2 | import requests 3 | 4 | 5 | class OOMonitor: 6 | 7 | def __init__(self, url, target_string, num_attempts=90): 8 | self.url = url 9 | self.target_string = target_string 10 | self.num_attempts = num_attempts 11 | 12 | def start_monitoring(self): 13 | for attempt_num in range(self.num_attempts): 14 | r = requests.get(self.url) 15 | print(f"Attempt #{attempt_num}. Status: {r.status_code}") 16 | 17 | if target_string in r.text: 18 | cmd = f'open -a "Google Chrome" {url}' 19 | os.system(cmd) 20 | print(" Found a new post!") 21 | sys.exit() 22 | else: 23 | print(" No new post found. Waiting one minute...") 24 | time.sleep(60) 25 | 26 | if __name__ == '__main__': 27 | url = "https://on.substack.com/s/office-hours" 28 | target_string = " min ago<" 29 | target_string = "Oct 26" 30 | 31 | monitor = OOMonitor(url, target_string) 32 | monitor.start_monitoring() -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/cli_11.py: -------------------------------------------------------------------------------- 1 | """Process the CLI for add_border.py.""" 2 | 3 | import sys, argparse 4 | from pathlib import Path 5 | 6 | def process_cli_args(): 7 | """Process all CLI arguments.""" 8 | parser = argparse.ArgumentParser() 9 | 10 | # Define arguments. 11 | parser.add_argument('path', 12 | help="path to the image file") 13 | parser.add_argument('border_width', 14 | nargs='?', type=int, default=2, 15 | help="default: 2px") 16 | parser.add_argument('--padding', type=int, default=0, 17 | help="default: 0px") 18 | parser.add_argument('--border-color', type=str, 19 | default='lightgray', help="default: lightgray") 20 | 21 | # Process arguments. 22 | args = parser.parse_args() 23 | 24 | path = Path(args.path) 25 | if not path.exists(): 26 | print(f"{path} does not seem to exist.") 27 | sys.exit() 28 | 29 | options = { 30 | 'border_width': args.border_width, 31 | 'padding': args.padding, 32 | 'border_color': args.border_color, 33 | } 34 | 35 | return path, options -------------------------------------------------------------------------------- /mp53_oop12_abc/account_4_invisible.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | """Model a user account on a site or app.""" 3 | 4 | def __init__(self, username, password=""): 5 | self.username = username 6 | self._store_password(password) 7 | 8 | def welcome_user(self): 9 | print(f"Welcome to the site, {self.username}!") 10 | 11 | def _store_password(self, password): 12 | print(f"Stored password for {self.username}.") 13 | 14 | 15 | class FreeAccount(Account): 16 | 17 | def welcome_user(self): 18 | super().welcome_user() 19 | print("You'll have limited access on a free account.") 20 | 21 | 22 | class StandardAccount(Account): 23 | 24 | def welcome_user(self): 25 | super().welcome_user() 26 | print("You have access to all features on the site.") 27 | 28 | 29 | class PremiumAccount(Account): 30 | 31 | def welcome_user(self): 32 | super().welcome_user() 33 | print("Thank you for supporting us at this level!") 34 | 35 | 36 | if __name__ == "__main__": 37 | account = PremiumAccount("birdie") 38 | account.welcome_user() 39 | -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/add_border_6.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | from PIL import Image, ImageOps, UnidentifiedImageError 4 | 5 | from cli import process_cli_args 6 | 7 | 8 | def load_image(path): 9 | """Load the image file.""" 10 | try: 11 | return Image.open(path) 12 | except UnidentifiedImageError: 13 | print(f"{path} does not seem to be an image file.") 14 | sys.exit() 15 | 16 | # Set default options. 17 | options = { 18 | 'border_width': 2, 19 | 'padding': 0, 20 | 'border_color': 'lightgray' 21 | } 22 | path = process_cli_args(options) 23 | img = load_image(path) 24 | 25 | # Add some padding before adding the border. 26 | # The padding is just a white border added before 27 | # the actual border. 28 | new_img = ImageOps.expand(img, border=options['padding'], 29 | fill="white") 30 | 31 | # Add the border. 32 | new_img = ImageOps.expand(new_img, 33 | border=options['border_width'], 34 | fill=options['border_color']) 35 | 36 | # Save new image. 37 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 38 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp53_oop12_abc/account_3_not_well_behaved.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | """Model a user account on a site or app.""" 3 | 4 | def __init__(self, username, password=""): 5 | self.username = username 6 | self._store_password(password) 7 | 8 | def welcome_user(self): 9 | print(f"Welcome to the site, {self.username}!") 10 | 11 | def _store_password(self, password): 12 | print(f"Stored password for {self.username}.") 13 | 14 | 15 | class FreeAccount(Account): 16 | 17 | def welcome_user(self): 18 | super().welcome_user() 19 | print("You'll have limited access on a free account.") 20 | 21 | 22 | class StandardAccount(Account): 23 | 24 | def welcome_user(self): 25 | super().welcome_user() 26 | print("You have access to all features on the site.") 27 | 28 | 29 | class PremiumAccount(Account): 30 | 31 | def welcome_user(self): 32 | super().welcome_user() 33 | print("Thank you for supporting us at this level!") 34 | 35 | 36 | if __name__ == "__main__": 37 | account = PremiumAccount("birdie") 38 | account.welcome_user() 39 | account.close_account() -------------------------------------------------------------------------------- /mp120_lotteries/nc_powerball_2_30_plays.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | def get_ticket(ticket_size=5, max_value=69): 4 | """Get a ticket of ticket_size numbers. 5 | Numbers are picked from 1 through max_value). 6 | """ 7 | ticket = [] 8 | 9 | while len(ticket) < ticket_size: 10 | pulled_number = randint(1, max_value) 11 | 12 | # Don't reuse numbers. 13 | if pulled_number in ticket: 14 | continue 15 | 16 | ticket.append(pulled_number) 17 | 18 | ticket.sort() 19 | return ticket 20 | 21 | def check_ticket(ticket, winning_draw): 22 | """Find out how many numbers matched.""" 23 | return len( 24 | [num for num in ticket if num in winning_draw]) 25 | 26 | 27 | bd_ticket = get_ticket(5, 31) 28 | print(f"Birthday ticket: {bd_ticket}\n") 29 | 30 | # Simulate a number of drawings. 31 | results = {0:0, 1:0, 2:0, 3:0, 4:0, 5:0} 32 | for _ in range(30): 33 | winning_draw = get_ticket() 34 | matches = check_ticket(bd_ticket, winning_draw) 35 | results[matches] += 1 36 | 37 | # Show results. 38 | for num, num_matches in results.items(): 39 | print(f"Match {num}: {num_matches}") -------------------------------------------------------------------------------- /mp149_debugging_8/card_models.py: -------------------------------------------------------------------------------- 1 | import card_data 2 | 3 | class Card: 4 | 5 | def __init__(self, rank, suit): 6 | self.rank = rank 7 | self.suit = suit 8 | 9 | def __repr__(self): 10 | symbol = card_data.suits_symbols[self.suit] 11 | return f"{self.rank}{symbol}" 12 | 13 | def __eq__(self, card_2): 14 | """Two cards are equal if their ranks match.""" 15 | return self.rank == card_2.rank 16 | 17 | def __gt__(self, card_2): 18 | """A card is greater if its value is higher.""" 19 | return self.value > card_2.value 20 | 21 | def __lt__(self, card_2): 22 | """A card is lesser if its value is lesser.""" 23 | return self.value < card_2.value 24 | 25 | @property 26 | def value(self): 27 | """Get a numerical value for the card.""" 28 | return card_data.ranks_values[self.rank] 29 | 30 | def same_suit(cards): 31 | """Check if all cards have the same suit.""" 32 | suits = [c.suit for c in cards] 33 | return len(set(suits)) == 1 34 | 35 | ace_spades = Card("A", "spades") 36 | ace_clubs = Card("A", "clubs") 37 | ten_spades = Card("10", "spades") 38 | -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/cli_10.py: -------------------------------------------------------------------------------- 1 | """Process the CLI for add_border.py.""" 2 | 3 | import sys, argparse 4 | from pathlib import Path 5 | 6 | def process_cli_args(options): 7 | """Process all CLI arguments.""" 8 | parser = argparse.ArgumentParser() 9 | 10 | # Define arguments. 11 | parser.add_argument('path', 12 | help="path to the image file") 13 | parser.add_argument('border_width', 14 | nargs='?', type=int, 15 | help="default: 2px") 16 | parser.add_argument('--padding', type=int, 17 | help="padding between image and border") 18 | parser.add_argument('--border-color', type=str, 19 | help="default: lightgray") 20 | 21 | # Process arguments. 22 | args = parser.parse_args() 23 | 24 | path = Path(args.path) 25 | if not path.exists(): 26 | print(f"{path} does not seem to exist.") 27 | sys.exit() 28 | 29 | if args.border_width: 30 | options['border_width'] = args.border_width 31 | if args.padding: 32 | options['padding'] = args.padding 33 | if args.border_color: 34 | options['border_color'] = args.border_color 35 | 36 | return path -------------------------------------------------------------------------------- /mp78_streamlit_basics/roller_chart.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | import altair as alt 4 | import pandas as pd 5 | import streamlit as st 6 | 7 | # Input widgets 8 | side_options = [6, 10, 12, 20] 9 | num_sides = st.radio("Number of sides:", side_options) 10 | num_dice = st.slider("Number of dice:", 1, 10, value=2) 11 | num_rolls_sim = st.slider("Number of rolls in simulation", 12 | 1_000, 100_000, value=1_000, step=1_000) 13 | 14 | st.button("Roll") 15 | 16 | # Roll calculation 17 | rolls = [randint(1, num_sides) for _ in range(num_dice)] 18 | roll = sum(rolls) 19 | 20 | # Simulation rolls 21 | sim_rolls = [] 22 | for _ in range(num_rolls_sim): 23 | sim_roll = sum( 24 | [randint(1, num_sides) for _ in range(num_dice)]) 25 | sim_rolls.append(sim_roll) 26 | df_sim = pd.DataFrame({"rolls": sim_rolls}) 27 | 28 | # Create histogram 29 | chart = alt.Chart(df_sim).mark_bar().encode( 30 | alt.X("rolls", bin=True), 31 | y="count()", 32 | ) 33 | chart.title = f"Simulation of {num_rolls_sim} rolls" 34 | 35 | # Output message 36 | st.write("---") 37 | st.subheader(roll) 38 | st.write(str(rolls)) 39 | 40 | st.write("---") 41 | st.altair_chart(chart) -------------------------------------------------------------------------------- /mp65_october_wx/october_temps_3_plot_highs.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import pandas as pd 3 | import matplotlib.pyplot as plt 4 | 5 | path = Path('wx_data/sitka_temps_1983_2023.csv') 6 | df_all = pd.read_csv(path) 7 | df_all['DATE'] = pd.to_datetime(df_all['DATE']) 8 | 9 | # Keep only October's data for each year. 10 | df_october = df_all[df_all['DATE'].dt.month == 10] 11 | 12 | # Visualize data. 13 | fig, ax = plt.subplots(figsize=(10, 6)) 14 | title = "October 2023, Sitka AK" 15 | ax.set_title(title, fontsize=18) 16 | ax.set_xlabel("October __") 17 | ax.set_ylabel("T (F)") 18 | 19 | # Plot each year as a separate line. 20 | for year in range(1983, 2024): 21 | df_current_year = df_october[df_october['DATE'].dt.year == year] 22 | dates = df_current_year['DATE'] 23 | 24 | # Want integer days, not actual dates for plotting. 25 | days = df_current_year['DATE'].dt.day 26 | highs = df_current_year['TMAX'] 27 | 28 | # Set line style by year. 29 | if year == 2023: 30 | ax.plot(days, highs, color='red', alpha=0.6) 31 | else: 32 | ax.plot(days, highs, color='gray', alpha=0.2) 33 | 34 | plt.savefig("october_highs.png", bbox_inches="tight") -------------------------------------------------------------------------------- /mp151_debugging_10/go_fish_fixed/go_fish.py: -------------------------------------------------------------------------------- 1 | """Go Fish game, where one person plays against computer.""" 2 | 3 | from card_models import Card, Hand, Deck 4 | 5 | 6 | class GoFish: 7 | 8 | def __init__(self): 9 | # Start with a new shuffled deck. 10 | self.deck = Deck() 11 | self.deck.shuffle() 12 | 13 | def start_game(self): 14 | # Deal two hands. 15 | hands = self.deck.deal(num_hands=2, num_cards=7) 16 | self.player_hand, self.computer_hand = hands 17 | 18 | self.player_hand.organize() 19 | self.computer_hand.organize() 20 | 21 | self.player_pairs = [] 22 | self.computer_pairs = [] 23 | 24 | # Player goes first. 25 | self.player_turn() 26 | 27 | def player_turn(self): 28 | """Manage the human player's turn.""" 29 | self.show_state() 30 | 31 | def show_state(self): 32 | """Show the current state of the game.""" 33 | print("Player hand:") 34 | self.player_hand.show() 35 | 36 | print("\nComputer hand:") 37 | self.computer_hand.show(hidden=True) 38 | 39 | if __name__ == "__main__": 40 | gf_game = GoFish() 41 | gf_game.start_game() -------------------------------------------------------------------------------- /mp151_debugging_10/go_fish_with_error/go_fish.py: -------------------------------------------------------------------------------- 1 | """Go Fish game, where one person plays against computer.""" 2 | 3 | from card_models import Card, Hand, Deck 4 | 5 | 6 | class GoFish: 7 | 8 | def __init__(self): 9 | # Start with a new shuffled deck. 10 | self.deck = Deck() 11 | self.deck.shuffle() 12 | 13 | def start_game(self): 14 | # Deal two hands. 15 | hands = self.deck.deal(num_hands=2, num_cards=7) 16 | self.player_hand, self.computer_hand = hands 17 | 18 | self.player_hand.organize() 19 | self.computer_hand.organize() 20 | 21 | self.player_pairs = [] 22 | self.computer_pairs = [] 23 | 24 | # Player goes first. 25 | self.player_turn() 26 | 27 | def player_turn(self): 28 | """Manage the human player's turn.""" 29 | self.show_state() 30 | 31 | def show_state(self): 32 | """Show the current state of the game.""" 33 | print("Player hand:") 34 | self.player_hand.show() 35 | 36 | print("\nComputer hand:") 37 | self.computer_hand.show(hidden=True) 38 | 39 | if __name__ == "__main__": 40 | gf_game = GoFish() 41 | gf_game.start_game() -------------------------------------------------------------------------------- /mp78_streamlit_basics/roller_sidebar.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | import altair as alt 4 | import pandas as pd 5 | import streamlit as st 6 | 7 | # Input widgets 8 | side_options = [6, 10, 12, 20] 9 | num_sides = st.sidebar.radio("Number of sides:", side_options) 10 | num_dice = st.sidebar.slider("Number of dice:", 1, 10, value=2) 11 | num_rolls_sim = st.sidebar.slider("Number of rolls in simulation", 12 | 1_000, 100_000, value=1_000, step=1_000) 13 | 14 | # Roll calculation 15 | rolls = [randint(1, num_sides) for _ in range(num_dice)] 16 | roll = sum(rolls) 17 | 18 | # Simulation rolls 19 | sim_rolls = [] 20 | for _ in range(num_rolls_sim): 21 | sim_roll = sum( 22 | [randint(1, num_sides) for _ in range(num_dice)]) 23 | sim_rolls.append(sim_roll) 24 | df_sim = pd.DataFrame({"rolls": sim_rolls}) 25 | 26 | # Create histogram 27 | chart = alt.Chart(df_sim).mark_bar().encode( 28 | alt.X("rolls", bin=True), 29 | y="count()", 30 | ) 31 | chart.title = f"Simulation of {num_rolls_sim} rolls" 32 | 33 | # Main page 34 | st.title("Rolling Dice") 35 | st.button("Roll!") 36 | 37 | st.write("---") 38 | st.subheader(roll) 39 | st.write(str(rolls)) 40 | 41 | st.write("---") 42 | st.altair_chart(chart) -------------------------------------------------------------------------------- /mp43_substack_notes_cguo/main_2.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | session = requests.Session() 4 | 5 | # Log in, using the existing session. 6 | login_url = "https://substack.com/api/v1/login" 7 | login_data = { 8 | "redirect": "", 9 | "for_pub": "PUBLICATION", 10 | "email": "MY_EMAIL", 11 | "password": "MY_PASSWORD", 12 | "captcha_response": None, 13 | } 14 | 15 | login_response = session.post(login_url, json=login_data) 16 | 17 | # Assemble data for the note. 18 | note_url = "https://substack.com/api/v1/comment/feed" 19 | note_headers = {"Content-Type": "application/json"} 20 | note_content = [] 21 | 22 | for line in tweet.split("\n"): 23 | if line: 24 | note_content.append( 25 | {"type": "paragraph", 26 | "content": [{"type": "text", "text": line}]} 27 | ) 28 | else: 29 | note_content.append({"type": "paragraph"}) 30 | 31 | note_data = { 32 | "bodyJson": { 33 | "type": "doc", 34 | "attrs": {"schemaVersion": "v1"}, 35 | "content": note_content, 36 | }, 37 | "tabId": "for-you", 38 | "replyMinimumRole": "everyone", 39 | } 40 | 41 | note_response = session.post(note_url, 42 | headers=note_headers, json=note_data) -------------------------------------------------------------------------------- /mp97_snippets/pygparser.py: -------------------------------------------------------------------------------- 1 | from pygments import highlight 2 | from pygments.lexers import PythonLexer, TextLexer, JsonLexer 3 | from pygments.formatters import ImageFormatter, RtfFormatter 4 | 5 | from pathlib import Path 6 | 7 | # Get all snippets. 8 | raw_dir = Path("raw_snippets") 9 | raw_files = [ 10 | path 11 | for path in raw_dir.iterdir() 12 | if path.suffix in [".py", ".json", ".txt"] 13 | ] 14 | 15 | # Highlight all snippets. 16 | hl_dir = Path("processed_snippets") 17 | for file in raw_files: 18 | code = file.read_text() 19 | 20 | if file.suffix == ".py": 21 | lexer = PythonLexer() 22 | elif file.suffix == ".json": 23 | lexer = JsonLexer() 24 | else: 25 | lexer = TextLexer() 26 | 27 | hl_filename = file.stem + ".png" 28 | hl_file = hl_dir / hl_filename 29 | with open(hl_file, "wb") as f: 30 | # Set better parameters for ImageFormatter. 31 | formatter = ImageFormatter( 32 | line_pad=15, 33 | font_size=60, 34 | line_numbers=False, 35 | ) 36 | 37 | highlighted_code = highlight(code, lexer, formatter) 38 | f.write(highlighted_code) 39 | print("Wrote file:", hl_file.as_posix()) -------------------------------------------------------------------------------- /mp53_oop12_abc/account.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | """Model a user account on a site or app.""" 3 | 4 | def __init__(self, username, password=""): 5 | self.username = username 6 | self._store_password(password) 7 | 8 | def welcome_user(self): 9 | print(f"Welcome to the site, {self.username}!") 10 | 11 | def close_account(self): 12 | print(f"Closed account for {self.username}.") 13 | 14 | def _store_password(self, password): 15 | print(f"Stored password for {self.username}.") 16 | 17 | 18 | class FreeAccount(Account): 19 | 20 | def welcome_user(self): 21 | super().welcome_user() 22 | print("You'll have limited access on a free account.") 23 | 24 | 25 | class StandardAccount(Account): 26 | 27 | def welcome_user(self): 28 | super().welcome_user() 29 | print("You have access to all features on the site.") 30 | 31 | 32 | class PremiumAccount(Account): 33 | 34 | def welcome_user(self): 35 | super().welcome_user() 36 | print("Thank you for supporting us at this level!") 37 | 38 | 39 | if __name__ == "__main__": 40 | account = PremiumAccount("birdie") 41 | account.welcome_user() 42 | account.close_account() -------------------------------------------------------------------------------- /mp53_oop12_abc/account_5_assertive_account.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | class Account(ABC): 4 | """Model a user account on a site or app.""" 5 | 6 | def __init__(self, username, password=""): 7 | self.username = username 8 | self._store_password(password) 9 | 10 | def welcome_user(self): 11 | print(f"Welcome to the site, {self.username}!") 12 | 13 | @abstractmethod 14 | def close_account(self): 15 | pass 16 | 17 | def _store_password(self, password): 18 | print(f"Stored password for {self.username}.") 19 | 20 | 21 | class FreeAccount(Account): 22 | 23 | def welcome_user(self): 24 | super().welcome_user() 25 | print("You'll have limited access on a free account.") 26 | 27 | 28 | class StandardAccount(Account): 29 | 30 | def welcome_user(self): 31 | super().welcome_user() 32 | print("You have access to all features on the site.") 33 | 34 | 35 | class PremiumAccount(Account): 36 | 37 | def welcome_user(self): 38 | super().welcome_user() 39 | print("Thank you for supporting us at this level!") 40 | 41 | 42 | if __name__ == "__main__": 43 | account = PremiumAccount("birdie") 44 | account.welcome_user() 45 | -------------------------------------------------------------------------------- /mp8_lists_closer_look_lists_tuples/list_tuple_size_comparison.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from matplotlib import pyplot as plt 4 | 5 | 6 | # What's the longest sequence we want to examine? 7 | max_length = 100 8 | 9 | list_sizes = [] 10 | tuple_sizes = [] 11 | for seq_length in range(max_length): 12 | # For every sequence length, make a list of squares and a tuple of squares. 13 | # Record the size of each list. 14 | squares_list = [x**2 for x in range(seq_length)] 15 | list_sizes.append(sys.getsizeof(squares_list)) 16 | 17 | # Record the size of each tuple. 18 | squares_tuple = tuple(x**2 for x in range(seq_length)) 19 | tuple_sizes.append(sys.getsizeof(squares_tuple)) 20 | 21 | # Plot the size of each sequence against the number of items. 22 | # Note: For Maptlotlib 3.5, use "seaborn". 23 | plt.style.use("seaborn-v0_8") 24 | 25 | # X values are the number of items in each sequence. 26 | x_values = list(range(1, max_length+1)) 27 | 28 | fig, ax = plt.subplots(figsize=(10, 6)) 29 | ax.plot(x_values, list_sizes) 30 | ax.plot(x_values, tuple_sizes) 31 | 32 | ax.set_title("Size of lists and tuples vs number of items", fontsize=24) 33 | ax.set_xlabel("Number of items", fontsize=14) 34 | ax.set_ylabel("Size (bytes)", fontsize=14) 35 | 36 | plt.show() 37 | -------------------------------------------------------------------------------- /mp143_debugging_4/utils.py: -------------------------------------------------------------------------------- 1 | """Utility functions for dice_battle.""" 2 | 3 | from die import Die 4 | 5 | 6 | def battle(): 7 | """Run a single dice battle.""" 8 | die = Die() 9 | 10 | a_result = die.roll() 11 | b_result = die.roll() 12 | return a_result, b_result 13 | 14 | 15 | def update_results(a_result, b_result, results): 16 | """Update results after a battle.""" 17 | if a_result > b_result: 18 | print("Player A won!") 19 | results["wins_a"] += 1 20 | elif b_result > a_result: 21 | print("Player B won!") 22 | results["wins_b"] += 1 23 | else: 24 | print("Tie!") 25 | results["ties"] += 1 26 | 27 | 28 | def show_summary(results): 29 | """Show summary of all battles.""" 30 | print("\n\nSummary:") 31 | print(f" Player A won {results["wins_a"]} battles.") 32 | print(f" Player B won {results["wins_b"]} battles.") 33 | print(f" There were {results["ties"]} tied battles.") 34 | 35 | if results["wins_a"] > results["wins_b"]: 36 | print("\nClearly, player A is better at rolling dice.") 37 | elif results["wins_b"] > results["wins_a"]: 38 | print("\nClearly, player B is better at rolling dice.") 39 | else: 40 | print("\nClearly, player A and player B are equals.") -------------------------------------------------------------------------------- /mp24_grounding_part_3/partial_programs/add_border_7.py: -------------------------------------------------------------------------------- 1 | """Add a border to any image.""" 2 | 3 | from PIL import Image, ImageOps, UnidentifiedImageError 4 | 5 | from cli import process_cli_args 6 | 7 | 8 | def load_image(path): 9 | """Load the image file.""" 10 | try: 11 | return Image.open(path) 12 | except UnidentifiedImageError: 13 | print(f"{path} does not seem to be an image file.") 14 | sys.exit() 15 | 16 | def process_image(img, options): 17 | """Modify the original image.""" 18 | 19 | # Add some padding before adding the border. 20 | # The padding is just a white border added before 21 | # the actual border. 22 | new_img = ImageOps.expand(img, border=options['padding'], 23 | fill="white") 24 | 25 | # Add the border. 26 | new_img = ImageOps.expand(new_img, 27 | border=options['border_width'], 28 | fill=options['border_color']) 29 | 30 | return new_img 31 | 32 | # Set default options. 33 | options = { 34 | 'border_width': 2, 35 | 'padding': 0, 36 | 'border_color': 'lightgray' 37 | } 38 | path = process_cli_args(options) 39 | img = load_image(path) 40 | new_img = process_image(img, options) 41 | 42 | # Save new image. 43 | new_path = path.parent / f"{path.stem}_bordered{path.suffix}" 44 | new_img.save(new_path) -------------------------------------------------------------------------------- /mp19_improving_code_blocks/partial_programs/email_parser_4.py: -------------------------------------------------------------------------------- 1 | """Parse raw post data, and generate neatly formatted 2 | code block titles. 3 | """ 4 | 5 | from pathlib import Path 6 | 7 | def process_code_block(line, lines_iter, modified_lines): 8 | """Check for a title, and convert as needed.""" 9 | modified_lines.append(line) 10 | 11 | # Read post file and template file. 12 | post = Path('raw_post.html').read_text() 13 | template = Path('my_template.eml').read_text() 14 | 15 | # Loop over the lines in the raw post. 16 | # When we get to a code block, look for a title. 17 | # If we find a title, rewrite that line and the 18 | # next line. 19 | modified_lines = [] 20 | lines = post.split("\n") 21 | lines_iter = iter(lines) 22 | 23 | while True: 24 | try: 25 | line = next(lines_iter) 26 | except StopIteration: 27 | break 28 | else: 29 | if "
" in line:
30 |             process_code_block(line, lines_iter, modified_lines)
31 |         else:
32 |             # Keep the line as is.
33 |             modified_lines.append(line)
34 | 
35 | # Write the modified lines into the template.
36 | post_html = "\n".join(modified_lines)
37 | 
38 | eml_string = template.replace('post_body', post_html)
39 | 
40 | output_file = Path('output_files/modified_test_email.eml')
41 | output_file.write_text(eml_string)


--------------------------------------------------------------------------------
/mp124_real_estate_images/image_archiver_3_first_full_image.py:
--------------------------------------------------------------------------------
 1 | from pathlib import Path
 2 | 
 3 | import httpx
 4 | 
 5 | from selenium import webdriver
 6 | from selenium.webdriver.chrome.service import Service
 7 | from webdriver_manager.chrome import ChromeDriverManager
 8 | from selenium.webdriver.common.by import By
 9 | from selenium.webdriver.support.ui import WebDriverWait
10 | from selenium.webdriver.support import expected_conditions as EC
11 | 
12 | 
13 | url = "https://www.zillow.com/homedetails/"
14 | url += "432-Park-Ave-PENTHOUSE-New-York-NY-10022/2069500049_zpid/"
15 | 
16 | driver = webdriver.Chrome(
17 |     service=Service(ChromeDriverManager().install()))
18 | 
19 | # Open main property page.
20 | driver.get(url)
21 | 
22 | # Click on first image in listing.
23 | button = WebDriverWait(driver, 10).until(
24 |     EC.element_to_be_clickable((
25 |         By.CSS_SELECTOR,
26 |         "button[aria-label='view larger view of the 1 photo of this home']"
27 |     ))
28 | )
29 | button.click()
30 | 
31 | # On main photos page. Click first image button.
32 | li_element = WebDriverWait(driver, 10).until(
33 |     EC.presence_of_element_located((
34 |         By.CSS_SELECTOR, "li.viw-tile-0"))
35 | )
36 | button = li_element.find_element(
37 |     By.CSS_SELECTOR, "button[data-cy='loaded-photo-tile']")
38 | button.click()
39 | 
40 | breakpoint()
41 | 


--------------------------------------------------------------------------------
/mp123_mortgages/mortgage_analysis_1.py:
--------------------------------------------------------------------------------
 1 | """Analyze a mortgage loan."""
 2 | 
 3 | purchase_price = 500_000
 4 | interest_rate = 0.075
 5 | loan_term = 360
 6 | 
 7 | # Find a monthly payment that pays off the loan.
 8 | monthly_payment = 1.00
 9 | principal = purchase_price
10 | 
11 | total_principal = 0
12 | total_interest = 0
13 | while True:
14 |     # Run the life of the loan with the current payment.
15 |     for payment_num in range(loan_term):
16 |         interest = (interest_rate/12) * principal
17 |         toward_principal = monthly_payment - interest
18 |         principal -= toward_principal
19 | 
20 |         total_interest += interest
21 |         total_principal += toward_principal
22 | 
23 |     # Exit loop if loan is paid off.
24 |     if principal <= 0:
25 |         break
26 | 
27 |     # Loan was not paid off. Increase monthly payment, and reset loan.
28 |     monthly_payment += 1.00
29 |     principal = purchase_price
30 | 
31 |     total_principal = 0
32 |     total_interest = 0
33 | 
34 | # Summarize loan.
35 | total_paid = total_principal + total_interest
36 | print("Loan summary:")
37 | print(f"  Purchase price: ${purchase_price:,.2f}")
38 | print(f"  Monthly payment: ${monthly_payment:,.2f}")
39 | print(f"  Principal paid: ${total_principal:,.2f}")
40 | print(f"  Total interest paid: ${total_interest:,.2f}")
41 | print(f"  Total paid: ${total_paid:,.2f}")
42 | 


--------------------------------------------------------------------------------
/mp154_debugging_11/go_fish_utils.py:
--------------------------------------------------------------------------------
 1 | """Utility functions for the Go Fish game."""
 2 | 
 3 | import subprocess
 4 | import sys
 5 | 
 6 | def get_player_guess(player_hand):
 7 |     """Get a valid guess from the player."""
 8 |     msg = "\nWhat card would you like to ask for? "
 9 |     requested_card = input(msg).upper()
10 | 
11 |     if requested_card == "QUIT":
12 |         sys.exit("\nThanks for playing!")
13 |     if requested_card not in "2345678910JQKA":
14 |         print("Invalid entry, please try again.")
15 |         get_player_guess(player_hand)
16 | 
17 |     player_ranks = [c.rank for c in player_hand.cards]
18 |     if requested_card not in player_ranks:
19 |         print("You don't have that card!")
20 |         get_player_guess(player_hand)
21 | 
22 |     # Valid response.
23 |     return requested_card
24 | 
25 | def remove_card(target_rank, hand):
26 |     """Remove the first card with a matching rank, and return it."""
27 |     for card in hand.cards:
28 |         if card.rank == target_rank:
29 |             hand.cards.remove(card)
30 |             return card
31 | 
32 | def clear_terminal():
33 |     """Clear the terminal."""
34 |     # Don't clear terminal in verbose mode.
35 |     if "-v" in sys.argv:
36 |         return
37 |         
38 |     if sys.platform == "win32":
39 |         subprocess.run("cls")
40 |     else:
41 |         subprocess.run("clear")


--------------------------------------------------------------------------------