shedding 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- shedding-0.1.0/LICENSE +21 -0
- shedding-0.1.0/MANIFEST.in +4 -0
- shedding-0.1.0/PKG-INFO +141 -0
- shedding-0.1.0/README.md +114 -0
- shedding-0.1.0/pyproject.toml +56 -0
- shedding-0.1.0/setup.cfg +4 -0
- shedding-0.1.0/shedding/__init__.py +3 -0
- shedding-0.1.0/shedding/__main__.py +27 -0
- shedding-0.1.0/shedding/app.py +451 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/README.md +80 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/hints.md +26 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/skins/mgs/README.md +83 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/skins/mgs/hints.md +26 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/skins/mgs/starter.py +25 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/skins/mgs/test_lesson.py +135 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/starter.py +25 -0
- shedding-0.1.0/shedding/lessons/01_variables_and_numbers/test_lesson.py +135 -0
- shedding-0.1.0/shedding/lessons/02_strings/README.md +71 -0
- shedding-0.1.0/shedding/lessons/02_strings/hints.md +24 -0
- shedding-0.1.0/shedding/lessons/02_strings/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/02_strings/skins/mgs/README.md +73 -0
- shedding-0.1.0/shedding/lessons/02_strings/skins/mgs/hints.md +25 -0
- shedding-0.1.0/shedding/lessons/02_strings/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/02_strings/skins/mgs/starter.py +22 -0
- shedding-0.1.0/shedding/lessons/02_strings/skins/mgs/test_lesson.py +151 -0
- shedding-0.1.0/shedding/lessons/02_strings/starter.py +22 -0
- shedding-0.1.0/shedding/lessons/02_strings/test_lesson.py +151 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/README.md +86 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/hints.md +23 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/skins/mgs/README.md +88 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/skins/mgs/hints.md +25 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/skins/mgs/starter.py +26 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/skins/mgs/test_lesson.py +174 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/starter.py +26 -0
- shedding-0.1.0/shedding/lessons/03_booleans_and_conditions/test_lesson.py +174 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/README.md +83 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/hints.md +24 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/skins/mgs/README.md +84 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/skins/mgs/hints.md +25 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/skins/mgs/starter.py +23 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/skins/mgs/test_lesson.py +151 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/starter.py +22 -0
- shedding-0.1.0/shedding/lessons/04_lists_and_loops/test_lesson.py +151 -0
- shedding-0.1.0/shedding/lessons/05_temperature_converter/README.md +51 -0
- shedding-0.1.0/shedding/lessons/05_temperature_converter/hints.md +17 -0
- shedding-0.1.0/shedding/lessons/05_temperature_converter/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/05_temperature_converter/skins/mgs/README.md +54 -0
- shedding-0.1.0/shedding/lessons/05_temperature_converter/skins/mgs/hints.md +17 -0
- shedding-0.1.0/shedding/lessons/05_temperature_converter/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/05_temperature_converter/skins/mgs/starter.py +35 -0
- shedding-0.1.0/shedding/lessons/05_temperature_converter/starter.py +35 -0
- shedding-0.1.0/shedding/lessons/05_temperature_converter/test_lesson.py +70 -0
- shedding-0.1.0/shedding/lessons/06_calculator/README.md +72 -0
- shedding-0.1.0/shedding/lessons/06_calculator/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/06_calculator/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/06_calculator/skins/mgs/README.md +74 -0
- shedding-0.1.0/shedding/lessons/06_calculator/skins/mgs/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/06_calculator/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/06_calculator/skins/mgs/starter.py +33 -0
- shedding-0.1.0/shedding/lessons/06_calculator/starter.py +33 -0
- shedding-0.1.0/shedding/lessons/06_calculator/test_lesson.py +101 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/README.md +73 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/hints.md +27 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/skins/mgs/README.md +78 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/skins/mgs/hints.md +30 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/skins/mgs/starter.py +36 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/skins/mgs/test_lesson.py +97 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/starter.py +36 -0
- shedding-0.1.0/shedding/lessons/07_number_guessing_game/test_lesson.py +97 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/README.md +82 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/hints.md +28 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/skins/mgs/README.md +84 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/skins/mgs/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/skins/mgs/starter.py +48 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/skins/mgs/test_lesson.py +102 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/starter.py +48 -0
- shedding-0.1.0/shedding/lessons/08_password_checker/test_lesson.py +102 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/README.md +93 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/skins/mgs/README.md +96 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/skins/mgs/hints.md +30 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/skins/mgs/starter.py +47 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/skins/mgs/test_lesson.py +122 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/starter.py +47 -0
- shedding-0.1.0/shedding/lessons/09_receipt_printer/test_lesson.py +122 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/README.md +71 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/skins/mgs/README.md +73 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/skins/mgs/hints.md +32 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/skins/mgs/starter.py +38 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/skins/mgs/test_lesson.py +119 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/starter.py +38 -0
- shedding-0.1.0/shedding/lessons/10_word_counter/test_lesson.py +119 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/README.md +80 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/hints.md +27 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/skins/mgs/README.md +80 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/skins/mgs/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/skins/mgs/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/skins/mgs/test_lesson.py +115 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/11_grade_book/test_lesson.py +115 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/README.md +78 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/hints.md +31 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/skins/mgs/README.md +79 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/skins/mgs/hints.md +31 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/skins/mgs/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/skins/mgs/test_lesson.py +110 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/12_ciphers/test_lesson.py +110 -0
- shedding-0.1.0/shedding/lessons/13_game_of_life/README.md +76 -0
- shedding-0.1.0/shedding/lessons/13_game_of_life/hints.md +30 -0
- shedding-0.1.0/shedding/lessons/13_game_of_life/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/13_game_of_life/skins/mgs/README.md +78 -0
- shedding-0.1.0/shedding/lessons/13_game_of_life/skins/mgs/hints.md +31 -0
- shedding-0.1.0/shedding/lessons/13_game_of_life/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/13_game_of_life/skins/mgs/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/13_game_of_life/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/13_game_of_life/test_lesson.py +112 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/README.md +94 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/hints.md +28 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/skins/mgs/README.md +99 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/skins/mgs/hints.md +31 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/skins/mgs/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/skins/mgs/test_lesson.py +122 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/14_todo_file/test_lesson.py +122 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/README.md +97 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/hints.md +32 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/skins/mgs/README.md +101 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/skins/mgs/hints.md +32 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/skins/mgs/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/skins/mgs/test_lesson.py +146 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/15_contact_book/test_lesson.py +144 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/README.md +87 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/hints.md +24 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/skins/mgs/README.md +88 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/skins/mgs/hints.md +25 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/skins/mgs/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/skins/mgs/test_lesson.py +153 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/16_bank_account/test_lesson.py +153 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/README.md +95 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/hints.md +28 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/skins/mgs/README.md +97 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/skins/mgs/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/skins/mgs/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/skins/mgs/test_lesson.py +147 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/17_library_catalogue/test_lesson.py +147 -0
- shedding-0.1.0/shedding/lessons/18_payroll/README.md +85 -0
- shedding-0.1.0/shedding/lessons/18_payroll/hints.md +28 -0
- shedding-0.1.0/shedding/lessons/18_payroll/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/18_payroll/skins/mgs/README.md +87 -0
- shedding-0.1.0/shedding/lessons/18_payroll/skins/mgs/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/18_payroll/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/18_payroll/skins/mgs/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/18_payroll/skins/mgs/test_lesson.py +124 -0
- shedding-0.1.0/shedding/lessons/18_payroll/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/18_payroll/test_lesson.py +124 -0
- shedding-0.1.0/shedding/lessons/19_poker_hands/README.md +105 -0
- shedding-0.1.0/shedding/lessons/19_poker_hands/hints.md +26 -0
- shedding-0.1.0/shedding/lessons/19_poker_hands/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/19_poker_hands/skins/mgs/README.md +107 -0
- shedding-0.1.0/shedding/lessons/19_poker_hands/skins/mgs/hints.md +27 -0
- shedding-0.1.0/shedding/lessons/19_poker_hands/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/19_poker_hands/skins/mgs/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/19_poker_hands/starter.py +5 -0
- shedding-0.1.0/shedding/lessons/19_poker_hands/test_lesson.py +142 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/README.md +117 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/hints.md +28 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/skins/mgs/README.md +118 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/skins/mgs/hints.md +28 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/skins/mgs/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/skins/mgs/test_lesson.py +188 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/20_vending_machine/test_lesson.py +188 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/README.md +96 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/hints.md +28 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/skins/mgs/README.md +100 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/skins/mgs/hints.md +30 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/skins/mgs/starter.py +10 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/skins/mgs/test_lesson.py +145 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/starter.py +10 -0
- shedding-0.1.0/shedding/lessons/21_expense_report/test_lesson.py +143 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/README.md +103 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/skins/mgs/README.md +105 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/skins/mgs/hints.md +30 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/skins/mgs/starter.py +10 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/skins/mgs/test_lesson.py +126 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/starter.py +10 -0
- shedding-0.1.0/shedding/lessons/22_log_analyzer/test_lesson.py +126 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/README.md +76 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/skins/mgs/README.md +82 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/skins/mgs/hints.md +29 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/skins/mgs/starter.py +10 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/skins/mgs/test_lesson.py +121 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/starter.py +10 -0
- shedding-0.1.0/shedding/lessons/23_habit_tracker/test_lesson.py +121 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/README.md +93 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/hints.md +32 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/skins/mgs/README.md +94 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/skins/mgs/hints.md +33 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/skins/mgs/starter.py +10 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/skins/mgs/test_lesson.py +127 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/starter.py +10 -0
- shedding-0.1.0/shedding/lessons/24_file_stats_cli/test_lesson.py +127 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/README.md +81 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/hints.md +31 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/skins/mgs/README.md +84 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/skins/mgs/hints.md +33 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/skins/mgs/starter.py +10 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/skins/mgs/test_lesson.py +130 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/25_folder_sizes/test_lesson.py +130 -0
- shedding-0.1.0/shedding/lessons/26_streaming_stats/README.md +73 -0
- shedding-0.1.0/shedding/lessons/26_streaming_stats/hints.md +30 -0
- shedding-0.1.0/shedding/lessons/26_streaming_stats/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/26_streaming_stats/skins/mgs/README.md +77 -0
- shedding-0.1.0/shedding/lessons/26_streaming_stats/skins/mgs/hints.md +30 -0
- shedding-0.1.0/shedding/lessons/26_streaming_stats/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/26_streaming_stats/skins/mgs/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/26_streaming_stats/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/26_streaming_stats/test_lesson.py +134 -0
- shedding-0.1.0/shedding/lessons/27_cache_and_retry/README.md +81 -0
- shedding-0.1.0/shedding/lessons/27_cache_and_retry/hints.md +32 -0
- shedding-0.1.0/shedding/lessons/27_cache_and_retry/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/27_cache_and_retry/skins/mgs/README.md +86 -0
- shedding-0.1.0/shedding/lessons/27_cache_and_retry/skins/mgs/hints.md +34 -0
- shedding-0.1.0/shedding/lessons/27_cache_and_retry/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/27_cache_and_retry/skins/mgs/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/27_cache_and_retry/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/27_cache_and_retry/test_lesson.py +250 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/README.md +73 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/hints.md +31 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/skins/mgs/README.md +76 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/skins/mgs/hints.md +31 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/skins/mgs/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/skins/mgs/test_lesson.py +164 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/28_context_helpers/test_lesson.py +164 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/README.md +105 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/hints.md +37 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/lesson.toml +2 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/skins/mgs/README.md +110 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/skins/mgs/hints.md +38 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/skins/mgs/lesson.toml +1 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/skins/mgs/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/skins/mgs/test_lesson.py +267 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/starter.py +9 -0
- shedding-0.1.0/shedding/lessons/29_finance_tracker/test_lesson.py +267 -0
- shedding-0.1.0/shedding/lessons.py +200 -0
- shedding-0.1.0/shedding/mascot.py +170 -0
- shedding-0.1.0/shedding/review.py +221 -0
- shedding-0.1.0/shedding/runner.py +213 -0
- shedding-0.1.0/shedding/shedding.tcss +95 -0
- shedding-0.1.0/shedding/skins.py +361 -0
- shedding-0.1.0/shedding/storage.py +201 -0
- shedding-0.1.0/shedding/widgets.py +166 -0
- shedding-0.1.0/shedding.egg-info/PKG-INFO +141 -0
- shedding-0.1.0/shedding.egg-info/SOURCES.txt +311 -0
- shedding-0.1.0/shedding.egg-info/dependency_links.txt +1 -0
- shedding-0.1.0/shedding.egg-info/entry_points.txt +2 -0
- shedding-0.1.0/shedding.egg-info/requires.txt +6 -0
- shedding-0.1.0/shedding.egg-info/top_level.txt +1 -0
- shedding-0.1.0/tests/test_app.py +157 -0
- shedding-0.1.0/tests/test_lessons_loader.py +84 -0
- shedding-0.1.0/tests/test_review.py +61 -0
- shedding-0.1.0/tests/test_runner.py +65 -0
- shedding-0.1.0/tests/test_skins.py +46 -0
- shedding-0.1.0/tests/test_storage.py +66 -0
shedding-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
shedding-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: shedding
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Learn Python by building small projects in a terminal UI, without an AI writing your code.
|
|
5
|
+
Author: dio
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/t3t5u0403/shedding
|
|
8
|
+
Project-URL: Source, https://github.com/t3t5u0403/shedding
|
|
9
|
+
Keywords: python,learning,tui,textual,exercises,pytest
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Education
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: Education
|
|
18
|
+
Requires-Python: >=3.12
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: textual[syntax]>=8.0
|
|
22
|
+
Requires-Dist: pytest>=8.0
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
|
|
25
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# shedding
|
|
29
|
+
|
|
30
|
+
A terminal app for getting solid at Python by building small projects, one lesson at a time,
|
|
31
|
+
without an AI writing your code.
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
┌ Lesson 11/29 ─────────────┐┌ solution.py ──────────────────────┐
|
|
35
|
+
│ # 11 · Grade book ││ def average(scores): │
|
|
36
|
+
│ ││ ... │
|
|
37
|
+
│ ## Goal ││ │
|
|
38
|
+
│ ... ││ │
|
|
39
|
+
│ ## Hints ││ │
|
|
40
|
+
│ Hint 1 of 3 ... ││ │
|
|
41
|
+
└───────────────────────────┘└───────────────────────────────────┘
|
|
42
|
+
┌ Results ── Tests │ Review ────────────────────────────────────┐
|
|
43
|
+
│ ✗ 2 failed, 9 passed │
|
|
44
|
+
│ ✓ average of three scores │
|
|
45
|
+
│ ✗ empty list averages to zero │
|
|
46
|
+
│ assert 0 == 0.0 ... │
|
|
47
|
+
└───────────────────────────────────────────────────────────────┘
|
|
48
|
+
F5 Run tests F1 Hint F2 Review F3 Prev F4 Next F9 Settings ^q Quit
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Install and run
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
python -m venv .venv
|
|
55
|
+
.venv/bin/pip install -e ".[dev]"
|
|
56
|
+
.venv/bin/shedding # or: .venv/bin/python -m shedding
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Options: `--lesson N` opens a specific lesson, `--lessons PATH` uses another lessons folder,
|
|
60
|
+
`--db PATH` uses another progress database. Progress, drafts and settings live in
|
|
61
|
+
`~/.local/share/shedding/shedding.db`.
|
|
62
|
+
|
|
63
|
+
## Keys
|
|
64
|
+
|
|
65
|
+
| Key | Action |
|
|
66
|
+
|---|---|
|
|
67
|
+
| F5 | Run the hidden tests against the code in the editor |
|
|
68
|
+
| F1 | Reveal the next hint (they appear under the lesson text) |
|
|
69
|
+
| F2 | Request a code review (only after the tests pass, only if enabled) |
|
|
70
|
+
| F3 / F4 | Previous / next lesson (your draft is saved automatically) |
|
|
71
|
+
| F9 | Settings: review on/off, Ollama URL and model |
|
|
72
|
+
| Esc | Switch focus between the lesson pane and the editor |
|
|
73
|
+
| Ctrl+S | Save the draft now (it also autosaves a second after you stop typing) |
|
|
74
|
+
| Ctrl+P | Command palette: jump to any lesson, reset a lesson to its starter code |
|
|
75
|
+
| Ctrl+Q | Quit |
|
|
76
|
+
|
|
77
|
+
## How lessons work
|
|
78
|
+
|
|
79
|
+
Each folder under `shedding/lessons/` is one project: a README with the goal, concepts and exact
|
|
80
|
+
requirements, a `starter.py` that is loaded into the editor, hints revealed one at a time,
|
|
81
|
+
and pytest tests the app runs but never shows. Your code is written to a temporary folder as
|
|
82
|
+
`solution.py` and pytest runs there in a subprocess with a timeout, no stdin and resource
|
|
83
|
+
limits, so an infinite loop or a stray `input()` just shows up as a failure.
|
|
84
|
+
|
|
85
|
+
The 29 lessons ramp in two ways. The topics go from variables to a SQLite-backed CLI, and
|
|
86
|
+
the scaffolding shrinks as you go:
|
|
87
|
+
|
|
88
|
+
- Lessons 01 to 04 are the basics, written as plain scripts: the starter holds given values,
|
|
89
|
+
you compute the results, and the tests re-run your code with other values.
|
|
90
|
+
- Lessons 05 to 10 give you function stubs to fill in.
|
|
91
|
+
- Lessons 11 to 19 give you only a docstring; the README lists the required names and you
|
|
92
|
+
write the signatures and pick your own helpers.
|
|
93
|
+
- Lessons 20 to 29 specify just the public surface. How you structure the program is yours
|
|
94
|
+
to decide, and the tests only look at behaviour.
|
|
95
|
+
|
|
96
|
+
Reference solutions live in `solutions/`, which the app never reads. Don't look in there
|
|
97
|
+
while doing a lesson.
|
|
98
|
+
|
|
99
|
+
## Code review (optional)
|
|
100
|
+
|
|
101
|
+
Off by default. Enable it in Settings (F9) and point it at a running [Ollama](https://ollama.com)
|
|
102
|
+
server with a model pulled (the default is `qwen2.5-coder:7b`). After your tests pass, F2 asks
|
|
103
|
+
the model for feedback. It returns a structured list of issues with line numbers and concepts
|
|
104
|
+
to look up; anything that looks like code is stripped before it reaches the screen. It will
|
|
105
|
+
not write a fix for you.
|
|
106
|
+
|
|
107
|
+
## The snake, and skins
|
|
108
|
+
|
|
109
|
+
A pixel snake lives next to the results pane. It comments on what just happened (first pass,
|
|
110
|
+
fewer failures than last run, the same failures again, a timeout), hands out a general Python
|
|
111
|
+
tip when clicked or every few minutes, and after three runs without progress reveals the next
|
|
112
|
+
hint on its own. Hide it with "Toggle mascot" in the command palette or in Settings.
|
|
113
|
+
|
|
114
|
+
Skins change the colour theme, the labels, and who the snake is:
|
|
115
|
+
|
|
116
|
+
| Skin | Snake | Flavour |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| Classic | Monty | Friendly python, plain labels |
|
|
119
|
+
| Metal Gear | Snake | Bandana, cigarette, codec calls from Otacon and the Colonel, missions instead of lessons |
|
|
120
|
+
|
|
121
|
+
The Metal Gear skin also retells every lesson: same concepts and the same tests one to one,
|
|
122
|
+
but rations instead of pizzas, codec contacts instead of a contact book, and Mother Base GMP
|
|
123
|
+
instead of a finance tracker. Switching skins swaps the lesson text, starter and tests, keeps
|
|
124
|
+
your progress, and keeps a separate draft per skin.
|
|
125
|
+
|
|
126
|
+
Pick one in Settings (F9) or with "Skin: …" in the command palette. Adding a skin is one
|
|
127
|
+
entry in `shedding/skins.py`: a Textual theme, a labels table, pixel frames and a set of lines
|
|
128
|
+
per event.
|
|
129
|
+
|
|
130
|
+
## Verifying lessons
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
.venv/bin/python scripts/verify_lessons.py # all lessons
|
|
134
|
+
.venv/bin/python scripts/verify_lessons.py 07 -v # one lesson, every check
|
|
135
|
+
.venv/bin/python -m pytest tests # the app's own tests
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
For every lesson the verifier checks that the files and metadata are valid, the reference
|
|
139
|
+
solution passes all tests, the starter fails, and both deliberately wrong solutions import
|
|
140
|
+
cleanly but fail at least one test. Anything else is reported as broken and CI fails.
|
|
141
|
+
See `docs/authoring.md` for how to add a lesson.
|
shedding-0.1.0/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# shedding
|
|
2
|
+
|
|
3
|
+
A terminal app for getting solid at Python by building small projects, one lesson at a time,
|
|
4
|
+
without an AI writing your code.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
┌ Lesson 11/29 ─────────────┐┌ solution.py ──────────────────────┐
|
|
8
|
+
│ # 11 · Grade book ││ def average(scores): │
|
|
9
|
+
│ ││ ... │
|
|
10
|
+
│ ## Goal ││ │
|
|
11
|
+
│ ... ││ │
|
|
12
|
+
│ ## Hints ││ │
|
|
13
|
+
│ Hint 1 of 3 ... ││ │
|
|
14
|
+
└───────────────────────────┘└───────────────────────────────────┘
|
|
15
|
+
┌ Results ── Tests │ Review ────────────────────────────────────┐
|
|
16
|
+
│ ✗ 2 failed, 9 passed │
|
|
17
|
+
│ ✓ average of three scores │
|
|
18
|
+
│ ✗ empty list averages to zero │
|
|
19
|
+
│ assert 0 == 0.0 ... │
|
|
20
|
+
└───────────────────────────────────────────────────────────────┘
|
|
21
|
+
F5 Run tests F1 Hint F2 Review F3 Prev F4 Next F9 Settings ^q Quit
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Install and run
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
python -m venv .venv
|
|
28
|
+
.venv/bin/pip install -e ".[dev]"
|
|
29
|
+
.venv/bin/shedding # or: .venv/bin/python -m shedding
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Options: `--lesson N` opens a specific lesson, `--lessons PATH` uses another lessons folder,
|
|
33
|
+
`--db PATH` uses another progress database. Progress, drafts and settings live in
|
|
34
|
+
`~/.local/share/shedding/shedding.db`.
|
|
35
|
+
|
|
36
|
+
## Keys
|
|
37
|
+
|
|
38
|
+
| Key | Action |
|
|
39
|
+
|---|---|
|
|
40
|
+
| F5 | Run the hidden tests against the code in the editor |
|
|
41
|
+
| F1 | Reveal the next hint (they appear under the lesson text) |
|
|
42
|
+
| F2 | Request a code review (only after the tests pass, only if enabled) |
|
|
43
|
+
| F3 / F4 | Previous / next lesson (your draft is saved automatically) |
|
|
44
|
+
| F9 | Settings: review on/off, Ollama URL and model |
|
|
45
|
+
| Esc | Switch focus between the lesson pane and the editor |
|
|
46
|
+
| Ctrl+S | Save the draft now (it also autosaves a second after you stop typing) |
|
|
47
|
+
| Ctrl+P | Command palette: jump to any lesson, reset a lesson to its starter code |
|
|
48
|
+
| Ctrl+Q | Quit |
|
|
49
|
+
|
|
50
|
+
## How lessons work
|
|
51
|
+
|
|
52
|
+
Each folder under `shedding/lessons/` is one project: a README with the goal, concepts and exact
|
|
53
|
+
requirements, a `starter.py` that is loaded into the editor, hints revealed one at a time,
|
|
54
|
+
and pytest tests the app runs but never shows. Your code is written to a temporary folder as
|
|
55
|
+
`solution.py` and pytest runs there in a subprocess with a timeout, no stdin and resource
|
|
56
|
+
limits, so an infinite loop or a stray `input()` just shows up as a failure.
|
|
57
|
+
|
|
58
|
+
The 29 lessons ramp in two ways. The topics go from variables to a SQLite-backed CLI, and
|
|
59
|
+
the scaffolding shrinks as you go:
|
|
60
|
+
|
|
61
|
+
- Lessons 01 to 04 are the basics, written as plain scripts: the starter holds given values,
|
|
62
|
+
you compute the results, and the tests re-run your code with other values.
|
|
63
|
+
- Lessons 05 to 10 give you function stubs to fill in.
|
|
64
|
+
- Lessons 11 to 19 give you only a docstring; the README lists the required names and you
|
|
65
|
+
write the signatures and pick your own helpers.
|
|
66
|
+
- Lessons 20 to 29 specify just the public surface. How you structure the program is yours
|
|
67
|
+
to decide, and the tests only look at behaviour.
|
|
68
|
+
|
|
69
|
+
Reference solutions live in `solutions/`, which the app never reads. Don't look in there
|
|
70
|
+
while doing a lesson.
|
|
71
|
+
|
|
72
|
+
## Code review (optional)
|
|
73
|
+
|
|
74
|
+
Off by default. Enable it in Settings (F9) and point it at a running [Ollama](https://ollama.com)
|
|
75
|
+
server with a model pulled (the default is `qwen2.5-coder:7b`). After your tests pass, F2 asks
|
|
76
|
+
the model for feedback. It returns a structured list of issues with line numbers and concepts
|
|
77
|
+
to look up; anything that looks like code is stripped before it reaches the screen. It will
|
|
78
|
+
not write a fix for you.
|
|
79
|
+
|
|
80
|
+
## The snake, and skins
|
|
81
|
+
|
|
82
|
+
A pixel snake lives next to the results pane. It comments on what just happened (first pass,
|
|
83
|
+
fewer failures than last run, the same failures again, a timeout), hands out a general Python
|
|
84
|
+
tip when clicked or every few minutes, and after three runs without progress reveals the next
|
|
85
|
+
hint on its own. Hide it with "Toggle mascot" in the command palette or in Settings.
|
|
86
|
+
|
|
87
|
+
Skins change the colour theme, the labels, and who the snake is:
|
|
88
|
+
|
|
89
|
+
| Skin | Snake | Flavour |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| Classic | Monty | Friendly python, plain labels |
|
|
92
|
+
| Metal Gear | Snake | Bandana, cigarette, codec calls from Otacon and the Colonel, missions instead of lessons |
|
|
93
|
+
|
|
94
|
+
The Metal Gear skin also retells every lesson: same concepts and the same tests one to one,
|
|
95
|
+
but rations instead of pizzas, codec contacts instead of a contact book, and Mother Base GMP
|
|
96
|
+
instead of a finance tracker. Switching skins swaps the lesson text, starter and tests, keeps
|
|
97
|
+
your progress, and keeps a separate draft per skin.
|
|
98
|
+
|
|
99
|
+
Pick one in Settings (F9) or with "Skin: …" in the command palette. Adding a skin is one
|
|
100
|
+
entry in `shedding/skins.py`: a Textual theme, a labels table, pixel frames and a set of lines
|
|
101
|
+
per event.
|
|
102
|
+
|
|
103
|
+
## Verifying lessons
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
.venv/bin/python scripts/verify_lessons.py # all lessons
|
|
107
|
+
.venv/bin/python scripts/verify_lessons.py 07 -v # one lesson, every check
|
|
108
|
+
.venv/bin/python -m pytest tests # the app's own tests
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
For every lesson the verifier checks that the files and metadata are valid, the reference
|
|
112
|
+
solution passes all tests, the starter fails, and both deliberately wrong solutions import
|
|
113
|
+
cleanly but fail at least one test. Anything else is reported as broken and CI fails.
|
|
114
|
+
See `docs/authoring.md` for how to add a lesson.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "shedding"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Learn Python by building small projects in a terminal UI, without an AI writing your code."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "dio" }]
|
|
14
|
+
keywords = ["python", "learning", "tui", "textual", "exercises", "pytest"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Education",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Topic :: Education",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"textual[syntax]>=8.0",
|
|
27
|
+
"pytest>=8.0",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/t3t5u0403/shedding"
|
|
32
|
+
Source = "https://github.com/t3t5u0403/shedding"
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
dev = ["pytest-asyncio>=0.24", "build>=1.2"]
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
shedding = "shedding.__main__:main"
|
|
39
|
+
|
|
40
|
+
[tool.setuptools]
|
|
41
|
+
packages = ["shedding"]
|
|
42
|
+
include-package-data = false
|
|
43
|
+
|
|
44
|
+
[tool.setuptools.package-data]
|
|
45
|
+
shedding = [
|
|
46
|
+
"*.tcss",
|
|
47
|
+
"lessons/**/*.md",
|
|
48
|
+
"lessons/**/*.py",
|
|
49
|
+
"lessons/**/*.toml",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[tool.pytest.ini_options]
|
|
53
|
+
testpaths = ["tests"]
|
|
54
|
+
addopts = "-q"
|
|
55
|
+
asyncio_mode = "auto"
|
|
56
|
+
asyncio_default_fixture_loop_scope = "function"
|
shedding-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Command-line entry point: ``shedding`` or ``python -m shedding``."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from .app import SheddingApp
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main(argv: list[str] | None = None) -> int:
|
|
12
|
+
parser = argparse.ArgumentParser(prog="shedding", description="Learn Python by building small projects.")
|
|
13
|
+
parser.add_argument("--lessons", help="path to the lessons folder (default: bundled lessons or $SHEDDING_LESSONS)")
|
|
14
|
+
parser.add_argument("--db", help="path to the SQLite database (default: ~/.local/share/shedding/shedding.db)")
|
|
15
|
+
parser.add_argument("--lesson", type=int, metavar="N", help="open lesson number N")
|
|
16
|
+
args = parser.parse_args(argv)
|
|
17
|
+
try:
|
|
18
|
+
app = SheddingApp(lessons_dir=args.lessons, db_path=args.db, start_lesson=args.lesson)
|
|
19
|
+
except FileNotFoundError as exc:
|
|
20
|
+
print(exc, file=sys.stderr)
|
|
21
|
+
return 2
|
|
22
|
+
app.run()
|
|
23
|
+
return 0
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
if __name__ == "__main__":
|
|
27
|
+
sys.exit(main())
|