├── projects ├── funny-web │ ├── requirements.piptools │ ├── README.md │ ├── .vscode │ │ ├── settings.json │ │ └── launch.json │ ├── data.py │ ├── templates │ │ └── joke.html │ ├── app.py │ ├── requirements.txt │ ├── LICENSE │ └── .gitignore ├── rps │ ├── README.md │ ├── LICENSE │ ├── .gitignore │ └── game.py └── readme.md ├── readme_resources └── pragmatic-git.png ├── ruff.toml ├── LICENSE ├── pyrefly.toml ├── .gitignore └── README.md /projects/funny-web/requirements.piptools: -------------------------------------------------------------------------------- 1 | flask 2 | -------------------------------------------------------------------------------- /projects/funny-web/README.md: -------------------------------------------------------------------------------- 1 | # funny-web 2 | Sample app from course 3 | -------------------------------------------------------------------------------- /projects/rps/README.md: -------------------------------------------------------------------------------- 1 | # sketchy-rock-paper-scissors 2 | A RPS app 3 | -------------------------------------------------------------------------------- /projects/funny-web/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.formatting.provider": "black" 3 | } -------------------------------------------------------------------------------- /readme_resources/pragmatic-git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/talkpython/pragmatic-git-course/HEAD/readme_resources/pragmatic-git.png -------------------------------------------------------------------------------- /projects/funny-web/data.py: -------------------------------------------------------------------------------- 1 | jokes = [ 2 | "Relationship status? I'll leave the relations to the database.", 3 | 'How do you get the code for the bank vault? You checkout their branch.', 4 | 'What diet did the ghost developer go on? Boolean', 5 | ] 6 | -------------------------------------------------------------------------------- /projects/funny-web/templates/joke.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Funny Web 6 | 7 | 8 | 9 |

Funny Web

10 | 11 |
12 | The joke: 13 |
14 | 15 |
16 | {{ joke_text }} 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /projects/funny-web/app.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | import data 4 | import flask 5 | from flask import Flask 6 | 7 | app = Flask(__name__) 8 | 9 | 10 | @app.get('/') 11 | def tell_a_joke(): 12 | print('Beginning to tell a joke!') 13 | joke = random.choice(data.jokes) 14 | print(f'The joke we are telling is {joke}') 15 | return flask.render_template('joke.html', joke_text=joke) 16 | 17 | 18 | if __name__ == '__main__': 19 | app.run(port=8001, debug=True) 20 | -------------------------------------------------------------------------------- /projects/funny-web/requirements.txt: -------------------------------------------------------------------------------- 1 | # This file was autogenerated by uv via the following command: 2 | # uv pip compile requirements.piptools --output-file requirements.txt 3 | blinker==1.9.0 4 | # via flask 5 | click==8.3.1 6 | # via flask 7 | flask==3.1.2 8 | # via -r requirements.piptools 9 | itsdangerous==2.2.0 10 | # via flask 11 | jinja2==3.1.6 12 | # via flask 13 | markupsafe==3.0.3 14 | # via 15 | # flask 16 | # jinja2 17 | # werkzeug 18 | werkzeug==3.1.4 19 | # via flask 20 | -------------------------------------------------------------------------------- /projects/readme.md: -------------------------------------------------------------------------------- 1 | # See important note: 2 | 3 | We have included the code from the two repos featured in the course here. But we also made the originals public. If you: 4 | 5 | * Just want the code, here is great. 6 | * Want to interact with git and see the history, refer to them directly below 7 | 8 | # Featured repositories 9 | 10 | * **[github.com/mikeckennedy/funny-web](https://github.com/mikeckennedy/funny-web)** 11 | * **[github.com/mikeckennedy/sketchy-rock-paper-scissors](https://github.com/mikeckennedy/sketchy-rock-paper-scissors)** -------------------------------------------------------------------------------- /projects/funny-web/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python: Flask", 9 | "type": "python", 10 | "request": "launch", 11 | "module": "flask", 12 | "env": { 13 | "FLASK_APP": "app.py", 14 | "FLASK_ENV": "development" 15 | }, 16 | "args": [ 17 | "run", 18 | "--no-debugger" 19 | ], 20 | "jinja": true, 21 | "justMyCode": true 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /ruff.toml: -------------------------------------------------------------------------------- 1 | # [ruff] 2 | line-length = 120 3 | format.quote-style = "single" 4 | 5 | # Enable Pyflakes `E` and `F` codes by default. 6 | lint.select = ["E", "F", "I"] 7 | lint.ignore = [] 8 | 9 | # Exclude a variety of commonly ignored directories. 10 | exclude = [ 11 | ".bzr", 12 | ".direnv", 13 | ".eggs", 14 | ".git", 15 | ".hg", 16 | ".mypy_cache", 17 | ".nox", 18 | ".pants.d", 19 | ".ruff_cache", 20 | ".svn", 21 | ".tox", 22 | "__pypackages__", 23 | "_build", 24 | "buck-out", 25 | "build", 26 | "dist", 27 | "node_modules", 28 | ".env", 29 | ".venv", 30 | "venv", 31 | "typings/**/*.pyi", 32 | ] 33 | lint.per-file-ignores = { } 34 | 35 | # Allow unused variables when underscore-prefixed. 36 | # dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" 37 | 38 | # Assume Python 3.13. 39 | target-version = "py313" 40 | 41 | #[tool.ruff.mccabe] 42 | ## Unlike Flake8, default to a complexity level of 10. 43 | lint.mccabe.max-complexity = 10 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Talk Python 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. 22 | -------------------------------------------------------------------------------- /projects/rps/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Michael Kennedy 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. 22 | -------------------------------------------------------------------------------- /projects/funny-web/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Michael Kennedy 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. 22 | -------------------------------------------------------------------------------- /pyrefly.toml: -------------------------------------------------------------------------------- 1 | ###### configuring what to type check and where to import from 2 | 3 | # check all files in "." 4 | project-includes = ["."] 5 | # exclude dotfiles 6 | project-excludes = ["**/.[!/.]*", "**/*venv/**"] 7 | # perform an upward search for `.gitignore`, `.ignore`, and `.git/info/exclude`, and 8 | # add those to `project-excludes` automatically 9 | use-ignore-files = true 10 | # import project files from "." 11 | search-path = [".", "projects/funny-web", "projects/rps"] 12 | # let Pyrefly try to guess your search path 13 | disable-search-path-heuristics = false 14 | # do not include any third-party packages (except those provided by an interpreter) 15 | site-package-path = [] 16 | 17 | ###### configuring your python environment 18 | 19 | # assume we're running on linux, regardless of the actual current platform 20 | python-platform = "linux" 21 | # assume the Python version we're using is 3.13, without querying an interpreter 22 | python-version = "3.13" 23 | # is Pyrefly disallowed from querying for an interpreter to automatically determine your 24 | # `python-platform`, `python-version`, and extra entries to `site-package-path`? 25 | skip-interpreter-query = false 26 | # query the default Python interpreter on your system, if installed and `python_platform`, 27 | # `python-version`, or `site-package-path` are unset. 28 | # python-interpreter = null # this is commented out because there are no `null` values in TOML 29 | 30 | #### configuring your type check settings 31 | 32 | # wildcards for which Pyrefly will unconditionally replace the import with `typing.Any` 33 | replace-imports-with-any = ["quart.*"] 34 | # wildcards for which Pyrefly will replace the import with `typing.Any` if it can't be found 35 | ignore-missing-imports = ["quart.*"] 36 | # should Pyrefly skip type checking if we find a generated file? 37 | ignore-errors-in-generated-code = false 38 | # should Pyrefly do a check to see if a `-stubs` library also has `` installed? 39 | ignore-missing-source = false 40 | # what should Pyrefly do when it encounters a function that is untyped? 41 | untyped-def-behavior = "check-and-infer-return-type" 42 | # can Pyrefly recognize ignore directives other than `# pyrefly: ignore` and `# type: ignore` 43 | permissive-ignores = false 44 | 45 | [errors] 46 | # this is an empty table, meaning all errors are enabled by default 47 | 48 | # no `[[sub-config]]` entries are included, since there are none by default -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /projects/rps/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | .idea 131 | -------------------------------------------------------------------------------- /projects/funny-web/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | .idea 131 | -------------------------------------------------------------------------------- /projects/rps/game.py: -------------------------------------------------------------------------------- 1 | import random 2 | import sys 3 | 4 | VERSION = "2.2" 5 | 6 | rolls = { 7 | 'rock': { 8 | 'defeats': ['scissors', 'lizard'], 9 | 'defeated_by': ['paper', 'spock'] 10 | }, 11 | 'paper': { 12 | 'defeats': ['rock', 'spock'], 13 | 'defeated_by': ['scissors', 'lizard'] 14 | }, 15 | 'scissors': { 16 | 'defeats': ['paper', 'lizard'], 17 | 'defeated_by': ['rock', 'spock'] 18 | }, 19 | 'lizard': { 20 | 'defeats': ['paper', 'spock'], 21 | 'defeated_by': ['rock', 'scissors'] 22 | }, 23 | 'spock': { 24 | 'defeats': ['rock', 'scissors'], 25 | 'defeated_by': ['lizard', 'paper'] 26 | }, 27 | } 28 | 29 | 30 | def main(): 31 | print(f"App starting up, v{VERSION}") 32 | show_header() 33 | play_game("Player 1", "Computer") 34 | 35 | 36 | def show_header(): 37 | print("---------------------------") 38 | print(" Rock Paper Scissors") 39 | print(f" v{VERSION} ") 40 | print("---------------------------") 41 | 42 | 43 | def play_game(player_1, player_2): 44 | wins = {player_1: 0, player_2: 0} 45 | roll_names = list(rolls.keys()) 46 | 47 | while not find_winner(wins, wins.keys()): 48 | roll1 = get_roll(player_1, roll_names) 49 | roll2 = get_computer_roll(roll_names) 50 | 51 | if not roll1: 52 | print("Try again!") 53 | continue 54 | 55 | print(f"{player_1} roll {roll1}") 56 | print(f"{player_2} rolls {roll2}") 57 | 58 | winner = check_for_winning_throw(player_1, player_2, roll1, roll2) 59 | 60 | if winner is None: 61 | print("This round was a tie!") 62 | else: 63 | print(f'{winner} takes the round!') 64 | wins[winner] += 1 65 | 66 | # print(f"Current win status: {wins}") 67 | 68 | print(f"Score is {player_1}: {wins[player_1]} and {player_2}: {wins[player_2]}.") 69 | print() 70 | 71 | overall_winner = find_winner(wins, wins.keys()) 72 | print(f"{overall_winner} wins the game!") 73 | 74 | 75 | def get_computer_roll(roll_names): 76 | names = roll_names + 2*[r for r in roll_names if r.startswith('s')] 77 | roll2 = random.choice(names) 78 | return roll2 79 | 80 | 81 | def find_winner(wins, names): 82 | best_of = 3 83 | for name in names: 84 | if wins.get(name, 0) >= best_of: 85 | return name 86 | 87 | print("No winner yet, keep playing!") 88 | return None 89 | 90 | 91 | def check_for_winning_throw(player_1, player_2, roll1, roll2): 92 | winner = None 93 | if roll1 == roll2: 94 | print("The play was tied!") 95 | 96 | outcome = rolls.get(roll1, {}) 97 | if roll2 in outcome.get('defeats', ''): 98 | return player_1 99 | elif roll2 in outcome.get('defeated_by', ''): 100 | return player_2 101 | 102 | return winner 103 | 104 | 105 | def get_roll(player_name, roll_names): 106 | print("Available rolls:") 107 | for index, r in enumerate(roll_names, start=1): 108 | print(f"{index}. {r}") 109 | 110 | text = input(f"{player_name}, what is your roll? ") 111 | selected_index = int(text) - 1 112 | 113 | if selected_index < 0 or selected_index >= len(rolls): 114 | print(f"Sorry {player_name}, {text} is out of bounds!") 115 | return None 116 | 117 | return roll_names[selected_index] 118 | 119 | 120 | if __name__ == '__main__': 121 | main() 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Up and Running with Git: A pragmatic, UI-based approach](https://training.talkpython.fm/courses/up-and-running-with-git-a-pragmatic-ui-based-introduction) 2 | 3 | [![](./readme_resources/pragmatic-git.png)](https://training.talkpython.fm/courses/up-and-running-with-git-a-pragmatic-ui-based-introduction) 4 | 5 | See **[the course page](https://training.talkpython.fm/courses/up-and-running-with-git-a-pragmatic-ui-based-introduction)** for details and overview video. 6 | 7 | # Featured repositories 8 | 9 | We created several repositories during the course. We've made them public and you can access them here: 10 | 11 | * **[github.com/mikeckennedy/funny-web](https://github.com/mikeckennedy/funny-web)** 12 | * **[github.com/mikeckennedy/sketchy-rock-paper-scissors](https://github.com/mikeckennedy/sketchy-rock-paper-scissors)** 13 | 14 | ## Course Summary 15 | 16 | This course takes an unconventional and pragmatic approach to git and source control and will get you up to speed very quickly. Many git courses take a least common denominator approach and decide you need to learn "pure" git. That is, just the commands right in the terminal or command prompt. 17 | 18 | Not **Up and Running with Git**. This course teaches you how to use git by leveraging the best UI tools from common editors such as Visual Studio Code and PyCharm as well as highly polished git applications including Atlassian's Sourcetree. 19 | 20 | ## What will you learn? 21 | 22 | In this course, you will: 23 | 24 | - How modern git-oriented editors and applications can **level up your understanding of your git repository** 25 | - **The 6 core git concepts** you need to understand to be effective with git (yes, just 6!) 26 | - Gain a clear understanding of what **distributed source control** is and how to visualize it 27 | - Work with source control using the **most popular editors**: PyCharm and Visual Studio Code 28 | - **Create a new open source project** with git and GitHub 29 | - Commit and **track core files** from your project, while **excluding files that don't belong** in source control 30 | - **Synchronize with remote** / hosted repositories 31 | - Merge file changes automatically and **manually using 3-way merge tools** 32 | - Learn about the **advantages of branching** for parallel work 33 | - Understand **the 5 key reasons for branching** and how they are similar and different 34 | - Tips and techniques for **limiting merge conflicts across branches** over time 35 | - Use **GitFlow and PRs** to make (and receive) an open source contribution 36 | - Many **tips and tricks for improving your computer** for working with git 37 | - And lots more 38 | 39 | ## Who is this course for? 40 | 41 | For anyone who needs to **get better using git and source control**. If you are brand new to git, the pragmatic and UI-based approach will help you get up to speed faster. And if you are an experienced developer, you'll see how choosing the right tools will multiply your productivity and insight into your code. 42 | 43 | As for prerequisites, we assume: 44 | 45 | - **No git or source control experience** required 46 | - Familiarity with some programming language (we use Python but just a little) 47 | 48 | The tools chosen and featured during this course are **100% free and most of them are open source**. 49 | 50 | ## The time to act is now 51 | 52 | Git has become the defacto way we build software. If you are not up to speed with git and source control, you'll be at a disadvantage. This course is focused on using the best tools to provide a deep and meaningful understanding of git. **[Take the course](https://training.talkpython.fm/courses/up-and-running-with-git-a-pragmatic-ui-based-introduction), level up your productivity today**. 53 | 54 | --------------------------------------------------------------------------------