├── .gitignore ├── 0. INSTALL HELP & AN INTRODUCTION TO JUPYTER NOTEBOOK.ipynb ├── A Beginners Guide to Python ├── 00. Project progress.ipynb ├── 01. Introduction.ipynb ├── 02. Guide FAQ.ipynb ├── 03. Hello World!.ipynb ├── 04. Comments.ipynb ├── 05. Variables & Assignment.ipynb ├── 06. Variable Names.ipynb ├── 07.1 Philosophy, Part One.ipynb ├── 07.2. Philosophy, Part Two.ipynb ├── 08. Calling Functions.ipynb ├── 09.1 Numbers, Part One.ipynb ├── 09.2 Numbers, Part Two.ipynb ├── 10. Strings.ipynb ├── 11. On the Importance of Errors (oh, and Operator Overloading).ipynb ├── 12. An Intuition for OOP.ipynb ├── 13. Strings & Methods.ipynb ├── 14. Lists.ipynb ├── 15. Indexing & Slicing.ipynb ├── 16. Sorting.ipynb ├── 17. If, else, Logic, and Laziness.ipynb ├── 18. Indentation.ipynb ├── 19. For-Loops.ipynb ├── 20. Functions & Namespaces.ipynb ├── 21. The joy of fast cars.ipynb ├── 22. Common Error Messages.ipynb ├── 23. Try & Except.ipynb ├── 24. Getting Help.ipynb ├── 25. Introduction to Testing.ipynb ├── 26. Design Decisions, How to Build Chess Game.ipynb ├── 27. Final Project, An Introduction.ipynb ├── 28. Conclusion.ipynb ├── Final Project (Minesweeper) │ ├── 01 Building the Board.ipynb │ ├── 02. Printing the board.ipynb │ ├── 03. Defining Helper Functions.ipynb │ ├── 04. Getting the Neighbours.ipynb │ ├── 06. Revealing Squares.ipynb │ ├── 07. Lets Play!.ipynb │ ├── _01. Building the Board (HW).ipynb │ ├── _02. Printing the Board(HW).ipynb │ ├── _03. Defining Helper Functions(HW).ipynb │ ├── _04. Getting the Neighbours(HW).ipynb │ ├── _06. Revealing Squares(HW).ipynb │ └── _07. My Solution (explanation).ipynb ├── Graphics │ ├── BugTime.png │ ├── Errordebug.png │ ├── Google It.png │ ├── IndexPic.png │ ├── Truth_table_for_AND,_OR,_and_NOT.png │ ├── indentguide.png │ └── indentguide2.png ├── Homework Solutions │ ├── .ipynb_checkpoints │ │ └── 08. Calling Functions (HW)-checkpoint.ipynb │ ├── 03. Hello World (HW).ipynb │ ├── 05. Assignment (HW).ipynb │ ├── 06. Names (HW).ipynb │ ├── 08. Calling Functions (HW).ipynb │ ├── 10. Strings (HW).ipynb │ ├── 13. Strings & Methods (HW 1).ipynb │ ├── 13. Strings & Methods (HW 2).ipynb │ ├── 17. If, else, Logic (HW).ipynb │ ├── 18. Indentation (HW).ipynb │ ├── 19. For Loops (HW).ipynb │ ├── 20. Functions (HW).ipynb │ ├── 21. The Joy of Fast Cars (HW).ipynb │ └── 24. Getting Help (HW).ipynb └── misc │ ├── minesweeper.py │ └── profile_code.py ├── CONTRIBUTING.md ├── Graphics Folder for Install Lecture ├── Editing Mode.png ├── Reading Mode.png ├── Run Button.png ├── Running Code.png └── download help.png ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *-checkpoint.ipynb 2 | A Beginners Guide to Python/misc/__pycache__/profile_code.cpython-37.pyc 3 | A Beginners Guide to Python/misc/__pycache__/minesweeper.cpython-37.pyc 4 | -------------------------------------------------------------------------------- /0. INSTALL HELP & AN INTRODUCTION TO JUPYTER NOTEBOOK.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": {}, 5 | "cell_type": "markdown", 6 | "metadata": {}, 7 | "source": [ 8 | "Hi guys, this lecture is about:\n", 9 | "\n", 10 | "1. Downloading the guide\n", 11 | "1. Installing Jupyter Notebook\n", 12 | "1. A quick overview of how to use the Notebook\n", 13 | "\n", 14 | "## Downloading the Guide\n", 15 | "\n", 16 | "If you have never used Github before that’s okay. Basically its just a website people use to share code. What you need to do is download the guide (which should be less than 10MB) from Github. You should find a big green button somewhere in the middle-right of the screen. The picture below should help you locate it. \n", 17 | "\n", 18 | "Talking of pictures, if you happen to be reading the main guide and an image fails to load you should be able to find it in the *graphics* folder.\n", 19 | "\n", 20 | "![download%20help.png](Graphics%20Folder%20for%20Install%20Lecture/download%20help.png)\n", 21 | "\n", 22 | "\n", 23 | "## Installing Juypter Notebook\n", 24 | "\n", 25 | "The official instructions for installing the notebook can be found here: http://jupyter.org/install.html \n", 26 | "\n", 27 | "This should take you through the process. If you know what 'PIP' is installing the Notebook can be as simple as typing (at the command line):\n", 28 | "\n", 29 | " pip3 install jupyter \n", 30 | "\n", 31 | "I would go into more detail, but I run Linux as an operating system and so I can't really help windows users *(and if Linux users need more help than this they probably shouldn't be running Linux!)*\n", 32 | "\n", 33 | "## How to use the Notebook\n", 34 | "\n", 35 | "An official introduction to Juypter can be found here: https://jupyter.readthedocs.io/en/latest/running.html#running\n", 36 | "\n", 37 | "To get started, go to the command line and type:\n", 38 | "\n", 39 | " jupyter notebook\n", 40 | " \n", 41 | "This should start a session in your browser. Simply find the directory where you saved my guide and open up the lectures. And voilà! You are ready to rock and roll.\n", 42 | "\n", 43 | "## Editing Mode\n", 44 | "\n", 45 | "Now, Jupyter notebook has two basic modes, and 'editing' mode and a 'reading' mode. So, if you are in 'editing mode' right now you should see something like this:\n", 46 | "\n", 47 | "![Editing%20Mode.png](Graphics%20Folder%20for%20Install%20Lecture/Editing%20Mode.png)\n", 48 | "\n", 49 | "## Reading Mode\n", 50 | "\n", 51 | "Whereas, if you are currently in reading mode you should see something more like this:\n", 52 | "\n", 53 | "![Reading%20Mode.png](Graphics%20Folder%20for%20Install%20Lecture/Reading%20Mode.png)\n", 54 | "\n", 55 | "If you are currently in reading mode then you should be able to double-click on the 'cell' (the text box) and that should take you to editing mode. Conversely, if you are in editing mode and you want to read simply go to the top menu, click 'cell' and select 'run all'. Or alternately, you can just hit the play button which I've highlighted yellow in the picture below:\n", 56 | "\n", 57 | "![Run%20Button.png](Graphics%20Folder%20for%20Install%20Lecture/Run%20Button.png)\n", 58 | "\n", 59 | "## Code & Test Windows\n", 60 | "\n", 61 | "In addition to the Notebook having two basic modes (reading, editing), Notebook also has two types of cells; text cells that support markdown and are designed to display, yes you've guess it, text. Code cells meanwhile allow us to run Python code. \n", 62 | "\n", 63 | "Below this text cell I have a code cell, it has the simple sum 7 + 7 in it. If we run it, notice the number 14 is printed directly below the cell." 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 2, 69 | "metadata": {}, 70 | "outputs": [ 71 | { 72 | "data": { 73 | "text/plain": [ 74 | "14" 75 | ] 76 | }, 77 | "execution_count": 2, 78 | "metadata": {}, 79 | "output_type": "execute_result" 80 | } 81 | ], 82 | "source": [ 83 | "7 + 7" 84 | ] 85 | }, 86 | { 87 | "attachments": { 88 | "Running%20Code.png": { 89 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAMsAAABECAYAAAAvHcE+AAAHgklEQVR4nO2db2gTdxjH864v55uyFyuCCr7whSu+EIRJZaVQkXRlBQWxexMZVYsOpXROypwbrhRmqVDRyUiJuEqrhcpYdLRVS+yKVdItLV69cl0abRZtaJp2TRMTv3uRpLb5e3f53V1yeT7wfdHkLr/L3fPhnt8luRpAEIQoDFpvAEEUCiQLQYiEZGGI3+/HxMQE7HY7RYchWRgyMTEBn8+HQCBA0WFIFobY7XbNDyiFZCkISBZ9h2RhCMmi75AsDCFZ9B2ShSEki75DsjCEZNF3SBaGkCz6ToHL4kPHITPKK8wor+hHv1fKumHYmuLrWvCVPZzz1pAs+o5CsoQx1mSJFeL69MMqqaCzEZWltn8p+Sknh5amfuyvio5dPxhM/RLBlzCpIcu8BTtbDTCkyN4Jt/IHW+vxdRDFziyrbh84/jWGfryF8qo/0D/pBccvwc90lPSyrPKTaPnpKXqsT1GbD7IE3OBmRzG6LvdHdsPQuheWeWkH7fW1MB4cfYs5n5T12I1frFG8DROu9aL8wEP8taFWgxg6Zsbupr/Rca4Pn1SYUV7Vh5bBFYmvnuHMsjbUS5hykGV1aQVvvEGsitgaaW3YDCw3SlDS0w+3xIPmOvEOPVsjmPbkcvDlj1+s0VSW8oo+tNlXAITB3exD+YFBjKWp6dQoLUsYtlPi50OSZPG0YWfrBzjCL0g+aExkyWH8Yo22shwT8Cb+kHsStRW9+MUp5dULV5bxgc0wXG7E6JK45b3dYQzXh/GgPox7HwM9W9/h90PRvx+cCOFfSS2Z9PEpWrdh59zv2xsvh4MVt9DGS5k7KN+GSUG0LEsPceSSAZuHx0UfqLmv36FnK9IkDKcUWWSMT9Falu+KUxb38yqUtO7EZZltVK5tWK7jF2tIFhET/FfuFYYT/Bn83GWA4YYFMzIPWm6y5D5+sUajS8cqyBJcgcB7wU1O4mCFGbU33eB4LwRvwuurPWfxtGF7awmMz+V/tpGTLAzGL9Zo9KGkCrI4n2J/0vhm7L/m27icqrIsYPTehzBcOoL7mkystR6/sKOLr7tkbMOyocUEn1KQ0YUs0bPGbzK+GxY/+91EM8lC0bcs+QXJou+QLAwhWfQdkoUhJIu+Q7IwhGTRd0gWhpAs+g7JwhCSRd8hWRhCsug7JAtDxsfH6V7HOg7JwhC/3w+Hw6H53d4pdBf9IiIEQABgB/AIwN0MsQIYATAFYFGLjS0aSBZVWES0mEcQLe71xf4o9vgIgAFkFiNbrEiWi2RiBcmiOAKSBdEq1tj2EHIgWRRlDNoLkipjSr5p3UKy5ESm9irfQ2cYqZAsssmn9kpuS0ZzGCmQLLLI1/ZKaqZY7xhdQ7JIRoD2Rc4qjxnvG31T4LK8wOvDpeAqS8FV7oNP0i8lA1hujq9bhpfjARHrLKKwW6/EWKXssKJHQVmc8Hd+Br46WpD8l43wOcUU5Dq83Zip3AE3n269qCzC3RS3sXSaMde8D9Ox8f8Z8iUvAwDBQThFyzIF2YXpOo72b7fA9LkBRqMBZ4a70yzbDUfnJhiNBpy0WuSPJzqEWBSSJYDA9V3gKvfAPTSGAD+I+dNl4Goa8Z+Ue0vkIEuEv4q59gtYuHcBAjNZHkNuUYaEo2jvrIN1oA4NGWRZfvYpTKbtqCdZ8g5lZAmOYa6mFHz7GCLxx9xXIVSWYtbmA+CDv7EUU9/b3j/vNWOmcgc8fGBtWS4pia1WhjPL2rYMwpmDLJElD956fbHtZNCChc7jbDpZls+jzbQFvdw3+FY1WWbT7ztiA8rIEit2p21dgcYF6nQgkk2WtcdyaMPWxs1FlgCWT6+XVElZLPjzh01o6OpAKHReRVkG0u87YgOKyBLhz4FPKsBoYU+12ApYFvltWDZZFoZ3ob6hDkIouox6stwFfUApDpJFrQl+Jlk8p3D20EfoEu6sLaOuLHYR752gNkySLAwuHaeQJfRsF4xGQ+qcPA6P4rI8EvHeCY0m+AEsN5dhqnlw7fno2SiVLNswN6mdLJElD0Juz/v3keuHkqnOLCELPK4rcMUjHMcZowENXRfh8qS7xMw6RDZUuXS8muLScej2HnA1X8DvBRB0YrFlG7hEWYI2vKopxXSnDW+DAUSS/mtEBlmCHqzyDgQmr2KmshTCrzYEeAdWvQlSSJqzxHkC6ZJY4BI6IHBHcdJoQEPvRQhCB1wLd1Isq3YbRrKIQdkPJdurwccu+75I/FAy6MD86R3R5w5XY+72OQiJsgAIDTVipkbGpWPnBUynuPw8ff3FxuVkyQJI/iKlqw6mFG2WqetK8rIkS16ii6+7ZGzDsiFpzpJIrr9szKcQ2dCFLNGzRrWM74aVxdbdhleSZZmF9gVOsqhJgcuiJTLmLXkdIhski2yy3XWl0EJkg2SRjdbFTbKoDckiG62Lm2RRG5JFNloXN8vQj8DEQLLIRusCZxn6ebEYSBbZaF3gLEM3rhADySIbrQucVeiWSGIhWWSjdZHTWUVtSBbZaF3krBJivWN0C8kiG62LnEXoJ8VSIFlko3Whs8gT5ntFz5AsstG60FmE7uwihf8BN6BDi1idJmkAAAAASUVORK5CYII=" 90 | } 91 | }, 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "So, you should see something like this:\n", 96 | "\n", 97 | "![Running%20Code.png](attachment:Running%20Code.png)\n", 98 | "\n", 99 | "Okay cool, so now what I want you to do is go into editing mode (just click on the box) and delete the number 7 and type 3 instead. Now try running it. The number 10 should be seen directly below cell.\n", 100 | "\n", 101 | "Congratulations! You have just learnt how to add numbers together in Python! As you work through my guide I would highly recommend tinkering with the code I provide, by changing different pieces and checking what happens is a really nice way to learn the material. In my mind the ability to play with code on the fly makes this medium much better than something like an ebook or a 'pdf' file. \n", 102 | "\n", 103 | "## Homework Assignment\n", 104 | "\n", 105 | "For your homework, I want you to have a 'play' with the code cell below. Try different numbers and a few different symbols ( +-\\*/ ) and see what happens. We will learn what all this stuff does in the numbers lecture, but for now the main purpose of this exercise it getting you familiar with editing and running code within Jupyter notebook. " 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "metadata": { 112 | "collapsed": true 113 | }, 114 | "outputs": [], 115 | "source": [] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 3", 121 | "language": "python", 122 | "name": "python3" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 3 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython3", 134 | "version": "3.7.4" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 2 139 | } 140 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/00. Project progress.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# CONTENTS " 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Lectures\n", 15 | "\n", 16 | "1. Introduction\n", 17 | "1. Guide FAQ\n", 18 | "1. Hello World! \n", 19 | "1. Comments\n", 20 | "1. Variables & Assignment\n", 21 | "1. Variable Names\n", 22 | "1. Philosophy\n", 23 | "1. Calling Functions\n", 24 | "1. Numbers\n", 25 | "1. Strings\n", 26 | "1. On the Importance of Errors (oh, and Operator Overloading)\n", 27 | "1. An Intuition for OOP\n", 28 | "1. Strings & methods \n", 29 | "1. Lists\n", 30 | "1. Indexing & Slicing\n", 31 | "1. Sorting\n", 32 | "1. If, else, Logic, and Laziness\n", 33 | "1. Indentation\n", 34 | "1. For-Loops\n", 35 | "1. Functions & Namespaces\n", 36 | "1. The Joy of Fast Cars\n", 37 | "1. Common Error Messages\n", 38 | "1. Try / Except\n", 39 | "1. Getting Help\n", 40 | "1. Introduction to Testing\n", 41 | "1. Design Decisions: How to Build a Chess Game\n", 42 | "1. Final Project: An Introduction\n", 43 | "1. Conclusion \n", 44 | "1. Updates & Acknowledgements" 45 | ] 46 | } 47 | ], 48 | "metadata": { 49 | "kernelspec": { 50 | "display_name": "Python 3", 51 | "language": "python", 52 | "name": "python3" 53 | }, 54 | "language_info": { 55 | "codemirror_mode": { 56 | "name": "ipython", 57 | "version": 3 58 | }, 59 | "file_extension": ".py", 60 | "mimetype": "text/x-python", 61 | "name": "python", 62 | "nbconvert_exporter": "python", 63 | "pygments_lexer": "ipython3", 64 | "version": "3.7.4" 65 | } 66 | }, 67 | "nbformat": 4, 68 | "nbformat_minor": 2 69 | } 70 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/02. Guide FAQ.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Guide FAQ\n", 8 | "\n", 9 | "Hi guys, in this lecture I’m going to elaborate a little bit more on the nature of this course, an ‘FAQ’ of sorts. \n", 10 | "\n", 11 | "## “Why doesn’t this guide cover sets, dicts, tuples?”\n", 12 | "\n", 13 | "I’ve left out lots of things for a variety of reasons, the main three reasons being:\n", 14 | "\n", 15 | "1. I do not have an infinite amount of time to spend on this project.\n", 16 | "1. Syntax discussion is, though necessary, really boring to teach.\n", 17 | "1. You must learn to think for yourselves!\n", 18 | "\n", 19 | "Every time I increase the ‘scope’ of this project ‘quality’ is going to suffer; more lectures means more typos and bugs to catch with less time (per lecture) to catch them in! \n", 20 | "\n", 21 | "And then there is the third (and most important) point; programming is about *self-learning* as opposed to being *spoon-fed* material. On numerous occasions throughout this guide I will encourage you to learn for yourselves, my job is to give you a set of tools to teach yourself with!\n", 22 | "\n", 23 | "In short, this guide was never intended to be fully comprehensive and if you find yourself wanting to know how ‘X’ works (e.g. Sets, Tuples, Dicts) then the answer is merely a google away. \n", 24 | "\n", 25 | "## “What is the 'Zen of Python' and why should I care?”" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 1, 31 | "metadata": {}, 32 | "outputs": [ 33 | { 34 | "name": "stdout", 35 | "output_type": "stream", 36 | "text": [ 37 | "The Zen of Python, by Tim Peters\n", 38 | "\n", 39 | "Beautiful is better than ugly.\n", 40 | "Explicit is better than implicit.\n", 41 | "Simple is better than complex.\n", 42 | "Complex is better than complicated.\n", 43 | "Flat is better than nested.\n", 44 | "Sparse is better than dense.\n", 45 | "Readability counts.\n", 46 | "Special cases aren't special enough to break the rules.\n", 47 | "Although practicality beats purity.\n", 48 | "Errors should never pass silently.\n", 49 | "Unless explicitly silenced.\n", 50 | "In the face of ambiguity, refuse the temptation to guess.\n", 51 | "There should be one-- and preferably only one --obvious way to do it.\n", 52 | "Although that way may not be obvious at first unless you're Dutch.\n", 53 | "Now is better than never.\n", 54 | "Although never is often better than *right* now.\n", 55 | "If the implementation is hard to explain, it's a bad idea.\n", 56 | "If the implementation is easy to explain, it may be a good idea.\n", 57 | "Namespaces are one honking great idea -- let's do more of those!\n" 58 | ] 59 | } 60 | ], 61 | "source": [ 62 | "import this" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "The Zen of Python is a poem by Tim Peters, each line of which expresses something fundamental about the nature/design of Python. When I started to write this guide from very early on I knew I wanted to teach more than just syntax (anyone can do that), I wanted to write a guide that also instilled some of Python’s philosophy and ethos, without the discussion turning into abstract/pretentious drivel. Such discussion also had to be suitable for beginners as well. \n", 70 | "\n", 71 | "In the end, I felt that the covering the ‘Zen of Python’ helps achieve these aims succinctly. By the end of this guide you should be able to understand most of what Tim Peter’s was waffling on about!\n", 72 | "\n", 73 | "## “This guide is really good, can I use it?”\n", 74 | "\n", 75 | "I’m pretty much okay with anyone taking this body of work and doing whatever they want with it *(that’s why I released it with an “MIT” license)*. So long as you give credit and don’t try to sell it for a profit it I don’t really care what you do. \n", 76 | "\n", 77 | "## “This guide sucks, this is wrong, that is wrong …”\n", 78 | "\n", 79 | "Then please give me your suggestions for improvement. :)\n", 80 | "\n", 81 | "\n", 82 | "## \"Why did you write this guide?\"\n", 83 | "\n", 84 | "Why? Why anything?\n", 85 | "\n", 86 | "I guess there are two main reasons why I started this guide:\n", 87 | "\n", 88 | "1. I enjoy teaching\n", 89 | "1. I thought a big shiny project on Github might get me a job.\n", 90 | "\n", 91 | "Personally I've been trying to get an entry level software job for about six months now, 40 applications a month and only two telephone interviews to show for it. I guess being a 29 year old dude with no relevant experience (or a computer science degree) probably means my CV doesn't really get past the *\"HR filter\"*. \n", 92 | "\n", 93 | "When I started writing this guide I did so with the hope that maybe-- just maybe-- it would help get me a foot in the door, so to speak. Time will tell I guess.\n", 94 | "\n", 95 | "### UPDATE JAN 2020 \n", 96 | "\n", 97 | "I wrote the paragraph above just about three years ago. I kindof abandoned this guide and have only recently come back to it. \n", 98 | "\n", 99 | "Its perhaps worth pointing out that I did in fact end up landing a junior developer job at a small medical start-up writing mostly C# and Python. So now that I am older and wiser I've decided to update this guide to better reflect how I feel about code nowadays.\n", 100 | "\n", 101 | "Anyway, I think I can say with hindsight that writing this guide probably wasn't the best use of my time; I had this idea that it would be a cool project to show potential employers what I could do, but I don't think they cared, or even looked at it. I probably would have been better off solving algorithms puzzles all day. Oh well, we live and we learn." 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [] 110 | } 111 | ], 112 | "metadata": { 113 | "kernelspec": { 114 | "display_name": "Python 3", 115 | "language": "python", 116 | "name": "python3" 117 | }, 118 | "language_info": { 119 | "codemirror_mode": { 120 | "name": "ipython", 121 | "version": 3 122 | }, 123 | "file_extension": ".py", 124 | "mimetype": "text/x-python", 125 | "name": "python", 126 | "nbconvert_exporter": "python", 127 | "pygments_lexer": "ipython3", 128 | "version": "3.7.4" 129 | } 130 | }, 131 | "nbformat": 4, 132 | "nbformat_minor": 2 133 | } 134 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/03. Hello World!.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Hello World!\n", 8 | "\n", 9 | "In this lecture, we shall be focusing on Python's print statement. As the word ‘print’ may suggest, this a command in Python that, err, prints to the console whatever you fed it as input. The syntax is:\n", 10 | " \n", 11 | " print({argument})\n", 12 | "\n", 13 | "Please take care to note that \"print\" is all lower-case (**Python is case-sensitive**). And don't forget the curly brackets! \"()\" \n", 14 | "\n", 15 | "As a quick side-node, if you see python code on the internet you may occassionaly see print statements without brackets:\n", 16 | "\n", 17 | " print \"hello\"\n", 18 | " print (\"hello\")\n", 19 | " \n", 20 | "The most likely explanation of this difference is that the print statement used to work differently in Python 2. In Python 3, you need the brackets. \n", 21 | "\n", 22 | "### How I present Syntax\n", 23 | "\n", 24 | "Before moving on, I’d like to make quick note about how I talk about syntax in Python. In the lectures where I chose to talk about syntax I use the format above. With the exception of the “{}” symbols, you should assume that **all the the symbols/words are deliberate.** In other words if you see a symbol such as comma (“,”), a colon (“:”) or whatever its there because Python needs it to be there! \n", 25 | "\n", 26 | "The exception to this rule is text sandwiched between the “{}” brackets. This is usually 'place-holder' text that you would need to change.\n", 27 | "\n", 28 | "In this particular case you should remove {argument} and replace with whatever you want to print. Lets run through a few examples:" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 5, 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "name": "stdout", 38 | "output_type": "stream", 39 | "text": [ 40 | "hi\n", 41 | "8\n", 42 | "[1, 2, 3]\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "print(\"hi\")\n", 48 | "print(4 + 4)\n", 49 | "print([1, 2, 3])" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "In the above case don't worry about *what* is going on, rather, I just want you to focus on the *how* we did it. The steps we took were: \n", 57 | "\n", 58 | "1. Type \"print\"\n", 59 | "1. Open bracket\n", 60 | "1. Type in the 'thing' we want to print\n", 61 | "1. Close bracket\n", 62 | "1. Hit the run button. \n", 63 | "\n", 64 | "When learning programming languages a long-standing tradition has it that the first program you write is \"hello world\" and who am I to break [tradition](https://blog.hackerrank.com/the-history-of-hello-world/)? \n", 65 | "\n", 66 | "\n", 67 | "### What are \"Strings\" ?\n", 68 | "\n", 69 | "In Python text is handled by something we call a **“string”**. Strings are an important data-type in Python and later on in this course we shall devote a good deal of time to understanding how they work. But for now, let's just focus on the syntax and how we can print hello word. The Syntax:\n", 70 | "\n", 71 | " \"{argument}\"" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 6, 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "data": { 81 | "text/plain": [ 82 | "'THIS IS A STRING'" 83 | ] 84 | }, 85 | "execution_count": 6, 86 | "metadata": {}, 87 | "output_type": "execute_result" 88 | } 89 | ], 90 | "source": [ 91 | "\"THIS IS A STRING\"" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "Yep, thats right, strings have a very simple syntax; to convert normal english text into a Python string all we have to do is surround it in quotation marks (\"\"). Okay we have all the tools we need, now lets give 'hello word' a go!" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 7, 104 | "metadata": {}, 105 | "outputs": [ 106 | { 107 | "name": "stdout", 108 | "output_type": "stream", 109 | "text": [ 110 | "hello World\n" 111 | ] 112 | } 113 | ], 114 | "source": [ 115 | "print(\"hello World\")" 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "### Errors happen...\n", 123 | "\n", 124 | "In later lectures I’ll go into a lot more detail about error messages. But for now I just want to point out that the computer is ultimately *stupid*; it cannot figure out what your *intentions* are and as a result the computer will interpret everything 100% literally and will complain whenever you get anything (even very small things) wrong. \n", 125 | "\n", 126 | "**As you learn to program you will see error messages a lot**. But, on the brightside error messages usually tell you *what is wrong*. Thus, a key skill to develop is understanding what various errors mean and how to fix them. \n", 127 | "\n", 128 | "For example:" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 1, 134 | "metadata": {}, 135 | "outputs": [ 136 | { 137 | "ename": "NameError", 138 | "evalue": "name 'Print' is not defined", 139 | "output_type": "error", 140 | "traceback": [ 141 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 142 | "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", 143 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mPrint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"this is a string!\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 144 | "\u001b[1;31mNameError\u001b[0m: name 'Print' is not defined" 145 | ] 146 | } 147 | ], 148 | "source": [ 149 | "Print(\"this is a string!\")" 150 | ] 151 | }, 152 | { 153 | "cell_type": "markdown", 154 | "metadata": {}, 155 | "source": [ 156 | "In the example above we tried to print a string and we got the following error message:\n", 157 | "\n", 158 | "* NameError: name 'Print' is not defined\n", 159 | "\n", 160 | "Why did this happen? Well, Python is complaining here because “Print” and “print” are not the same thing. Remember what I said about the computer being stupid? The computer cannot figure out our intentions nor can it figure out what is meant via contextual cues. Basically, everything we type must be **exact** and Python is case-sensitive.\n", 161 | "\n", 162 | "Okay, lets look at one more type of error we may encounter:" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 2, 168 | "metadata": {}, 169 | "outputs": [ 170 | { 171 | "ename": "SyntaxError", 172 | "evalue": "unexpected EOF while parsing (, line 1)", 173 | "output_type": "error", 174 | "traceback": [ 175 | "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m print(\"this is a string\"\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m unexpected EOF while parsing\n" 176 | ] 177 | } 178 | ], 179 | "source": [ 180 | "print(\"this is a string\"" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 3, 186 | "metadata": {}, 187 | "outputs": [ 188 | { 189 | "ename": "SyntaxError", 190 | "evalue": "EOL while scanning string literal (, line 1)", 191 | "output_type": "error", 192 | "traceback": [ 193 | "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m print(\"this is a string)\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m EOL while scanning string literal\n" 194 | ] 195 | } 196 | ], 197 | "source": [ 198 | "print(\"this is a string)" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 4, 204 | "metadata": {}, 205 | "outputs": [ 206 | { 207 | "ename": "SyntaxError", 208 | "evalue": "invalid syntax (, line 1)", 209 | "output_type": "error", 210 | "traceback": [ 211 | "\u001b[1;36m File \u001b[1;32m\"\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m print(\"this is a string\"))\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n" 212 | ] 213 | } 214 | ], 215 | "source": [ 216 | "print(\"this is a string\"))" 217 | ] 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "So what happened here then? Well in the first case we are missing a closing bracket and in the second example we are missing a quotation mark, and in the third example we have one too many closing brackets. The result is the following errors:\n", 224 | "\n", 225 | "* SyntaxError: unexpected EOF while parsing\n", 226 | "* SyntaxError: EOL while scanning string literal\n", 227 | "* SyntaxError: invalid syntax\n", 228 | "\n", 229 | "Notice that Python has a little \"^\" icon pointing out where it thinks the mistake is. \n", 230 | "\n", 231 | "When you see errors like this don’t give up! Most of the time when you see errors like this your mistake was that you missed a comma, or added an extra bracket or something. Basically, you probably just have a typo somewhere in your code.\n", 232 | "\n", 233 | "Basically, try not to get too fustrated when you see errors; its a normal part of the learning process and more often than not its something really simple. So if you are stuck I recommend taking a quick teabreak, a fresh pair of eyes will often spot the mistake a pair of tired eyes couldn't! " 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": {}, 239 | "source": [ 240 | "## Homework\n", 241 | "\n", 242 | "For your homework, I want you to print the following phrase into the box below:\n", 243 | "> MY HUMAN UNDERSTANDS ME.\n", 244 | "\n", 245 | "If you try to print that statement and it doesn't work remember about what I said about error messages; Python needs everything to be 100% correct, not 99% or 99.98% correct. So yeah, if you receive an error message what one did you get? Is it one of the ones I mention above? If so, can you figure out what the fix might be?" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": 8, 251 | "metadata": { 252 | "collapsed": true 253 | }, 254 | "outputs": [], 255 | "source": [ 256 | "# ENTER YOUR CODE BELOW THIS LINE AND HIT THE 'RUN CELL' BUTTON ABOVE.\n" 257 | ] 258 | } 259 | ], 260 | "metadata": { 261 | "kernelspec": { 262 | "display_name": "Python 3", 263 | "language": "python", 264 | "name": "python3" 265 | }, 266 | "language_info": { 267 | "codemirror_mode": { 268 | "name": "ipython", 269 | "version": 3 270 | }, 271 | "file_extension": ".py", 272 | "mimetype": "text/x-python", 273 | "name": "python", 274 | "nbconvert_exporter": "python", 275 | "pygments_lexer": "ipython3", 276 | "version": "3.7.4" 277 | } 278 | }, 279 | "nbformat": 4, 280 | "nbformat_minor": 2 281 | } 282 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/04. Comments.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Comments\n", 8 | "\n", 9 | "In the previous lecture we learnt how to print \"hello world\". Lets try to do that again. Click on the cell below and hit the 'run' button. Go on, I'll wait for you..." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 2, 15 | "metadata": { 16 | "collapsed": true 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "# print(\"Hello World)" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "Woah !? Nothing happened!? Why is that? \n", 28 | "\n", 29 | "The reason “hello world” did not get printed to the console in this case is because that line of code is *“commented out”*. Comments in Python have a very simple syntax:\n", 30 | "\n", 31 | " # {Any text we want}\n", 32 | " # {More gibberish}\n", 33 | "\n", 34 | "To use comments it is actually super easy, we just type the \"#\" character, and this will make Python ignore everything **on that line from that point on**. If we want comments to span multiple lines, then we have to remember to put a # at the start of every line. For example:" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 3, 40 | "metadata": { 41 | "collapsed": true 42 | }, 43 | "outputs": [], 44 | "source": [ 45 | "# Lots...\n", 46 | "# and lots...\n", 47 | "# of comments..." 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "You can also place comments after some code, in which case the code executes. Here, let me show you:" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 4, 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "name": "stdout", 64 | "output_type": "stream", 65 | "text": [ 66 | "this works\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "print(\"this works\") # this works because the \"#\" symbol is placed AFTER the bit of code we want to run!" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "## What are comments for?\n", 79 | "\n", 80 | "Comments have a few uses, but the main one is to communicate with other human beings (including your future self!). Helpful comments can make reading and understanding code a lot less difficult, and that's why leaving good comments is a **GREAT** idea. \n", 81 | "\n", 82 | "Here, let me show you:" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 7, 88 | "metadata": {}, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "text/plain": [ 93 | "'abcabcabcabc'" 94 | ] 95 | }, 96 | "execution_count": 7, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "\"abc\" * 4 # ??? " 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 8, 108 | "metadata": {}, 109 | "outputs": [ 110 | { 111 | "data": { 112 | "text/plain": [ 113 | "'aaa'" 114 | ] 115 | }, 116 | "execution_count": 8, 117 | "metadata": {}, 118 | "output_type": "execute_result" 119 | } 120 | ], 121 | "source": [ 122 | "\"a\" * 3 # string * number repeats the character. Thus \"a\" * 2 = \"aa\" and \"az\" * 2 = \"azaz\"." 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": {}, 128 | "source": [ 129 | "In later lectures I'll explain how multiplying strings work. But for now just notice that in the first case you didn't know what was going on (because there were no helpful comments), but you understand what is happening in the second case because the comment explains the code. \n", 130 | "\n", 131 | "Also as a quick heads up, generally speaking, if you feel you need to write comments explaining the code then this often a sign that your code isn't actually good code. Good code usually has the property that you can just tell what it is doing just by looking at it. For example:\n" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": 17, 137 | "metadata": {}, 138 | "outputs": [ 139 | { 140 | "name": "stdout", 141 | "output_type": "stream", 142 | "text": [ 143 | "8\n", 144 | "8\n" 145 | ] 146 | } 147 | ], 148 | "source": [ 149 | "print( 4 * 2 ) # Very simply and clear code, you can tell what it does just by looking at it.\n", 150 | "print( int(chr(52)).__mul__(int(chr(50))) ) # A TERRIBLE and confusing way to calculate \"4 * 2\"" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": {}, 156 | "source": [ 157 | "Complex code often requires comments to explain what it does, and that's why comments are (sort-of) bad.\n", 158 | "\n", 159 | "Make no mistake, comments are really useful and you SHOULD use them. However, it’s often a good idea to think of comments as a last-resort; only use them if you cannot think of a way to make your code less complicated. In later lectures, I'll discuss a number of techniques for writing simple code." 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "## Homework\n", 167 | "\n", 168 | "Your task for this week is to get the code in the box below to work, use your understanding of comments to fix it! " 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 3, 174 | "metadata": {}, 175 | "outputs": [], 176 | "source": [ 177 | "# print(\"\\n * ,MMM8&&&. *\\n MMMM88&&&&& .\\n MMMM88&&&&&&&\\n * MMM88&&&&&&&&\\n MMM88&&&&&&&&\\n 'MMM88&&&&&&'\\n 'MMM8&&&' *\\n |\\\\___/|\\n ) ( . '\\n =\\\\ /=\\n )===( *\\n / \\\\\\n | |\\n / \\\\\\n \\\\ /\\n _/\\\\_/\\\\_/\\\\__ _/_/\\\\_/\\\\_/\\\\_/\\\\_/\\\\_/\\\\_/\\\\_/\\\\_/\\\\_\\n | | | |( ( | | | | | | | | | |\\n | | | | ) ) | | | | | | | | | |\\n | | | |(_( | | | | | | | | | |\\n | | | | | | | | | | | | | | |\\n | | | | | | | | | | | | | | |\\n\")" 178 | ] 179 | } 180 | ], 181 | "metadata": { 182 | "kernelspec": { 183 | "display_name": "Python 3", 184 | "language": "python", 185 | "name": "python3" 186 | }, 187 | "language_info": { 188 | "codemirror_mode": { 189 | "name": "ipython", 190 | "version": 3 191 | }, 192 | "file_extension": ".py", 193 | "mimetype": "text/x-python", 194 | "name": "python", 195 | "nbconvert_exporter": "python", 196 | "pygments_lexer": "ipython3", 197 | "version": "3.7.4" 198 | } 199 | }, 200 | "nbformat": 4, 201 | "nbformat_minor": 2 202 | } 203 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/06. Variable Names.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Variable Names\n", 8 | "\n", 9 | "Before moving on, let's say a few things about variable names. If you want to *name* some object in Python you have to abide by a few 'concrete' rules:\n", 10 | "\n", 11 | "1. The name should not be already be in use (unless you want to 'delete' the previous value).\n", 12 | "1. The name should not start with a number or punctuation marks (with the notable exception of the underscore \"_\" character)\n", 13 | "1. The name cannot contain any \"special characters\" or spaces. \n", 14 | "\n", 15 | "Below are a few examples of the above three rules in action." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 1, 21 | "metadata": {}, 22 | "outputs": [ 23 | { 24 | "ename": "SyntaxError", 25 | "evalue": "invalid syntax (, line 2)", 26 | "output_type": "error", 27 | "traceback": [ 28 | "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m 0sales = 10.20 # Rule 2: cannot start a name with a number.\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" 29 | ] 30 | } 31 | ], 32 | "source": [ 33 | "print = 10.20 # Rule 1: \"print\" is a reserved word in Python and therefore we cannot use it.\n", 34 | "0sales = 10.20 # Rule 2: cannot start a name with a number.\n", 35 | "this has spaces = 10.20 # Rule 2: space character is punctation.\n", 36 | "thisnamehasa+init = 10.20 # Rule 3: Fails because \"+\" is a special character in python (addition)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "In addition to the above ‘concrete’ there are also a few *guidelines* that describe *\"best practices\"*:\n", 44 | "\n", 45 | "* Variable names should be concise yet relevant, descriptive too. \n", 46 | "* The best names are not just relevant and descriptive, there are also elegant. \n", 47 | "* The best names are easy to read and type.\n", 48 | "* Try to avoid possible confusion; \"Print\" is a legal name, but easily mistaken for the \"print\" command.\n", 49 | "* Don’t use ALL CAPS *(unless you know what you are doing).*\n", 50 | "* Don't start a name with an underscore character or double underscore *(unless you know what you are doing).* \n", 51 | "* Don't start a name with a capital letter *(unless you know what you are doing).* \n", 52 | "\n", 53 | "For the last three bullet points I said *\"unless you know what you are doing\"*, let me explain that quickly. \n", 54 | "\n", 55 | "By convention, variable names in ALLCAPS are supposed to have a special meaning, and that is these are values that should **NOT** be changed by the program at runtime. \n", 56 | "\n", 57 | "Mathematical constants are a pretty good example; for most applications you probably don't want to change these values while the program is running. For example, under what circumstances would you want to change the value of PI while the code is running?\n", 58 | "\n", 59 | "In python we denote constants by naming them in ALLCAPS, and I would recommend you follow this already agreed upon practice; after all, if everyone uses the same naming conventions then all code is that little bit easier to read. " 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": { 66 | "collapsed": true 67 | }, 68 | "outputs": [], 69 | "source": [ 70 | "golden_ratio = 1.61803398874989484820 # okay name\n", 71 | "GOLDEN_RATIO = 1.61803398874989484820 # better name" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "As for using underscores and captial letters in names, well, thats to do with classes, which I do not cover in this lecture series. All you need to know right now is that underscores and capital letters are best avoided.\n", 79 | "\n", 80 | "Anyway, here are a few more examples:" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 2, 86 | "metadata": { 87 | "collapsed": true 88 | }, 89 | "outputs": [], 90 | "source": [ 91 | "# superbad (nonsense name, mixed case, starts with underscore):\n", 92 | "_QWeRTy = 10.20\n", 93 | "# bad (still nonsense):\n", 94 | "qwerty = 10.20 \n", 95 | "# poor (descriptive, but mixed case is very annoying):\n", 96 | "SaLestAX = 10.20\n", 97 | "# better (most boxes ticked!):\n", 98 | "salestax = 10.20\n", 99 | "# even better:\n", 100 | "sales_tax = 10.20\n", 101 | "# WAAAYYYY over the top (descriptive doesn't mean \"write a novel!\")\n", 102 | "this_is_the_sales_tax_for_the_beer_I_bought_on_a_summers_day_in_1965_or_was_it_1967_I_cant_remember = 10.20 " 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "So in the above examples we saw a few terrible names and two reasonable ones. “sales_tax” is my top-pick because the name tells use something about our data and at just two words long it is concise. \n", 110 | "\n", 111 | "In C# the usual naming convention is to use snake case. So a variable in C# should be called 'salesTax'. In Python we tend to use underscores to split up words. And thats another reason why 'sales_tax' is my top-pick.\n", 112 | "\n", 113 | "**The last thing I would like to say about variable names is that very good names can negate the need for comments.** [Pep8](https://www.python.org/dev/peps/pep-0008/#inline-comments) *(the main style guideline for Python)* recommends that we use in-line comments sparingly and comments should also avoid stating the obvious; needless comments only serve as a distraction.\n", 114 | "\n", 115 | "Don't get it twisted; we **should** write comments, but they should be good ones. The real point here is that good code should explain itself. \n", 116 | "\n", 117 | "Here, let me show you can example." 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 19, 123 | "metadata": { 124 | "collapsed": true 125 | }, 126 | "outputs": [], 127 | "source": [ 128 | "price = 1000 # including sales tax" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "So this bit of code isn't actually that bad; the variable name \"price\" is a reasonably good one (short, readable, descriptive) and the comment is helpful. All in all, this code is decent, but that doesn’t mean we cannot do even better:" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 20, 141 | "metadata": { 142 | "collapsed": true 143 | }, 144 | "outputs": [], 145 | "source": [ 146 | "price_after_tax = 1000" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "All we did here is change our variable name to be a bit more descriptive. And now since our variable name states that this figure includes tax we don't need the comment!\n", 154 | "> **Show, don't tell.**\n", 155 | "\n", 156 | "The point of today was to make you aware that programming is not just about writing code that machines can understand; **Good code is understood by both man AND machine.**" 157 | ] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "metadata": {}, 162 | "source": [ 163 | "## Homework\n", 164 | "\n", 165 | "Below is three lines of python code, the only thing you have seen yet is the '*' symbol which means multiplication. The Syntax:\n", 166 | " \n", 167 | " {number}*{number}\n", 168 | "\n", 169 | "Your task comes in three parts:\n", 170 | "\n", 171 | "1. Figure out what the code is supposed to do. *(this might take some googling. Hint: think circles!)*\n", 172 | "2. Add a comment or two, explaining what it does.\n", 173 | "2. change the name \"belt_size\" and \"cake\" to something more meaningful.\n", 174 | "2. After you have renamed the variables, do you still need the comments in order to understand the code?" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": null, 180 | "metadata": { 181 | "collapsed": true 182 | }, 183 | "outputs": [], 184 | "source": [ 185 | "# WTF does this do? Place your bets now...\n", 186 | "cake = 3.14\n", 187 | "diameter = 2\n", 188 | "\n", 189 | "belt_size = cake * diameter" 190 | ] 191 | } 192 | ], 193 | "metadata": { 194 | "kernelspec": { 195 | "display_name": "Python 3", 196 | "language": "python", 197 | "name": "python3" 198 | }, 199 | "language_info": { 200 | "codemirror_mode": { 201 | "name": "ipython", 202 | "version": 3 203 | }, 204 | "file_extension": ".py", 205 | "mimetype": "text/x-python", 206 | "name": "python", 207 | "nbconvert_exporter": "python", 208 | "pygments_lexer": "ipython3", 209 | "version": "3.7.4" 210 | } 211 | }, 212 | "nbformat": 4, 213 | "nbformat_minor": 2 214 | } 215 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/07.1 Philosophy, Part One.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Philosophy, Part One\n", 8 | "\n", 9 | "In this Lecture we won't be doing much coding, but we will be taking a closer look at Pythons ideals, beliefs, and core principles. To do that, let's read a poem together..." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "The Zen of Python, by Tim Peters\n", 22 | "\n", 23 | "Beautiful is better than ugly.\n", 24 | "Explicit is better than implicit.\n", 25 | "Simple is better than complex.\n", 26 | "Complex is better than complicated.\n", 27 | "Flat is better than nested.\n", 28 | "Sparse is better than dense.\n", 29 | "Readability counts.\n", 30 | "Special cases aren't special enough to break the rules.\n", 31 | "Although practicality beats purity.\n", 32 | "Errors should never pass silently.\n", 33 | "Unless explicitly silenced.\n", 34 | "In the face of ambiguity, refuse the temptation to guess.\n", 35 | "There should be one-- and preferably only one --obvious way to do it.\n", 36 | "Although that way may not be obvious at first unless you're Dutch.\n", 37 | "Now is better than never.\n", 38 | "Although never is often better than *right* now.\n", 39 | "If the implementation is hard to explain, it's a bad idea.\n", 40 | "If the implementation is easy to explain, it may be a good idea.\n", 41 | "Namespaces are one honking great idea -- let's do more of those!\n" 42 | ] 43 | } 44 | ], 45 | "source": [ 46 | "import this" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "In the above we ran one line of code and out popped a poem, and as we go through the course more and more lines of this poem should start to make sense to you. But before all that, let's talk about 'import'.\n", 54 | "\n", 55 | "## Import\n", 56 | "\n", 57 | "The Import statement is basically us saying to the computer:\n", 58 | "\n", 59 | "> \"Hey Python, can you go fetch to other bit of code that someone else wrote? thanx mate.\"\n", 60 | "\n", 61 | "In this particular case, we are importing something called \"this\". Python has a few easter-eggs and inside jokes dotted around the place, you can read about the history of how ‘import this’ became a thing by clicking [here](https://www.wefearchange.org/2010/06/import-this-and-zen-of-python.html).\n", 62 | "\n", 63 | "Anyway, the syntax for importing code is below.\n", 64 | "\t\n", 65 | "\timport {Name of module we wish to import}\n", 66 | "\n", 67 | "Anyway, I digress; the actual focus of today's lecture is to study the meaning of two lines found within Tim Peter's poem. \n", 68 | "\n", 69 | "1. Readability counts.\n", 70 | "1. Explicit is better than Implicit.\n", 71 | "\n", 72 | "Part One will speak about readability, part two will talk about the distinction between implicit/explicit code.\n", 73 | "\n", 74 | "## Readability counts\n", 75 | "\n", 76 | "On numerous occasions throughout this course I will refer to the idea that readability matters, indeed, we have already seen the importance of good names, but readability has a much larger scope than that. Most of my lectures will focus on *how *code can made more readable, but in this lecture I want to try to explain *why* readability counts. \n", 77 | "\n", 78 | "The TLDR version:\n", 79 | "* Readability is at the heart of Python's ethos.\n", 80 | "* Everything else we care about 'flows' from readable code. \n", 81 | "\n", 82 | "The second bullet point is a bit cryptic, but once I’ve finished explaining it will make sense, I promise. \n", 83 | "\n", 84 | "Alright, let’s imagine we are trying to build the ‘perfect’ bit of software. What properties would it have? Its an abstract question, but here are a free of my ideas of what 'perfect code' would look like.\n", 85 | "\n", 86 | "* it would be performant\n", 87 | "* correct\n", 88 | "* bug free\n", 89 | "* safe (e.g no security defects that could be attacked)\n", 90 | "* easy to use (for the end-user)\n", 91 | "* easy to maintain, improve, change (for programmers)\n", 92 | "* integrates nicely with other code/infrastructure. \n", 93 | "\n", 94 | "So that’s a nice list of qualities that exemplary software would have. The interesting thing to note here is that readability helps with every single one of these bullet points. \n", 95 | "\n", 96 | "Take the first point, performance, how does readability help here? \n", 97 | "\n", 98 | "Well, imagine being handed a novel with all the pages out of order. Think about how much harder and how much more time consuming understanding that novel would be relative to being given a copy with the correct page numbers; working with messy code is very much like the disordered novel. If the code is messy the development team has to spend a lot of time just understanding how the pieces fit together, they have to do that before they can actually go about making meaningful performance improvements. The readable code meanwhile is understood in a much shorter space of time, therefore our team of hypothetical developers can thus spend more of their time and energy focused on the actual task at hand. \n", 99 | "\n", 100 | "In short, the less developers have to wonder about *how* something works, the more time they have to innervate, tinker, and toy with the code. The result (over long periods of time) is faster code with fewer bugs and more features. \n", 101 | "\n", 102 | "The lesson here is that readability isn’t a ‘nice-to-have extra’, rather, it's a core ingredient for great code. And so, when writing code I want you guys to always ask yourself the following two questions:\n", 103 | "\n", 104 | "1. Does my code work like it is supposed to? (correctness is *the* single most important thing, after all).\n", 105 | "1. Can I make my code more readable?\n", 106 | "\n", 107 | "If you keep on asking yourself these two basic questions when writing code then you'll be writing *good code* in no time at all!\n", 108 | "\n", 109 | "In short, bugs and security flaws often lurk in the shadows. So, one way to avoid these problems is to avoid the number of shadows there are in the first place. In this analogys, the shadows refer to confusing bits of code that are difficult to understand. Complexity obscures things, simplicity reveals the truth. \n", 110 | "\n", 111 | "Here's a quick attempt to show you that. " 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 5, 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "a = 7\n", 121 | "b = (False * a) + a \n", 122 | "\n", 123 | "c = a / b" 124 | ] 125 | }, 126 | { 127 | "cell_type": "markdown", 128 | "metadata": {}, 129 | "source": [ 130 | "So this code is a bit confusing. How can we simplify the code? Well, we can do this:" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": 1, 136 | "metadata": {}, 137 | "outputs": [], 138 | "source": [ 139 | "c = 1" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "In this above code snippet \"False * a number\" is actually the same as \"0 * n\", which is always zero. So 'b' is always '0 + a', which simplifies to just 'a'. And since 'a' divided by 'a' is always 1 (except when a is zero) we can actually just delete all the code and set c to 1.\n", 147 | "\n", 148 | "Complex code becomes simple. And remember, bugs hide in complexity. We can see that clearly if we set a to zero:" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 4, 154 | "metadata": {}, 155 | "outputs": [ 156 | { 157 | "ename": "ZeroDivisionError", 158 | "evalue": "division by zero", 159 | "output_type": "error", 160 | "traceback": [ 161 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 162 | "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", 163 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;32mFalse\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0ma\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0ma\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mc\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0ma\u001b[0m \u001b[1;33m/\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 164 | "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero" 165 | ] 166 | } 167 | ], 168 | "source": [ 169 | "a = 0\n", 170 | "b = (False * a) + a \n", 171 | "\n", 172 | "c = a / b" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "So, not only did simplifying the code make it easier to understand what was going on, the simplification also doesn't contain a zero division error. Its also faster. Okay, I must admit that this example was a bit contrived, but still, hopefully you get the idea; simple code is good, complex code is bad. Okay, lets look at another example:" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "**POP QUIZ!** Can you guys figure out what the following code snippet does?" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": null, 192 | "metadata": { 193 | "collapsed": true 194 | }, 195 | "outputs": [], 196 | "source": [ 197 | "def f(m, a):\n", 198 | " return m * a" 199 | ] 200 | }, 201 | { 202 | "cell_type": "markdown", 203 | "metadata": {}, 204 | "source": [ 205 | "The answer is probably no, and that's not particularly surprising since this code has two new keywords (def, return), indentation, and a few other bits of syntax we have yet to discuss. Tell you what, let's change the variable names to something better and see if you can figure it out then…" 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": null, 211 | "metadata": { 212 | "collapsed": true 213 | }, 214 | "outputs": [], 215 | "source": [ 216 | "def net_force(mass, acceleration):\n", 217 | " return mass * acceleration" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "If you have managed to figure out what this code does then I’d say I’ve proven just how useful readability can be; despite you guys not know several bits of syntax a wise choice of variable names allowed you to figure what is (probably) going on. \n", 225 | "\n", 226 | "If I were to rate it, I'd probably give this code a C+. The code seems correct, it is concise, and chose variable names wisely. However, the major drawback to this code is it doesn't use any *defensive programming* techniques and as a consequence the code may break when we give it unexpected input (the *‘operator overloading’* lecture will go into the specifics). Now, writing code without test cases or checks is acceptable in many cases, but having no tests/checks AND no documentation is just asking for trouble! Basically the problem with the above code is that it makes no effort to warn/protect from 'improper' usage. \n", 227 | "\n", 228 | "## What is Defensive Programming?\n", 229 | "\n", 230 | "Defensive programming is a style of writing code whereby you try to write code that ‘predicts’ errors and stops them from happening in the first place.\n", 231 | "\n", 232 | "> \"Prevention is better than cure\". \n", 233 | "\n", 234 | "How can we prevent problems? Well, there are hundreds upon hundreds of ways to do that, but the code snippet above doesn’t try any of them.\n", 235 | "\n", 236 | "That’s it for today, ‘Philosophy part two’ will elaborate even further about some of potential fixes to this code. Stay tuned folks! " 237 | ] 238 | } 239 | ], 240 | "metadata": { 241 | "kernelspec": { 242 | "display_name": "Python 3", 243 | "language": "python", 244 | "name": "python3" 245 | }, 246 | "language_info": { 247 | "codemirror_mode": { 248 | "name": "ipython", 249 | "version": 3 250 | }, 251 | "file_extension": ".py", 252 | "mimetype": "text/x-python", 253 | "name": "python", 254 | "nbconvert_exporter": "python", 255 | "pygments_lexer": "ipython3", 256 | "version": "3.7.4" 257 | } 258 | }, 259 | "nbformat": 4, 260 | "nbformat_minor": 2 261 | } 262 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/08. Calling Functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# How to Call Functions...\n", 8 | "\n", 9 | "\n", 10 | "### What are functions... \n", 11 | "\n", 12 | "Functions are an incredibly useful concept and I will cover them in greater detail later on, I promise. But for now let's just say functions are bits of *self-contained code* that take some input value(s), perform some process, and return some output. Today we shall be studying how to call functions, for what it's worth you guys have already called functions, you just didn't know that was what you are doing!\n", 13 | "\n", 14 | "For the sake of simplicity, we are going to split functions into four basic categories:\n", 15 | "1. Those that take zero arguments as input.\n", 16 | "2. Those that take one argument as input.\n", 17 | "3. Those that take multiple arguments as input.\n", 18 | "4. Those that take optional arguments.\n", 19 | "\n", 20 | "Before we begin though I really want to stress that these categories are ***not real***, its an arbitrary distinction that is not founded upon anything of substance.\n", 21 | "\n", 22 | "If that’s the case, why do it, then? I here you ask. Well, just because a distinction is not *real* doesn't mean it is not helpful. Basically, the reason I have made these categories is because I believe it makes the material easier to teach; a *pedagogical tool*, if you will.\n", 23 | "\n", 24 | "### 1. Zero argument functions....\n", 25 | "\n", 26 | "Calling zero argument functions are super simple, but they also tend to be rather uninteresting as well. The syntax:\n", 27 | "\n", 28 | " {function name} ()\n", 29 | " \n", 30 | "In box below I've quickly made such a function and then calling it. Boring stuff ensues." 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 1, 36 | "metadata": {}, 37 | "outputs": [ 38 | { 39 | "data": { 40 | "text/plain": [ 41 | "'ZZZZZZZZ...'" 42 | ] 43 | }, 44 | "execution_count": 1, 45 | "metadata": {}, 46 | "output_type": "execute_result" 47 | } 48 | ], 49 | "source": [ 50 | "# Defining the function...\n", 51 | "def boring():\n", 52 | " return \"ZZZZZZZZ...\"\n", 53 | "\n", 54 | "# calling said function...\n", 55 | "boring()" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "### 2. One argument functions....\n", 63 | "\n", 64 | "The syntax:\n", 65 | "\n", 66 | " {function name} ({argument})\n", 67 | " \n", 68 | "\"len\" is a Python built-in function. Let's call it on a few strings and see if you can figure out what it does. " 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 12, 74 | "metadata": { 75 | "scrolled": true 76 | }, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "1\n", 83 | "2\n", 84 | "3\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "print ( len(\"a\") )\n", 90 | "print ( len(\"aa\") )\n", 91 | "print ( len(\"aaa\") )" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "'len' is short for length. When you call it returns how big the object is, in the case of strings, that’s how many characters the string contains. Thus len(“12345”) returns 5.\n", 99 | "\n", 100 | "### 3. Functions with Multiple Arguments\n", 101 | "\n", 102 | "Functions that take multiple arguments can be further defined into those that require exactly n arguments and those functions that can handle an arbitrary number of arguments. We shall briefly cover both. The syntax:\n", 103 | "\n", 104 | " {function name} ({argument}, {argument2}) \n", 105 | "\n", 106 | "So, to call a function that takes two arguements as imput all we do is type two arguments seperated by a comma. Let's see that in action: " 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 7, 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "data": { 116 | "text/plain": [ 117 | "250" 118 | ] 119 | }, 120 | "execution_count": 7, 121 | "metadata": {}, 122 | "output_type": "execute_result" 123 | } 124 | ], 125 | "source": [ 126 | "# defining the function...\n", 127 | "def multiply(a, b):\n", 128 | " return a * b # remember '*' is multiplication!\n", 129 | "\n", 130 | "multiply(10, 25) # <-- calling the function with two arguments, 10 and 25" 131 | ] 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "What happens when you give such a function too few/too many arguments? Well, you get an error:" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": 3, 143 | "metadata": {}, 144 | "outputs": [ 145 | { 146 | "ename": "TypeError", 147 | "evalue": "multiply() takes 2 positional arguments but 3 were given", 148 | "output_type": "error", 149 | "traceback": [ 150 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 151 | "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", 152 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mmultiply\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 153 | "\u001b[1;31mTypeError\u001b[0m: multiply() takes 2 positional arguments but 3 were given" 154 | ] 155 | } 156 | ], 157 | "source": [ 158 | "multiply(2,3,4)" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 4, 164 | "metadata": {}, 165 | "outputs": [ 166 | { 167 | "ename": "TypeError", 168 | "evalue": "multiply() missing 1 required positional argument: 'b'", 169 | "output_type": "error", 170 | "traceback": [ 171 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", 172 | "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", 173 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mmultiply\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 174 | "\u001b[1;31mTypeError\u001b[0m: multiply() missing 1 required positional argument: 'b'" 175 | ] 176 | } 177 | ], 178 | "source": [ 179 | "multiply(1)" 180 | ] 181 | }, 182 | { 183 | "cell_type": "markdown", 184 | "metadata": {}, 185 | "source": [ 186 | "Take care to note that the error messages you get are actually rather insightful, Python is telling you what the problem is!\n", 187 | "\n", 188 | "#### Functions that take an aribitary number of arguments\n", 189 | "\n", 190 | "Now, the syntax for a function that takes an arbitrary number of arguments is the same as the above, you just separate the values by a comma and keep on going. As a matter of fact, we have seen such a function several times already. Its called 'print'... " 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": 6, 196 | "metadata": {}, 197 | "outputs": [ 198 | { 199 | "name": "stdout", 200 | "output_type": "stream", 201 | "text": [ 202 | "hello\n", 203 | "hello world\n", 204 | "\n", 205 | "a b c d e f g\n" 206 | ] 207 | } 208 | ], 209 | "source": [ 210 | "print(\"hello\") # calling print with one arguement\n", 211 | "print(\"hello\", \"world\") # two arguments\n", 212 | "print() # calling print with zero arguments returns an empty line.\n", 213 | "print(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\") # seven arguments" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": {}, 219 | "source": [ 220 | "### 4. Functions with optional arguments...\n", 221 | "\n", 222 | "If a particular function argument is optional is will have two parts, a 'keyword' and a 'default value'. The syntax:\n", 223 | "\n", 224 | " {keyword} = {value}\n", 225 | " \n", 226 | "The 'default value' is what happens when we *don't* change anything, and obviously that is the bit we may want to change. \n", 227 | "\n", 228 | "If you do give a function an optional argument make sure it is **the last** argument you pass the function; if you don't Python with throw and error. Anyway, here's the syntax:\n", 229 | "\n", 230 | " {function name} ({argument}, {argument2}, {keyword} = {value} ) \n", 231 | "\n", 232 | "As a matter of fact, the print function we have been calling has an optional argument, this argument is called \"sep\" and its default value is a single 'space' character. \n", 233 | "\n", 234 | "Let's look at the print calls above a bit more closely, did you notice that when we gave print several arguments it separated everything with a space? Well, we can change that behaviour by changing 'sep'. \n", 235 | "\n", 236 | "For example..." 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": 14, 242 | "metadata": {}, 243 | "outputs": [ 244 | { 245 | "name": "stdout", 246 | "output_type": "stream", 247 | "text": [ 248 | "a b c d e f g\n", 249 | "abcdefg\n", 250 | "a__b__c__d__e__f__g\n", 251 | "a,b,c,d,e,f,g\n", 252 | "a\n", 253 | "b\n", 254 | "c\n", 255 | "d\n", 256 | "e\n", 257 | "f\n", 258 | "g\n" 259 | ] 260 | } 261 | ], 262 | "source": [ 263 | "print(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\") # Notice 'sep' is not defined here. Thus the default value \" \" is used. \n", 264 | "print(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", sep=\"\") # no spaces 'abc'\n", 265 | "print(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", sep=\"__\") # double underscore, 'a__b__c' \n", 266 | "print(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", sep=\",\") # comma, 'a,b,c'\n", 267 | "print(\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", sep=\"\\n\") # \\n = New-line, please see string lecture!" 268 | ] 269 | }, 270 | { 271 | "cell_type": "code", 272 | "execution_count": 15, 273 | "metadata": {}, 274 | "outputs": [ 275 | { 276 | "ename": "SyntaxError", 277 | "evalue": "positional argument follows keyword argument (, line 1)", 278 | "output_type": "error", 279 | "traceback": [ 280 | "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print(sep=\"\", \"a\", \"b\", \"c\") # Keywords must be at the end!\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m positional argument follows keyword argument\n" 281 | ] 282 | } 283 | ], 284 | "source": [ 285 | "print(sep=\"\", \"a\", \"b\", \"c\") # Keywords must be at the end! " 286 | ] 287 | }, 288 | { 289 | "cell_type": "markdown", 290 | "metadata": {}, 291 | "source": [ 292 | "In later lectures I'll show you how to build your own functions (and why you would want to), but the purpose of this lecture was to simply get you used to seeing *function calls*. Trust me when I say understanding this stuff is a really useful skill to have moving forward." 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": {}, 298 | "source": [ 299 | "## Homework\n", 300 | "\n", 301 | "In the cell below there is a function called \"call me\". For homework I want you to call this function with several arguments such that it returns the string:\n", 302 | "\n", 303 | " \"Dave and Jerry went to the cheese factory.\"" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 9, 309 | "metadata": {}, 310 | "outputs": [], 311 | "source": [ 312 | "def call_me(a, f, d, b=\"\", c=\"cheese\", e=False):\n", 313 | " if e == True:\n", 314 | " return \"{} and {} went to the {}{} {}\".format(a, b, c, d, f)\n", 315 | " else:\n", 316 | " return \"YOU SHALL NOT PASS\"\n", 317 | "\n", 318 | "# Your Code goes here... call_me(?, ?, ?, ?, ?)" 319 | ] 320 | } 321 | ], 322 | "metadata": { 323 | "kernelspec": { 324 | "display_name": "Python 3", 325 | "language": "python", 326 | "name": "python3" 327 | }, 328 | "language_info": { 329 | "codemirror_mode": { 330 | "name": "ipython", 331 | "version": 3 332 | }, 333 | "file_extension": ".py", 334 | "mimetype": "text/x-python", 335 | "name": "python", 336 | "nbconvert_exporter": "python", 337 | "pygments_lexer": "ipython3", 338 | "version": "3.7.4" 339 | } 340 | }, 341 | "nbformat": 4, 342 | "nbformat_minor": 2 343 | } 344 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/09.2 Numbers, Part Two.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# How Floats work (in a bit more depth)\n", 8 | "\n", 9 | "At the fundamental level computers work by flicking on and off trillions of little switches (transistors). \n", 10 | "\n", 11 | "When Python receives a number (in any base) it converts that number into base 2 (binary). This is because at the fundamental level computers run on binary (1’s and 0’s get further converted into electrical current; say 2V for 1 and 0V for 0). \n", 12 | "\n", 13 | "So numbers start at base 10 → are converted to base 2 → and then are converted back again. Sometimes information can be lost in this process. As a result sometimes Python will give you weird answers to basic arithmetic questions. It might seem like a bug when it happens. But actually, these ‘quirks’ are just a consequence of how floats are implemented at the low level.\n", 14 | "\n", 15 | "Let's take a look at a few examples..." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 1, 21 | "metadata": {}, 22 | "outputs": [ 23 | { 24 | "name": "stdout", 25 | "output_type": "stream", 26 | "text": [ 27 | "0.2\n" 28 | ] 29 | } 30 | ], 31 | "source": [ 32 | "print (0.1 + 0.1)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "metadata": {}, 38 | "source": [ 39 | "0.1 + 0.1 = 0.2 Okay, no surprises here. But what about the following sum:" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 2, 45 | "metadata": {}, 46 | "outputs": [ 47 | { 48 | "name": "stdout", 49 | "output_type": "stream", 50 | "text": [ 51 | "0.30000000000000004\n" 52 | ] 53 | } 54 | ], 55 | "source": [ 56 | "print(0.1 + 0.1 + 0.1)" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "This sum should equal 0.3, you don’t need to be a genius to figure that out. But what Python returns is close to right answer but nonetheless wrong. \n", 64 | "\n", 65 | "What happened? well 0.1 * 3 is easy for us to do in base 10 but in base 2 it’s a bit more tricky. Instead of trying to find the actual value Python \"gives up\" after a while and just does a bit of rounding.\n", 66 | "\n", 67 | "Here’s another example:" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 11, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "name": "stdout", 77 | "output_type": "stream", 78 | "text": [ 79 | "2.0999999999999996\n", 80 | "2.8\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "print(0.7 + 0.7 + 0.7)\n", 86 | "print(0.7 + 0.7 + 0.7 + 0.7)" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "Here 0.7 times 3 is clearly 2.1 but Python returns 2.099. If we add an extra 0.7 to the mix Python gets the anwser correct, 0.7 times 4 does in fact equal 2.8. \n", 94 | "\n", 95 | "Alright, that just about wraps up this lecture on numbers. If you would like an even more in-depth explanation how floats works please [read this](https://docs.python.org/3/tutorial/floatingpoint.html). " 96 | ] 97 | } 98 | ], 99 | "metadata": { 100 | "kernelspec": { 101 | "display_name": "Python 3", 102 | "language": "python", 103 | "name": "python3" 104 | }, 105 | "language_info": { 106 | "codemirror_mode": { 107 | "name": "ipython", 108 | "version": 3 109 | }, 110 | "file_extension": ".py", 111 | "mimetype": "text/x-python", 112 | "name": "python", 113 | "nbconvert_exporter": "python", 114 | "pygments_lexer": "ipython3", 115 | "version": "3.7.4" 116 | } 117 | }, 118 | "nbformat": 4, 119 | "nbformat_minor": 2 120 | } 121 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/19. For-Loops.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## For-loops\n", 8 | "\n", 9 | "For loops; what are they? A super useful construct that allows us to do hundreds of calculations with 2-3 lines of code. The Syntax:\n", 10 | "\n", 11 | " for {item} in {iterable}:\n", 12 | " {code block}\n", 13 | " \n", 14 | "So what is an iterable? Well basically it is a data-type that can be considered as 'sequence' of items. In this course we have seen three iterables already: strings, lists and the range function. Lets check that out now: " 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": {}, 21 | "outputs": [ 22 | { 23 | "name": "stdout", 24 | "output_type": "stream", 25 | "text": [ 26 | "1 1\n", 27 | "2 4\n", 28 | "3 9\n", 29 | "4 16\n", 30 | "5 25\n", 31 | "1 is not even\n", 32 | "2 is even\n", 33 | "3 is not even\n", 34 | "4 is even\n", 35 | "5 is not even\n", 36 | "1\n", 37 | "2\n", 38 | "3\n", 39 | "4\n", 40 | "5\n" 41 | ] 42 | } 43 | ], 44 | "source": [ 45 | "a_string = \"12345\"\n", 46 | "a_list = list(range(1,6))\n", 47 | "a_range_object = range(1, 6)\n", 48 | "\n", 49 | "for num in a_range_object:\n", 50 | " print(num, num*num) # prints num and num**2.\n", 51 | " \n", 52 | "for num in a_list:\n", 53 | " print(num, \"is {}even\".format(\"not \" if num % 2 != 0 else \"\")) # returns num and whether it is/isnot even\n", 54 | "\n", 55 | "for num in a_string:\n", 56 | " print(int(num)) # returns num, after converting it to an int. " 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "From this code snippet I want you to understand a few things. The first is that \"num\" takes on all the values 1...5 sequentially. The other (main) thing I want you to realise is that within the context of the loop \"num\" works just like any other normal variable name. And that means we can test it (is it prime, even, divisible by 6, etc) or operate on it (e.g. +,-,/, etc), append it to lists and so on. \n", 64 | "\n", 65 | "Okay, lets heat things up a little. Lets imagine we have a task which states:\n", 66 | "\n", 67 | "* find every single possible sequence of length 2 (XY) where X and Y are in the English alphabet.\n", 68 | "* for example: \"aa\", \"ab\", \"ac\"... \"zz\"\n", 69 | "\n", 70 | "Okay, how many combinations are there? Well, we have 26 possible letters and for each letter there are 26 continuations. 26\\*26= 676. Thats a lot of work for a human being to do by hand, but fortunately for us we have an unthinking machine that can do it all the grunt work. How could we go about solving this task?" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 1, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "676\n", 83 | "['aa', 'ab', 'ac', 'ad', 'ae', 'af', 'ag', 'ah', 'ai', 'aj'] ... ['zr', 'zs', 'zt', 'zu', 'zv', 'zw', 'zx', 'zy', 'zz']\n" 84 | ] 85 | } 86 | ], 87 | "source": [ 88 | "import string\n", 89 | "alphabet = string.ascii_lowercase # this string is simply abc...xyz\n", 90 | "\n", 91 | "combinations = [] \n", 92 | "for letter in alphabet:\n", 93 | " for letter2 in alphabet: # a for loop-inside a for-loop! Sexy. \n", 94 | " sequence = letter + letter2 # aa, ab, ac, etc\n", 95 | " combinations.append(sequence)\n", 96 | " \n", 97 | "print(len(combinations)) # length of the list\n", 98 | "print(combinations[:10], \"...\", combinations[-9:]) # because the list is so long we are printing two smaller slices of it." 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "So as you guys can see, it wasn't actually that difficult to enumerate all the combinations. Using for-loops inside for loops is a powerful way of expressing this type of problem but one should always be aware of the maths involved if we wanted to write code in this way for sequence of length five thats 26\\*\\*5 or 11881376 possible combinations. And so, although double for-loops is a super useful tool to have at ones disposal the reality is an algorithm of the order O(n\\*\\*2) ([see wiki's 'Big O notation' article](https://en.wikipedia.org/wiki/Big_O_notation)) isn't practical for large problem sets.\n", 106 | "\n", 107 | "## Cautionary tale, beware of the infinite!\n", 108 | "\n", 109 | "When using for and while loops it is possible to accidentally create programs that never terminate. And thats err, usually bad. \n", 110 | "\n", 111 | "There are several ways to make this mistake and below I'm going to showcase one particular issue. Although, since I don't want to crash my computer I have added a 'safety valve' which will allow us to run the code safely." 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 2, 117 | "metadata": {}, 118 | "outputs": [ 119 | { 120 | "name": "stdout", 121 | "output_type": "stream", 122 | "text": [ 123 | "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102]\n" 124 | ] 125 | } 126 | ], 127 | "source": [ 128 | "lst = [1,2]\n", 129 | "\n", 130 | "loop_counter = 0\n", 131 | "for item in lst:\n", 132 | " lst.append(item+2)\n", 133 | " loop_counter +=1 # every time we go through the loop, we add one to our counter. \n", 134 | " if exit_counter == 100: # if we have gone through the loop 100 times...\n", 135 | " break # we escape the loop.\n", 136 | "print(lst)" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": { 142 | "collapsed": true 143 | }, 144 | "source": [ 145 | "Okay so this code starts with a list of 2 items, and for each item it adds a new item to the list (item + 2). Because we are constantly adding one to the list we never reach the end of the list, and so therefore the program never terminates. \n", 146 | "\n", 147 | "The 'bandage' fix in place here is a loop_counter. This simply keeps check of how many times we have gone through the loop. Once we hit 100 loops we execute \"break\" to escape the loop. And thus the program doesn't waltz toward infinity.\n", 148 | "\n", 149 | "There is another (often better) way to handle this issue however, and that is to separate out the thing we wish to iterate over and the thing we wish to change. Here's an example:" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 3, 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "name": "stdout", 159 | "output_type": "stream", 160 | "text": [ 161 | "[1, 2, 3, 4]\n" 162 | ] 163 | } 164 | ], 165 | "source": [ 166 | "lst = [1,2]\n", 167 | "\n", 168 | "for item in lst[:]: # <--- see lecture on splicing, lst[:] is a COPY of the lst, not the list itself.\n", 169 | " lst.append(item+2)\n", 170 | "print(lst)" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": {}, 176 | "source": [ 177 | "The difference here, as noted in the comment, is that lst[:] is a copy of lst and this copy doesn't actually change as lst changes, and so therefore the program terminates.\n", 178 | "\n", 179 | "## Homework Assignment\n", 180 | "\n", 181 | "Your task this week is to make a program named \"fizzbuzz\". The rules\n", 182 | "\n", 183 | "* Your program should go through the numbers 1 to 100,\n", 184 | "* if the number is even, print \"fizz\"\n", 185 | "* if the number is divisible by 5 print \"buzz\"\n", 186 | "* if the number is both even and divisible by 5 print \"fizzbuzz\"\n", 187 | "* otherwise just print the number. \n", 188 | "\n", 189 | "**For extra points**:\n", 190 | "\n", 191 | "For extra points you need to make your code easily modifiable. I want to be able to:\n", 192 | "\n", 193 | "* change the string printed out (e.g change 'fizz' to 'dave', or some other string)\n", 194 | "* be able to change the total\n", 195 | "* change one(or both) of the rules (e.g. change the rule to be divisible by 6, not 5)\n", 196 | "\n", 197 | "To do this you should ask the user what the rules should be (Hint you should use Pythons \"input\" Function). " 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "metadata": { 204 | "collapsed": true 205 | }, 206 | "outputs": [], 207 | "source": [ 208 | "# YOUR CODE HERE" 209 | ] 210 | } 211 | ], 212 | "metadata": { 213 | "kernelspec": { 214 | "display_name": "Python 3", 215 | "language": "python", 216 | "name": "python3" 217 | }, 218 | "language_info": { 219 | "codemirror_mode": { 220 | "name": "ipython", 221 | "version": 3 222 | }, 223 | "file_extension": ".py", 224 | "mimetype": "text/x-python", 225 | "name": "python", 226 | "nbconvert_exporter": "python", 227 | "pygments_lexer": "ipython3", 228 | "version": "3.7.4" 229 | } 230 | }, 231 | "nbformat": 4, 232 | "nbformat_minor": 2 233 | } 234 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/23. Try & Except.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Error Handling Using Try & Except\n", 8 | "\n", 9 | "> Errors should never pass silently.\n", 10 | "Unless explicitly silenced. ~ Zen of Python\n", 11 | "\n", 12 | "Hi guys, last lecture we looked at common error messages, in this lecture we shall look at a neat way to handle those errors. The Syntax:\n", 13 | "\n", 14 | " try:\n", 15 | " {code block}\n", 16 | " except {Error}:\n", 17 | " {code block}\n", 18 | " \n", 19 | "Okay, so what does try & except actually do? Well basically, Python tries to execute a statement, but if in the process of executing that statement an error (of type Error) occurs then we to something else instead. In terms of logic, try/except works a bit like if/elif work. Here is a simple example:" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 1, 25 | "metadata": {}, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "100\n", 32 | "1049.76\n", 33 | "201.64\n", 34 | "aa\n", 35 | "bb\n", 36 | "[]\n", 37 | "[1, 2, 1, 2]\n" 38 | ] 39 | } 40 | ], 41 | "source": [ 42 | "a_list = [10, 32.4, -14.2, \"a\", \"b\", [], [1,2]]\n", 43 | "\n", 44 | "for item in a_list:\n", 45 | " try:\n", 46 | " print(item * item)\n", 47 | " except TypeError:\n", 48 | " print(item + item)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "So what’s going on here? Well, we have list which contains several different data-types. For every 'item' we try to multiply item by itself. If 'item' is a number this makes sense and so we print item * item. However, if we try to multiply a string by a string we get a TypeError, which the except statement catches. So if we receive a TypeError we try something else, in this particular case we add item to item, and thus \"aa\", \"bb\", etc get printed.\n", 56 | "\n", 57 | "Now it is important to note this current code is only set up to handle TypeErrors. What happens if we change the above bit of code to divide rather than multiply and feed it 0?" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 4, 63 | "metadata": {}, 64 | "outputs": [ 65 | { 66 | "ename": "ZeroDivisionError", 67 | "evalue": "division by zero", 68 | "output_type": "error", 69 | "traceback": [ 70 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 71 | "\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", 72 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mitem\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mitem\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mitem\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mitem\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mitem\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 73 | "\u001b[0;31mZeroDivisionError\u001b[0m: division by zero" 74 | ] 75 | } 76 | ], 77 | "source": [ 78 | "item = 0\n", 79 | "try:\n", 80 | " item / item\n", 81 | "except TypeError:\n", 82 | " print(item + item)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": {}, 88 | "source": [ 89 | "In this case Python didn't receive a TypeError and thus the except block of code failed to execute. Now, we can fix this code in one of two ways:" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 18, 95 | "metadata": {}, 96 | "outputs": [ 97 | { 98 | "name": "stdout", 99 | "output_type": "stream", 100 | "text": [ 101 | "Bad 0\n", 102 | "Good 0\n" 103 | ] 104 | } 105 | ], 106 | "source": [ 107 | "x = 0\n", 108 | "\n", 109 | "# The bad fix first...\n", 110 | "try:\n", 111 | " x / x\n", 112 | "except: \n", 113 | " print(\"Bad \", x + x)\n", 114 | "\n", 115 | "# The Good fix...\n", 116 | "try:\n", 117 | " item / item\n", 118 | "except (TypeError, ZeroDivisionError): # please note the \"SnakeCase\".\n", 119 | " print(\"Good\", x + x)" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "The bad fix just leaves a blank except statement, this catches ALL errors. The good fix meanwhile specifically states what errors it should catch, but the code will still fail if the error is something other than Type or dividing by zero.\n", 127 | "\n", 128 | "So why is it bad to leave a bare except statement? Well, as I've stated elsewhere in these lecture series it is often better to crash than it is to output junk. And please trust me when I say bare except clauses are a great way to output junk. \n", 129 | "\n", 130 | "In the second case we specifically state the errors we expect to sometimes receive. And this is nice for a few reasons, first, by naming the exceptions the code is a bit more readable. Secondly, expressly stating the errors forces you to be much more *mindful* when writing the code in the first place. And thirdly, if something unexpected does happen then, unless you have bare except statements throughout all of your code eventually you'll pass junk data to some function and get an error there. So basically in many cases you are not really *solving* the problem, you end up *delaying* the problem. \n", 131 | "\n", 132 | "In short, for most applications you should be looking to handle the minimum number of cases you need for the code to function and in all other cases just let it crash.\n", 133 | "\n", 134 | "Okay, how about one more example?" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 36, 140 | "metadata": {}, 141 | "outputs": [ 142 | { 143 | "name": "stdout", 144 | "output_type": "stream", 145 | "text": [ 146 | "Starting square = (2,2)\n", 147 | "Trying to move 'left' to square (1, 2):\n", 148 | "[0, 0, 0]\n", 149 | "[0, 0, 0]\n", 150 | "[0, 2, 1]\n", 151 | "\n", 152 | "\n", 153 | "Trying to move 'right' to square (3, 2):\n", 154 | "Square (3, 2), is out of bounds. IndexError sucessfully caught.\n", 155 | "\n", 156 | "Trying to move 'up' to square (2, 1):\n", 157 | "[0, 0, 0]\n", 158 | "[0, 0, 2]\n", 159 | "[0, 2, 1]\n", 160 | "\n", 161 | "\n", 162 | "Trying to move 'down' to square (2, 3):\n", 163 | "Square (2, 3), is out of bounds. IndexError sucessfully caught.\n", 164 | "\n" 165 | ] 166 | } 167 | ], 168 | "source": [ 169 | "def character_movement(x, y):\n", 170 | " \"\"\"where (x,y) is the position on a 2-d plane\"\"\"\n", 171 | " return [(\"start\", (x, y)), \n", 172 | " (\"left\", (x -1, y)),(\"right\", (x + 1, y)),\n", 173 | " (\"up\", (x, y - 1)), (\"down\", (x, y + 1))]\n", 174 | "\n", 175 | "the_map = [ [0, 0, 0], \n", 176 | " [0, 0, 0],\n", 177 | " [0, 0, 1]] # 1 denotes our character\n", 178 | "\n", 179 | "\n", 180 | "moves = character_movement(2, 2)\n", 181 | "print(\"Starting square = (2,2)\")\n", 182 | "\n", 183 | "for (direction, position) in moves[1:]:\n", 184 | " print(\"Trying to move '{}' to square {}:\".format(direction, position))\n", 185 | " try:\n", 186 | " the_map[position[1]][position[0]] = 2\n", 187 | " print(*the_map, sep=\"\\n\")\n", 188 | " print(\"\\n\")\n", 189 | " except IndexError:\n", 190 | " print(\"Square {}, is out of bounds. IndexError sucessfully caught.\\n\".format(position))" 191 | ] 192 | } 193 | ], 194 | "metadata": { 195 | "kernelspec": { 196 | "display_name": "Python 3", 197 | "language": "python", 198 | "name": "python3" 199 | }, 200 | "language_info": { 201 | "codemirror_mode": { 202 | "name": "ipython", 203 | "version": 3 204 | }, 205 | "file_extension": ".py", 206 | "mimetype": "text/x-python", 207 | "name": "python", 208 | "nbconvert_exporter": "python", 209 | "pygments_lexer": "ipython3", 210 | "version": "3.7.4" 211 | } 212 | }, 213 | "nbformat": 4, 214 | "nbformat_minor": 2 215 | } 216 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/27. Final Project, An Introduction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "# Final Project: An Introduction\n", 10 | "\n", 11 | "Congratulations guys, you are sooo close to the finish line. The final project is going to be split up into several parts; the aim is to get you guys to code up a working version of the game minesweeper.\n", 12 | "\n", 13 | "For each part I shall introduce the problem to solve and you then have to solve it as homework. I'll provide solutions as well, which means if you get stuck on part two or something you can just read my solution and move onto part three. The aim of splitting the project into chunks is help give you some structure; by the end of it we should be able to 'glue' the parts together and have a functioning game.\n", 14 | "\n", 15 | "For some of you this is about to be the largest program you have ever written. And unfortunately knowing your Python syntax isn't going to sufficient to succeed. Before you start, it might be a good idea to take a quick refresher in \"design decisions\". I say that because big projects require you to think about the big picture!\n", 16 | "\n", 17 | "Oh, one last thing, with the exception of this lecture all the materials related to the Minesweeper project are to be found in the *Final Project (minsweeper)* folder. \n", 18 | "\n", 19 | "## The game\n", 20 | "\n", 21 | "* The Rules: [clicky here](http://www.wikihow.com/Play-Minesweeper)\n", 22 | "* To play: [clicky here](http://minesweeperonline.com/#)\n", 23 | "\n", 24 | "## Dividing into Chunks\n", 25 | "\n", 26 | "When starting large projects it is often a good idea to start with an 'itinerary' of concepts, that is, \"what will I have to do?\" Below I've provided a rough outline of some of the steps we are going to need to take to finish this project. \n", 27 | "\n", 28 | "* Build a board, (with bombs)\n", 29 | "* Have a function that works out how many neighbour squares are bombs. \n", 30 | "* A way to show the player the board\n", 31 | "* Have a 'reveal square' mechanic (player action) \n", 32 | "* Have a 'flag' mechanic (player action)\n", 33 | "\n", 34 | "Alright so let's get started. It seems like building a board might be the first step so come join me in the \"building the board\" lecture!\n", 35 | "\n", 36 | "## Lessons included!\n", 37 | "\n", 38 | "As a final note, even if you don't want to do the main project, I would nonetheless recommend checking out the sample solutions and the project lectures all the same. The reason I say that is there a few self-contained 'mini-sections' which you can learn from. So...yeah, I'll see you there, right guys?" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [] 47 | } 48 | ], 49 | "metadata": { 50 | "kernelspec": { 51 | "display_name": "Python 3", 52 | "language": "python", 53 | "name": "python3" 54 | }, 55 | "language_info": { 56 | "codemirror_mode": { 57 | "name": "ipython", 58 | "version": 3 59 | }, 60 | "file_extension": ".py", 61 | "mimetype": "text/x-python", 62 | "name": "python", 63 | "nbconvert_exporter": "python", 64 | "pygments_lexer": "ipython3", 65 | "version": "3.7.4" 66 | } 67 | }, 68 | "nbformat": 4, 69 | "nbformat_minor": 2 70 | } 71 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/28. Conclusion.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "# CONGRATULATIONS!\n", 10 | "\n", 11 | "Well done you made it. I sincerely hope you enjoyed your time with me and I hope you will continue your studies and do great things in Python. \n", 12 | " \n", 13 | "Regards, \n", 14 | " Chris. \n", 15 | "\n", 16 | "\n", 17 | "### Last Updated: \n", 18 | "\n", 19 | "17/01/2020\n", 20 | "\n", 21 | "### Version History\n", 22 | "\n", 23 | "* 17th Jan '20: Substantial rewrite and content improvement.\n", 24 | "* 8th Dec '17: Redone all lectures, changed/added some content, fixed a lot of typos/grammer stuff.\n", 25 | "* 26th June '17: Redone lecture numbers, added \"Guide FAQ\" section, completed (first draft) of main project.\n", 26 | "* 23rd June '17: Added first drafts of the main project, added a new lecture on how to use/install jupyter notebooks.\n", 27 | "* 22nd June '17: 1.0 (Alpha) released! Posted to 'learn python' subreddit.\n", 28 | "\n", 29 | "### Acknowledgements\n", 30 | "\n", 31 | "* Thankyou to everyone who helped make this possible, however small your contribution. :)" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [] 40 | } 41 | ], 42 | "metadata": { 43 | "kernelspec": { 44 | "display_name": "Python 3", 45 | "language": "python", 46 | "name": "python3" 47 | }, 48 | "language_info": { 49 | "codemirror_mode": { 50 | "name": "ipython", 51 | "version": 3 52 | }, 53 | "file_extension": ".py", 54 | "mimetype": "text/x-python", 55 | "name": "python", 56 | "nbconvert_exporter": "python", 57 | "pygments_lexer": "ipython3", 58 | "version": "3.7.4" 59 | } 60 | }, 61 | "nbformat": 4, 62 | "nbformat_minor": 2 63 | } 64 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/01 Building the Board.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Building the Board\n", 8 | "\n", 9 | "Alright, so lets start with the big picture thinking. How to do represent the board itself? Well, as we saw with the chess program (design lecture) it seems like nested lists trump strings. So lets run with that.\n", 10 | "\n", 11 | "Okay so our board is going to look something like this:\n", 12 | "\n", 13 | " [ _, B, _ ]\n", 14 | " [ B, _, _ ]\n", 15 | " [ _, _, _ ]\n", 16 | "\n", 17 | " Where \"B\" = Bomb\n", 18 | "\n", 19 | "Now. If we show the player the board above then clearly the game is easy. So thats something we need to think about; how are we going to handle (a) the internal state of the game and (b) what we show to the player. \n", 20 | "\n", 21 | "So now if the player selects the first square (0, 0) then we want to display something like this:\n", 22 | "\n", 23 | " [ 2, _, _ ]\n", 24 | " [ _, _, _ ]\n", 25 | " [ _, _, _ ]\n", 26 | "\n", 27 | " Where '2' denotes the number of bombs nearby. \n", 28 | "\n", 29 | "What else might our build board function need to do? Well, I think it would be nice to be able to set the board size (e.g. 10x10, 5x20) and we may also want to set the number of bombs in the game.\n", 30 | "\n", 31 | "Alright, so now that we have fleshed out the problem we need to solve the next thing to do is to try to come up with a solution. There are of course many possible ways to do this, but I think a simple approach is to just we build two boards of the same size. One board represents the internal games state and the other board is what we show the player. This two boards will need to be kept 'insync'. \n", 32 | "\n", 33 | "\n", 34 | "## Test-Driven Development\n", 35 | "\n", 36 | "Remember in the testing lecture I talked about how sometimes writing the tests first makes implementing the problem easier? Well, I'd encourage you to think about writing some tests before getting 'stuck in', in the long run, it may save you a lot of time. \n", 37 | "\n", 38 | "As a quick tip, if you want to place bombs randomly and also want to test the code then you may wish to set random.seed to some constant. " 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": { 45 | "collapsed": true 46 | }, 47 | "outputs": [], 48 | "source": [ 49 | "def test_board():\n", 50 | " \"\"\"\n", 51 | " Write your tests here...\n", 52 | " \n", 53 | " Example:\n", 54 | " >>> 1 + 1\n", 55 | " 2\n", 56 | " \n", 57 | " \"\"\"\n", 58 | " import doctest\n", 59 | " doctest.testmod()\n", 60 | " print(\"TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\")" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "metadata": { 67 | "collapsed": true 68 | }, 69 | "outputs": [], 70 | "source": [ 71 | "#def build_board\n", 72 | " # Your code here\n", 73 | "\n", 74 | "# Runing the tests...\n", 75 | "test_board()\n", 76 | "# Note if you recieve an error message saying test_board not found \n", 77 | "# try hitting the run button on the test_board cell and try again." 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "If you get stuck, then you can always check out my solution to the problem (just look for _1 Building the board (HW))" 85 | ] 86 | } 87 | ], 88 | "metadata": { 89 | "kernelspec": { 90 | "display_name": "Python 3", 91 | "language": "python", 92 | "name": "python3" 93 | }, 94 | "language_info": { 95 | "codemirror_mode": { 96 | "name": "ipython", 97 | "version": 3 98 | }, 99 | "file_extension": ".py", 100 | "mimetype": "text/x-python", 101 | "name": "python", 102 | "nbconvert_exporter": "python", 103 | "pygments_lexer": "ipython3", 104 | "version": "3.7.4" 105 | } 106 | }, 107 | "nbformat": 4, 108 | "nbformat_minor": 2 109 | } 110 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/02. Printing the board.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Printing the Board\n", 8 | "\n", 9 | "Okay so in the last lecture we built a board for our game. Right now a 3x3 grid with 3 bombs looks a little something like this:\n", 10 | "\n", 11 | " [['-', 'B', '-'], ['-', 'B', 'B'], ['-', '-', '-']]\n", 12 | " \n", 13 | "What we now want is a function that will take a board as input and print each row on a new line, since we can't really play a game of minesweeper when the board looks like it does in the above example. \n", 14 | "\n", 15 | "What we need is a function that will take a board and display it in a user-friendly fashion. Like so:\n", 16 | " \n", 17 | " ['-', 'B', '-']\n", 18 | " ['-', 'B', 'B']\n", 19 | " ['-', '-', '-']\n", 20 | " \n", 21 | "Just as before, I recomend writing some tests before you start." 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 20, 27 | "metadata": { 28 | "collapsed": true 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "def test():\n", 33 | " \"\"\"\n", 34 | " Write your tests here...\n", 35 | " \n", 36 | " Example:\n", 37 | " >>> 1 + 1\n", 38 | " 2\n", 39 | " \n", 40 | " \"\"\"\n", 41 | " import doctest\n", 42 | " doctest.testmod()\n", 43 | " print(\"TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\")\n" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 21, 49 | "metadata": {}, 50 | "outputs": [ 51 | { 52 | "name": "stdout", 53 | "output_type": "stream", 54 | "text": [ 55 | "TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\n" 56 | ] 57 | } 58 | ], 59 | "source": [ 60 | "def display_board(board):\n", 61 | " # your code here\n", 62 | " pass\n", 63 | " \n", 64 | "# Runing the tests...\n", 65 | "test()\n", 66 | "# Note if you recieve an error message saying test_board not found \n", 67 | "# try hitting the run button on the test_board cell and try again." 68 | ] 69 | } 70 | ], 71 | "metadata": { 72 | "kernelspec": { 73 | "display_name": "Python 3", 74 | "language": "python", 75 | "name": "python3" 76 | }, 77 | "language_info": { 78 | "codemirror_mode": { 79 | "name": "ipython", 80 | "version": 3 81 | }, 82 | "file_extension": ".py", 83 | "mimetype": "text/x-python", 84 | "name": "python", 85 | "nbconvert_exporter": "python", 86 | "pygments_lexer": "ipython3", 87 | "version": "3.7.4" 88 | } 89 | }, 90 | "nbformat": 4, 91 | "nbformat_minor": 2 92 | } 93 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/03. Defining Helper Functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "For this project we are going to need to index squares on the board. Thus, its probably a good idea to write some helper functions. For example:\n", 8 | "\n", 9 | "* 'get_square' -- takes a board and a position(x,y), returns the value of square (x,y).\n", 10 | "* 'set_square' -- takes a board and a position(x,y) and new_val. We then change value of square(x,y) to new_val.\n", 11 | "\n", 12 | "In future we will be able to use these functions inside other functions. This will hopefully save a bit of time and avoid a few bugs!" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 1, 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "def test():\n", 22 | " \"\"\"\n", 23 | " Write your tests here...\n", 24 | " \n", 25 | " Example:\n", 26 | " >>> 1 + 1\n", 27 | " 2\n", 28 | " \n", 29 | " \"\"\"\n", 30 | " import doctest\n", 31 | " doctest.testmod()\n", 32 | " print(\"TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\")" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "def get_square(x, y, board):\n", 42 | " \"\"\"\n", 43 | " This function takes a board and returns the value at that square(x,y).\n", 44 | " \"\"\"\n", 45 | " # Your code here.\n", 46 | " pass\n", 47 | "\n", 48 | "def set_square(x, y, new_val, board):\n", 49 | " \"\"\"\n", 50 | " This function indexes into the given board at position (x, y).\n", 51 | " We then change that value to new_val. Returns nothing.\n", 52 | " \"\"\"\n", 53 | " # Your code here.\n", 54 | " pass\n", 55 | "\n", 56 | "# Runing the tests...\n", 57 | "test()\n", 58 | "# Note if you recieve an error message saying test_board not found \n", 59 | "# try hitting the run button on the test_board cell and try again." 60 | ] 61 | } 62 | ], 63 | "metadata": { 64 | "kernelspec": { 65 | "display_name": "Python 3", 66 | "language": "python", 67 | "name": "python3" 68 | }, 69 | "language_info": { 70 | "codemirror_mode": { 71 | "name": "ipython", 72 | "version": 3 73 | }, 74 | "file_extension": ".py", 75 | "mimetype": "text/x-python", 76 | "name": "python", 77 | "nbconvert_exporter": "python", 78 | "pygments_lexer": "ipython3", 79 | "version": "3.7.4" 80 | } 81 | }, 82 | "nbformat": 4, 83 | "nbformat_minor": 2 84 | } 85 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/04. Getting the Neighbours.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "Hi guys, so in this lecture we are going to look at how to work out how many bombs surround a given square. This problem might be best solved by splitting it into two parts. \n", 8 | "\n", 9 | "1. Create a function that takes position(x,y) on the board and returns all its nieghbours (i.e 8 squares).\n", 10 | "1. Create a function that calls that takes all the (x, y) points and counts up the number of bombs.\n", 11 | "\n", 12 | "for example:\n", 13 | "\n", 14 | " [[_,B,-,-],\n", 15 | " [Y,-,-,-],\n", 16 | " [B,B,X,-],\n", 17 | " [B,-,-,B]]\n", 18 | " \n", 19 | "In the above board, we want X to equal 1 because there are 2 bombs nearby. In the case of Y we want to return 3.\n", 20 | "\n", 21 | "A few hints:\n", 22 | "\n", 23 | "* Make sure you don't change the square if it is a bomb! \n", 24 | "* How do you want to handle IndexErrors?\n", 25 | "* Don't forget to use those helper functions we defined last time (get_square, set_square).\n", 26 | "* If you get stuck, you may find some finds in the design lecture.\n", 27 | " " 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 29, 33 | "metadata": { 34 | "collapsed": true 35 | }, 36 | "outputs": [], 37 | "source": [ 38 | "def test():\n", 39 | " \"\"\"\n", 40 | " Write your tests here...\n", 41 | " \n", 42 | " Example:\n", 43 | " >>> 1 + 1\n", 44 | " 2\n", 45 | " \n", 46 | " \"\"\"\n", 47 | " \n", 48 | " print(\"Testing Complete\")" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": { 55 | "collapsed": true 56 | }, 57 | "outputs": [], 58 | "source": [ 59 | "def neighbour_squares(x, y, num_rows, num_cols):\n", 60 | " \"\"\"\n", 61 | " (x, y) 0-based index co-ordinate pair.\n", 62 | " num_rows, num_cols: specifiy the max size of the board\n", 63 | " \n", 64 | " returns all valid (x, y) coordinates from starting position.\n", 65 | " \"\"\"\n", 66 | " pass\n", 67 | " \n", 68 | "def count_bombs(x, y, board):\n", 69 | " \"\"\"\n", 70 | " returns the number of neighbours of (x,y) that are bombs. Max is 8, min is 0.\n", 71 | " \"\"\"\n", 72 | " pass\n", 73 | " \n", 74 | "test()" 75 | ] 76 | } 77 | ], 78 | "metadata": { 79 | "kernelspec": { 80 | "display_name": "Python 3", 81 | "language": "python", 82 | "name": "python3" 83 | }, 84 | "language_info": { 85 | "codemirror_mode": { 86 | "name": "ipython", 87 | "version": 3 88 | }, 89 | "file_extension": ".py", 90 | "mimetype": "text/x-python", 91 | "name": "python", 92 | "nbconvert_exporter": "python", 93 | "pygments_lexer": "ipython3", 94 | "version": "3.7.4" 95 | } 96 | }, 97 | "nbformat": 4, 98 | "nbformat_minor": 2 99 | } 100 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/06. Revealing Squares.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "Okay so lets quickly recap where we are at with this project:\n", 8 | " \n", 9 | "* We have built the 'board function'\n", 10 | "* We can print the board.\n", 11 | "* We can set the board to display the correct number of neughor bombs.\n", 12 | "\n", 13 | "And finally, let's quickly consider what we have left to do:\n", 14 | "\n", 15 | "* create a 'reveal square' function.\n", 16 | "* create a 'flag square' function.\n", 17 | "* Add win/loss checks, a UI, set-up functions, bling\n", 18 | "* Bring everything together\n", 19 | "\n", 20 | "Today we shall be focus on the reveal square function.\n", 21 | "\n", 22 | "## ToDo\n", 23 | "\n", 24 | "Okay, so here's the basic implementation idea. When we start a new game we create two boards:\n", 25 | "\n", 26 | "* The 'game board' (with bombs) -- Hidden from player\n", 27 | "* The 'player board' (with flags and numbers) -- This is what the players sees during the game.\n", 28 | "\n", 29 | "The player board will have the same dimensions as the game board. This means that the square (0, 0) on the game board corressponds to same square on the player board. You may remember that when we wrote the 'build_board' function I advised you to make it generalisable. Well, the effort is about to pay-off; we can create both of our boards with just a few lines of code:" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "NUMBER_OF_ROWS = 3\n", 39 | "NUMBER_OF_COLS = 3\n", 40 | "NUMBER_OF_BOMBS = 2 # You may remember that all_caps mean that these variables should NOT change values at runtime.\n", 41 | "\n", 42 | "game_board = build_board(NUMBER_OF_ROWS, NUMBER_OF_COLS, bomb_count = NUMBER_OF_BOMBS)\n", 43 | "player_board = build_board(NUMBER_OF_ROWS, NUMBER_OF_COLS, bomb_count=0)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "## The Reveal function\n", 51 | "\n", 52 | "* Take a square as input and reveal a square to the player (said square will be either a bomb or a number)\n", 53 | "* In the case of revealing a bomb, its game over.\n", 54 | "* If we reveal a number, it should stay revealed until the end of the game. \n", 55 | "* If we highlight an already selected square (e.g a number or the letter \"F\") we should do nothing. \n", 56 | "\n", 57 | "## The Flag Function\n", 58 | "\n", 59 | "* If the selected square is flagged, de-flag it.\n", 60 | "* If the square is already revealed (e.g. a flag or a number) we should do nothing.\n", 61 | "* If we flag a square, the player board should display an \"F\" character. \n", 62 | "\n", 63 | "Also note that if the player flags all (and only) bombs then the player has won the game. You may wish to bear that in mind as you write your functions...\n", 64 | "\n", 65 | "Also as you read the requirements it should hopefully occur to you that the flag and reveal square functions are actually rather similar. What do this mean? What should you do as a result of this similiarity?" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "def test_board():\n", 75 | " \"\"\"\n", 76 | " Write your tests here...\n", 77 | " \n", 78 | " Example:\n", 79 | " >>> 1 + 1\n", 80 | " 2\n", 81 | " \n", 82 | " \"\"\"\n", 83 | " import doctest\n", 84 | " doctest.testmod()\n", 85 | " print(\"TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\")" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "def reveal_square(row, col, player_board, game_board):\n", 95 | " # Your code here...\n", 96 | " pass\n", 97 | "\n", 98 | "# testing...\n", 99 | "test()" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "def flag_square(row, col, player_board):\n", 109 | " # Your code here...\n", 110 | " pass\n", 111 | "\n", 112 | "# testing...\n", 113 | "test()" 114 | ] 115 | } 116 | ], 117 | "metadata": { 118 | "kernelspec": { 119 | "display_name": "Python 3", 120 | "language": "python", 121 | "name": "python3" 122 | }, 123 | "language_info": { 124 | "codemirror_mode": { 125 | "name": "ipython", 126 | "version": 3 127 | }, 128 | "file_extension": ".py", 129 | "mimetype": "text/x-python", 130 | "name": "python", 131 | "nbconvert_exporter": "python", 132 | "pygments_lexer": "ipython3", 133 | "version": "3.7.4" 134 | } 135 | }, 136 | "nbformat": 4, 137 | "nbformat_minor": 2 138 | } 139 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/07. Lets Play!.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Lets play Minesweeper\n", 8 | "\n", 9 | "This lecture is a chill one. All I am going to do is play my implementation of minesweeper. I'll show you the code in the next lecture." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "+--------------------------------+\n", 22 | "| WELCOME TO MINSWEEPER 1.0! |\n", 23 | "+--------------------------------+\n", 24 | "How to play: type 'commands' for a list of valid inputs. Then type 'help x' for information about how to use command 'x'\n", 25 | "\n", 26 | "Command: commands\n", 27 | "dict_keys(['flag', 'pick', 'hint', 'new', 'cheat', 'help', 'commands', 'exit'])\n", 28 | "[]\n", 29 | "\n", 30 | "\n", 31 | "Command: help exit\n", 32 | "Exit the application. Example useage: exit\n", 33 | "[]\n", 34 | "\n", 35 | "\n", 36 | "Command: help new\n", 37 | "Starts a new game with a board size of (x,y) with z bombs. Example useage: new x y z\n", 38 | "[]\n", 39 | "\n", 40 | "\n", 41 | "Command: help hint\n", 42 | "The computer checks if square(x, y) is a bomb or not. Example useage: hint x y\n", 43 | "[]\n", 44 | "\n", 45 | "\n", 46 | "Command: help flag\n", 47 | "Flags/deflags square(x,y). Example useage: flag x y\n", 48 | "[]\n", 49 | "\n", 50 | "\n", 51 | "Command: help pick\n", 52 | "Selects square(x, y) to reveal, its game over if you reveal a bomb. Example useage: pick x y\n", 53 | "[]\n", 54 | "\n", 55 | "\n", 56 | "Command: exit\n", 57 | "[]\n", 58 | "\n", 59 | "\n" 60 | ] 61 | } 62 | ], 63 | "source": [ 64 | "import sys\n", 65 | "sys.path.append(\"..\\misc\") # Adding to sys.path allows us to find \"minsweeper.py\" \n", 66 | "\n", 67 | "import minesweeper\n", 68 | "\n", 69 | "minesweeper.main()" 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "So as you can see, to make the game more playable I have enabled to program to listen to instructions and execute them. By typing commands we see a list of all the availible instructions and help instruction tells us what how we can use that instruction. This is all the information we should need in order to play a game of minesweeper. Okay, lets play a game for 3x3 with 4 bombs..." 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 2, 82 | "metadata": {}, 83 | "outputs": [ 84 | { 85 | "name": "stdout", 86 | "output_type": "stream", 87 | "text": [ 88 | "+--------------------------------+\n", 89 | "| WELCOME TO MINSWEEPER 1.0! |\n", 90 | "+--------------------------------+\n", 91 | "How to play: type 'commands' for a list of valid inputs. Then type 'help x' for information about how to use command 'x'\n", 92 | "\n", 93 | "Command: new 3 3 4\n", 94 | "['-', '-', '-']\n", 95 | "['-', '-', '-']\n", 96 | "['-', '-', '-']\n", 97 | "\n", 98 | "\n", 99 | "Command: pick 0 1\n", 100 | "['-', '2', '-']\n", 101 | "['-', '-', '-']\n", 102 | "['-', '-', '-']\n", 103 | "\n", 104 | "\n", 105 | "Command: hint 0 2\n", 106 | "Is square(0,2) a bomb?: False\n", 107 | "['-', '2', '-']\n", 108 | "['-', '-', '-']\n", 109 | "['-', '-', '-']\n", 110 | "\n", 111 | "\n", 112 | "Command: pick 0 2\n", 113 | "['-', '2', '1']\n", 114 | "['-', '-', '-']\n", 115 | "['-', '-', '-']\n", 116 | "\n", 117 | "\n", 118 | "Command: cheat\n", 119 | "['-', '-', '-']\n", 120 | "['B', 'B', '-']\n", 121 | "['B', 'B', '-']\n", 122 | "\n", 123 | "\n", 124 | "['-', '2', '1']\n", 125 | "['-', '-', '-']\n", 126 | "['-', '-', '-']\n", 127 | "\n", 128 | "\n", 129 | "Command: flag 1 0\n", 130 | "['-', '2', '1']\n", 131 | "['F', '-', '-']\n", 132 | "['-', '-', '-']\n", 133 | "\n", 134 | "\n", 135 | "Command: flag 1 1\n", 136 | "['-', '2', '1']\n", 137 | "['F', 'F', '-']\n", 138 | "['-', '-', '-']\n", 139 | "\n", 140 | "\n", 141 | "Command: pick 0 0\n", 142 | "['2', '2', '1']\n", 143 | "['F', 'F', '-']\n", 144 | "['-', '-', '-']\n", 145 | "\n", 146 | "\n", 147 | "Command: pick 2 0\n", 148 | "============\n", 149 | "GAME OVER\n", 150 | "=============\n", 151 | "['-', '-', '-']\n", 152 | "['B', 'B', '-']\n", 153 | "['B', 'B', '-']\n", 154 | "[]\n", 155 | "\n", 156 | "\n", 157 | "Command: exit\n", 158 | "[]\n", 159 | "\n", 160 | "\n" 161 | ] 162 | } 163 | ], 164 | "source": [ 165 | "minesweeper.main()" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "So there you have it. Feel free to play a game yourself. A magic internet cookie goes to anyone how can find a bug!\n", 173 | "\n", 174 | "If you want to inspect the code you'll find it in the 'misc' folder." 175 | ] 176 | } 177 | ], 178 | "metadata": { 179 | "kernelspec": { 180 | "display_name": "Python 3", 181 | "language": "python", 182 | "name": "python3" 183 | }, 184 | "language_info": { 185 | "codemirror_mode": { 186 | "name": "ipython", 187 | "version": 3 188 | }, 189 | "file_extension": ".py", 190 | "mimetype": "text/x-python", 191 | "name": "python", 192 | "nbconvert_exporter": "python", 193 | "pygments_lexer": "ipython3", 194 | "version": "3.7.4" 195 | } 196 | }, 197 | "nbformat": 4, 198 | "nbformat_minor": 2 199 | } 200 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/_01. Building the Board (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "def test_board():\n", 10 | " \"\"\"\n", 11 | " >>> build_board(1, 1, 1)\n", 12 | " [['B']]\n", 13 | " >>> build_board(1,3, 3)\n", 14 | " [['B', 'B', 'B']]\n", 15 | " >>> build_board(3, 1, 0, non_bomb_character = \"X\")\n", 16 | " [['X'], ['X'], ['X']]\n", 17 | " >>> build_board(3, 6, 0, non_bomb_character = \"y\")\n", 18 | " [['y', 'y', 'y', 'y', 'y', 'y'], ['y', 'y', 'y', 'y', 'y', 'y'], ['y', 'y', 'y', 'y', 'y', 'y']]\n", 19 | " >>> build_board(3, 3, 9)\n", 20 | " [['B', 'B', 'B'], ['B', 'B', 'B'], ['B', 'B', 'B']]\n", 21 | " >>> build_board(3, 3, 300)\n", 22 | " [['B', 'B', 'B'], ['B', 'B', 'B'], ['B', 'B', 'B']]\n", 23 | " >>> build_board(4, 3, 0)\n", 24 | " [['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']]\n", 25 | " \"\"\"\n", 26 | " import doctest\n", 27 | " doctest.testmod()\n", 28 | " print(\"TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\")" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "## Possible Solution" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 2, 41 | "metadata": {}, 42 | "outputs": [ 43 | { 44 | "name": "stdout", 45 | "output_type": "stream", 46 | "text": [ 47 | "TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\n" 48 | ] 49 | } 50 | ], 51 | "source": [ 52 | "import random\n", 53 | "\n", 54 | "\n", 55 | "def build_board(num_rows, num_cols, bomb_count=0, non_bomb_character=\"-\"):\n", 56 | " board_temp = [\"B\"] * bomb_count + [non_bomb_character] * (num_rows * num_cols - bomb_count)\n", 57 | "\n", 58 | " if bomb_count:\n", 59 | " random.shuffle(board_temp)\n", 60 | "\n", 61 | " board = []\n", 62 | " for i in range(0, num_rows*num_cols, num_cols):\n", 63 | " board.append(board_temp[i:i+num_cols])\n", 64 | " return board\n", 65 | "\n", 66 | "# Runing the tests...\n", 67 | "test_board()\n", 68 | "# Note if you recieve an error message saying test_board not found \n", 69 | "# try hitting the run button on the test_board cell and try again." 70 | ] 71 | }, 72 | { 73 | "cell_type": "markdown", 74 | "metadata": {}, 75 | "source": [ 76 | "## Explaining my code\n", 77 | "\n", 78 | "Okay guys, my code is a bit complicated to understand at first glance, but I'm going to talk you through it.\n", 79 | "\n", 80 | " board_temp = [\"B\"] * bomb_count + [non_bomb_character] * (row * col-bomb_count)\n", 81 | " \n", 82 | "So this line of code looks like a monster, but actually once you think about it is not so difficult to understand. Basically we start by making a list containing \"B\" characters, the number of \"B\"'s we add to the list is dependant on the number of bombs the board is supposed to have (which is given by the bomb count argument)." 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 9, 88 | "metadata": {}, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "text/plain": [ 93 | "['B', 'B', 'B']" 94 | ] 95 | }, 96 | "execution_count": 9, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "bomb_count = 3\n", 103 | "[\"B\"] * bomb_count" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "The next step is to multiply the row by the col to get the total number of squares our board should have. We subtract the bomb_count from this figure because we have already added those to the board and we do not wish to 'double count'. \n", 111 | "\n", 112 | "For example, if bomb_count is 10 and our board is 10x10 then we want to add 90 non-bomb characters to the list (10\\*10 - 10 = 90). The result is a list of length 100, 10 of which are bombs." 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 10, 118 | "metadata": {}, 119 | "outputs": [ 120 | { 121 | "name": "stdout", 122 | "output_type": "stream", 123 | "text": [ 124 | "['B', '-', '-', '-']\n" 125 | ] 126 | } 127 | ], 128 | "source": [ 129 | "row = 2\n", 130 | "col = 2 \n", 131 | "b_count = 1\n", 132 | "\n", 133 | "part_one_of_list = [\"B\"] * b_count\n", 134 | "part_two_of_list = [\"-\"] * (row * col-b_count)\n", 135 | "\n", 136 | "our_list = part_one_of_list + part_two_of_list\n", 137 | "\n", 138 | "print(our_list) # --> 2x2 grid with 1 bomb.\n" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "The next two lines of code are:\n", 146 | "\n", 147 | " if bomb_count:\n", 148 | " random.shuffle(board_temp)\n", 149 | "\n", 150 | "So this code shuffles the list (but only if bombs >= 1), we take a list with all the bombs at the start and we jumble them around. \n", 151 | "\n", 152 | " board = []\n", 153 | " for i in range(0, row*col, col ):\n", 154 | " board.append(board_temp[i : i+col])\n", 155 | " \n", 156 | "So this is the most complex part of my function, what are we doing here?\n", 157 | "\n", 158 | "We have a range function, which starts at 0, ends at row \\* col and has a step of size col. Next up, we use those values to slice the temp_board we made earlier. In effect this is creating a 'moving window', and this gives us our board with the correct dimensions. \n", 159 | "\n", 160 | "Lets try to visualise what is happening here by running it a few times with print statement:" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": 9, 166 | "metadata": {}, 167 | "outputs": [ 168 | { 169 | "name": "stdout", 170 | "output_type": "stream", 171 | "text": [ 172 | "['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20']\n" 173 | ] 174 | } 175 | ], 176 | "source": [ 177 | "## Create a 1d board\n", 178 | "board_temp = [str(i).zfill(2) for i in range(1,21)]\n", 179 | "print(board_temp)" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 10, 185 | "metadata": {}, 186 | "outputs": [ 187 | { 188 | "name": "stdout", 189 | "output_type": "stream", 190 | "text": [ 191 | "['01', '02', '03', '04']\n", 192 | "['05', '06', '07', '08']\n", 193 | "['09', '10', '11', '12']\n", 194 | "['13', '14', '15', '16']\n", 195 | "['17', '18', '19', '20']\n" 196 | ] 197 | } 198 | ], 199 | "source": [ 200 | "row = 5\n", 201 | "col = 4\n", 202 | "\n", 203 | "# print board with dims (5, 4)\n", 204 | "for i in range(0, row*col, col ):\n", 205 | " print(board_temp[i : i+col])" 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": 17, 211 | "metadata": {}, 212 | "outputs": [ 213 | { 214 | "name": "stdout", 215 | "output_type": "stream", 216 | "text": [ 217 | "['01', '02', '03', '04', '05', '06', '07', '08', '09']\n", 218 | "['10', '11', '12', '13', '14', '15', '16', '17', '18']\n", 219 | "['19', '20']\n" 220 | ] 221 | } 222 | ], 223 | "source": [ 224 | "row = 3\n", 225 | "col = 9\n", 226 | "\n", 227 | "# print board with dims (3, 9)\n", 228 | "for i in range(0, row*col, col ):\n", 229 | " print(board_temp[i : i+col])" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 14, 235 | "metadata": {}, 236 | "outputs": [ 237 | { 238 | "name": "stdout", 239 | "output_type": "stream", 240 | "text": [ 241 | "['01', '02']\n", 242 | "['03', '04']\n", 243 | "['05', '06']\n", 244 | "['07', '08']\n", 245 | "['09', '10']\n", 246 | "['11', '12']\n" 247 | ] 248 | } 249 | ], 250 | "source": [ 251 | "row = 6\n", 252 | "col = 2\n", 253 | "\n", 254 | "# print board with dims (6, 2)\n", 255 | "for i in range(0, row*col, col ):\n", 256 | " print(board_temp[i : i+col])" 257 | ] 258 | }, 259 | { 260 | "cell_type": "markdown", 261 | "metadata": {}, 262 | "source": [ 263 | "In the above demonstration the board consists of 20 squares. As we If change the row/col dimensions of the board you should begin to see how the code works." 264 | ] 265 | } 266 | ], 267 | "metadata": { 268 | "kernelspec": { 269 | "display_name": "Python 3", 270 | "language": "python", 271 | "name": "python3" 272 | }, 273 | "language_info": { 274 | "codemirror_mode": { 275 | "name": "ipython", 276 | "version": 3 277 | }, 278 | "file_extension": ".py", 279 | "mimetype": "text/x-python", 280 | "name": "python", 281 | "nbconvert_exporter": "python", 282 | "pygments_lexer": "ipython3", 283 | "version": "3.7.4" 284 | } 285 | }, 286 | "nbformat": 4, 287 | "nbformat_minor": 2 288 | } 289 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/_02. Printing the Board(HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "def test():\n", 10 | " \"\"\"\n", 11 | " >>> display_board([['-', 'B', '-'], ['-', 'B', 'B'], ['-', '-', '-']])\n", 12 | " ['-', 'B', '-']\n", 13 | " ['-', 'B', 'B']\n", 14 | " ['-', '-', '-']\n", 15 | " >>> display_board([['-', 'B', '-'], ['-', 'B', 'B']])\n", 16 | " ['-', 'B', '-']\n", 17 | " ['-', 'B', 'B']\n", 18 | " >>> display_board([['-', 'B', '-','-', 'B', 'B']])\n", 19 | " ['-', 'B', '-', '-', 'B', 'B']\n", 20 | " >>> display_board([['-', '-'], ['B', '-'], ['-', '-'], ['-', 'B'], ['-', '-'], ['-', '-']])\n", 21 | " ['-', '-']\n", 22 | " ['B', '-']\n", 23 | " ['-', '-']\n", 24 | " ['-', 'B']\n", 25 | " ['-', '-']\n", 26 | " ['-', '-']\n", 27 | " >>> display_board([['B']])\n", 28 | " ['B']\n", 29 | " \"\"\"\n", 30 | " import doctest\n", 31 | " doctest.testmod()\n", 32 | " print(\"TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\")" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "metadata": {}, 38 | "source": [ 39 | "## Possible Solution" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 2, 45 | "metadata": {}, 46 | "outputs": [ 47 | { 48 | "name": "stdout", 49 | "output_type": "stream", 50 | "text": [ 51 | "TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\n" 52 | ] 53 | } 54 | ], 55 | "source": [ 56 | "def display_board(board):\n", 57 | " for row in board:\n", 58 | " print(row)\n", 59 | " \n", 60 | "# Runing the tests...\n", 61 | "test()\n", 62 | "# Note if you recieve an error message saying test_board not found \n", 63 | "# try hitting the run button on the test_board cell and try again." 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "## Alternate Solution" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 3, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\n" 83 | ] 84 | } 85 | ], 86 | "source": [ 87 | "def display_board(board):\n", 88 | " print(*board, sep=\"\\n\")\n", 89 | " \n", 90 | "# Runing the tests...\n", 91 | "test()\n", 92 | "# Note if you recieve an error message saying test_board not found \n", 93 | "# try hitting the run button on the test_board cell and try again." 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "The alternate solution uses a concept we haven't seen in this course, if you want to know how it works you need to google \"unpacking\" in Python. \n", 101 | "\n", 102 | "You might be wondering why this function was so easy for me. Well, the answer is because I have already done the hard-work creating a 2d board in homework 1. And since I have a 2D board already defined all I need to do here is print what I already have. " 103 | ] 104 | } 105 | ], 106 | "metadata": { 107 | "kernelspec": { 108 | "display_name": "Python 3", 109 | "language": "python", 110 | "name": "python3" 111 | }, 112 | "language_info": { 113 | "codemirror_mode": { 114 | "name": "ipython", 115 | "version": 3 116 | }, 117 | "file_extension": ".py", 118 | "mimetype": "text/x-python", 119 | "name": "python", 120 | "nbconvert_exporter": "python", 121 | "pygments_lexer": "ipython3", 122 | "version": "3.7.4" 123 | } 124 | }, 125 | "nbformat": 4, 126 | "nbformat_minor": 2 127 | } 128 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/_03. Defining Helper Functions(HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "def test():\n", 12 | " \"\"\"\n", 13 | " >>> get_square(0,1, [[\"-\",\"YES!\", \"-\", \"-\"], [\"-\",\"-\",\"-\"]])\n", 14 | " 'YES!'\n", 15 | " >>> get_square(0, 0, [[\"B\"]])\n", 16 | " 'B'\n", 17 | " \n", 18 | " >>> b = [[\"B\"]]\n", 19 | " >>> set_square(0, 0, \"X\", b) \n", 20 | " >>> b[0][0] == \"X\"\n", 21 | " True\n", 22 | " >>> get_square(0,0, b)\n", 23 | " 'X'\n", 24 | " \n", 25 | " >>> board = [['0', '1', '2', '3', '4', '5'], ['6', '7', '8', '9', '10', '11']]\n", 26 | " >>> get_square(0,2, board)\n", 27 | " '2'\n", 28 | " >>> set_square(0,5, 'This', board)\n", 29 | " >>> get_square(1,2, board)\n", 30 | " '8'\n", 31 | " >>> set_square(1,0, 'is', board)\n", 32 | " >>> get_square(1,3, board)\n", 33 | " '9'\n", 34 | " >>> set_square(1, 5, 'sparta', board)\n", 35 | " >>> board\n", 36 | " [['0', '1', '2', '3', '4', 'This'], ['is', '7', '8', '9', '10', 'sparta']]\n", 37 | " \"\"\"\n", 38 | " \n", 39 | " # IndexErrors raised?\n", 40 | " try:\n", 41 | " get_square(1, 0, [[1,2,3,4,5,6,7,8]])\n", 42 | " print(\"TEST FAIL, IndexError not raised\")\n", 43 | " except IndexError:\n", 44 | " pass\n", 45 | " try:\n", 46 | " set_square(1, 0, \"X\", [[1,2,3,4,5,6,7,8]])\n", 47 | " print(\"TEST FAIL, IndexError not raised\")\n", 48 | " except IndexError:\n", 49 | " pass\n", 50 | " \n", 51 | " import doctest\n", 52 | " doctest.testmod()\n", 53 | " print(\"TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\")" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 2, 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "TESTING COMPLETE... if you see nothing, (other than this message) that means all tests passed.\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "def get_square(x, y, board):\n", 71 | " \"\"\"\n", 72 | " This function takes a board and returns the value at that square(x,y).\n", 73 | " \"\"\"\n", 74 | " return board[x][y]\n", 75 | "\n", 76 | "def set_square(x, y, new_val, board):\n", 77 | " \"\"\"\n", 78 | " This function indexes into the given board at position (x, y).\n", 79 | " We then change that value to new_val. Returns nothing.\n", 80 | " \"\"\"\n", 81 | " board[x][y] = new_val\n", 82 | " \n", 83 | "# Runing the tests...\n", 84 | "test()\n", 85 | "# Note if you recieve an error message saying test_board not found \n", 86 | "# try hitting the run button on the test_board cell and try again." 87 | ] 88 | } 89 | ], 90 | "metadata": { 91 | "kernelspec": { 92 | "display_name": "Python 3", 93 | "language": "python", 94 | "name": "python3" 95 | }, 96 | "language_info": { 97 | "codemirror_mode": { 98 | "name": "ipython", 99 | "version": 3 100 | }, 101 | "file_extension": ".py", 102 | "mimetype": "text/x-python", 103 | "name": "python", 104 | "nbconvert_exporter": "python", 105 | "pygments_lexer": "ipython3", 106 | "version": "3.7.4" 107 | } 108 | }, 109 | "nbformat": 4, 110 | "nbformat_minor": 2 111 | } 112 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Final Project (Minesweeper)/_04. Getting the Neighbours(HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## TEST CASES..." 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 45, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "def test_neighbour_squares():\n", 17 | " \n", 18 | " actual = neighbour_squares(0, 0, 1, 1)\n", 19 | " expected = []\n", 20 | " assert actual == expected\n", 21 | " \n", 22 | " actual2 = neighbour_squares(0, 0, 2, 1)\n", 23 | " expected2 = [(0, 1)]\n", 24 | " assert actual2 == expected2, \"jklj\" #str(actual2)\n", 25 | " \n", 26 | " actual3 = neighbour_squares(0, 0, 1, 2)\n", 27 | " expected3 = [(1, 0)]\n", 28 | " assert actual3 == expected3\n", 29 | " \n", 30 | " actual4 = sorted(neighbour_squares(0, 0, 2, 2))\n", 31 | " expected4 = sorted([(0, 1), (1, 0), (1, 1)])\n", 32 | " assert actual4 == expected4\n", 33 | " \n", 34 | " actual5 = sorted(neighbour_squares(1, 1, 4, 4))\n", 35 | " expected5 = sorted([(0, 0), (1, 0), (0, 1), (2, 2), (1,2), (2,1), (0,2), (2,0)])\n", 36 | " assert actual5 == expected5\n", 37 | "\n", 38 | " \n", 39 | "def test_count_bombs():\n", 40 | " b = [[\"B\", \"_\", \"B\"],\n", 41 | " [\"_\", \"B\", \"B\"]]\n", 42 | "\n", 43 | " assert count_bombs(0, 0, b) == 1\n", 44 | " assert count_bombs(1, 2, b) == 2\n", 45 | " assert count_bombs(1, 0, b) == 4\n", 46 | "\n", 47 | " b2 = [[\"B\"],\n", 48 | " [\"-\"],\n", 49 | " [\"B\"]]\n", 50 | "\n", 51 | " assert count_bombs(0, 0, b2) == 0\n", 52 | " assert count_bombs(0, 1, b2) == 2\n", 53 | "\n", 54 | " b3 = [[\"B\",\"-\",\"-\",\"B\",\"B\",\"-\"]]\n", 55 | "\n", 56 | " assert count_bombs(0, 0, b3) == 0\n", 57 | " assert count_bombs(2, 0, b3) == 1\n", 58 | "\n", 59 | "\n", 60 | " print(\"Testing Complete\")" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "## Possible Solution" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 47, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "name": "stdout", 77 | "output_type": "stream", 78 | "text": [ 79 | "Testing Complete\n" 80 | ] 81 | } 82 | ], 83 | "source": [ 84 | "def neighbour_squares(x, y, num_rows, num_cols):\n", 85 | " \"\"\"\n", 86 | " (x, y) 0-based index co-ordinate pair.\n", 87 | " num_rows, num_cols: specifiy the max size of the board\n", 88 | " \n", 89 | " returns all valid (x, y) coordinates from starting position.\n", 90 | " \"\"\"\n", 91 | " offsets = [(-1,-1), (-1,0), (-1,1),\n", 92 | " ( 0,-1), ( 0,1),\n", 93 | " ( 1,-1), ( 1,0), ( 1,1)]\n", 94 | " \n", 95 | " result = []\n", 96 | " for x2, y2 in offsets:\n", 97 | " \n", 98 | " px = x + x2\n", 99 | " py = y + y2\n", 100 | " \n", 101 | " row_check = 0 <= px < num_rows\n", 102 | " col_check = 0 <= py < num_cols\n", 103 | " \n", 104 | " if row_check and col_check:\n", 105 | " point = (py, px)\n", 106 | " result.append(point)\n", 107 | " \n", 108 | " return result\n", 109 | " \n", 110 | "def count_bombs(x, y, board):\n", 111 | " \"\"\"\n", 112 | " returns the number of neighbours of (x,y) that are bombs. Max is 8, min is 0.\n", 113 | " \"\"\"\n", 114 | " num_rows = len(board[0])\n", 115 | " num_cols = len(board)\n", 116 | " \n", 117 | " squares = neighbour_squares(x, y, num_rows, num_cols)\n", 118 | "\n", 119 | " bombs_found = 0\n", 120 | " for px, py in squares:\n", 121 | " if board[px][py] == \"B\":\n", 122 | " bombs_found += 1\n", 123 | " \n", 124 | " return bombs_found\n", 125 | " \n", 126 | " \n", 127 | "# Testing...\n", 128 | "test_neighbour_squares()\n", 129 | "test_count_bombs()" 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "metadata": {}, 135 | "source": [ 136 | "## Explanation\n", 137 | "\n", 138 | "### Neighbour Squares\n", 139 | "\n", 140 | "'neighbour_squares' takes an (x, y) pair co-ordinate and returns the neighbours of that square. Often a square has eight neighbors (up left, up right, below, below right, etc), however squares on the edge of the board have fewer. The purpose of \"row_check\" and \"col_check\" is to help avoid possible index errors later on and also avoids a possible bug where the index is negative. For example:\n", 141 | "\n", 142 | "\n", 143 | " [1,2,3]\n", 144 | " [4,5,6]\n", 145 | " [7,8,9]\n", 146 | "\n", 147 | "square(3) has an index of (0,2). If we subtract 1 from both sides we get (-1,1). And the index (-1,1) is equivalent to (2,1), thus we end saying the neighbour of square(3) is square(8). This is only desirable in the cases where we want the edges of the board to 'wrap round'. \n", 148 | "\n", 149 | "Carving this logic out into its own function (as opposed to doing everything in the count_bombs function) allows us to be flexible and this code can be reused (notice that \"neighbour_squares\" doesn't even take a board as an argument). \n", 150 | "\n", 151 | "\n", 152 | "### Count Bombs\n", 153 | "\n", 154 | "The 'count_bombs' function takes an (x,y) position and a board. If then returns how many neighbour squares are in fact bombs. This function can however be improved. \n", 155 | "\n", 156 | "You may remember me saying in the design lecture that its usually better to give a function a name that describes what it does and not what it is used for. This functions name (\"count_bombs\") makes this mistake. To fix this problem, we have to ask ourselves:\n", 157 | "\n", 158 | " \"What this function is actually doing?\"\n", 159 | " \n", 160 | "Here's what it is not doing: counting_bombs. A bomb in our current implementation is simply the string \"B\". So what this function is actually doing is counting how many occurrences of the string \"B\" there are. That's not a very useful function. A much more useful function would be to count any arbitrary character. So let's change the function name and signature to better reflect this new understanding\n", 161 | "\n", 162 | " def count_occurence_of_character_in_neighbour_squares(x, y, array, character):\n", 163 | " ...\n", 164 | " \n", 165 | "And thats a function that we could use easily in a chess game:\n", 166 | "\n", 167 | " ENEMY_PIECE = \"P\"\n", 168 | " \n", 169 | " chess_board = [\"_, \"P\", _]\n", 170 | " [\"k\", \"P, _]\n", 171 | " \n", 172 | " def can_king_capture_piece(king_position_x, king_position_y, chess_board):\n", 173 | " \n", 174 | " possible_captures = count_occurence_of_character_in_neighbour_squares(king_position_x, \n", 175 | " king_position_y, \n", 176 | " chess_board, \n", 177 | " ENEMY_PIECE)\n", 178 | " \n", 179 | " return possible_captures.\n", 180 | " \n", 181 | " \n", 182 | "And it is also a function we could use in a sudoku game to check if a 3x3 grid is correct (or not):\n", 183 | "\n", 184 | " def is_3x3_correct(mid_point_x, mid_point_y, grid):\n", 185 | " \n", 186 | " for number in range(1, 10):\n", 187 | " if count_occurence_of_character_in_neighbour_squares(mid_point_x, mid_point_y, grid, str(number)) != 1:\n", 188 | " return False # number is either missing or there are duplicates\n", 189 | " \n", 190 | " return True\n", 191 | "\n", 192 | "Hopefully those two additional examples illustrate how writing flexible code is useful. By thinking about that the function does (as opposed to concentrating on how we use it) we were able to make the code significantly more flexible with minimal work. And it doesn't take that much effort to imagine scenarios where we might want to use such a function. \n", 193 | "\n", 194 | "The final improvement I can think of that is worth mentioning is that in the previous homework we actually wrote helper functions that could get a value at a given square. Since we already have that function we may as well use it." 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": null, 200 | "metadata": {}, 201 | "outputs": [], 202 | "source": [ 203 | "def get_square(x, y, board):\n", 204 | " \"\"\"\n", 205 | " This function takes a board and returns the value at that square(x,y).\n", 206 | " \"\"\"\n", 207 | " return board[x][y]\n", 208 | "\n", 209 | "def count_occurence_of_character_in_neighbour_squares(x, y, board, character):\n", 210 | " \"\"\"\n", 211 | " returns the number of neighbours of (x,y) that are bombs. Max is 8, min is 0.\n", 212 | " \"\"\"\n", 213 | " num_rows = len(board[0])\n", 214 | " num_cols = len(board)\n", 215 | " \n", 216 | " squares = neighbour_squares(x, y, num_rows, num_cols)\n", 217 | "\n", 218 | " character_found = 0\n", 219 | " for px, py in squares:\n", 220 | " \n", 221 | " square_value = get_square(px, py, board)\n", 222 | " \n", 223 | " if square_value == character:\n", 224 | " character_found += 1\n", 225 | " \n", 226 | " return character_found" 227 | ] 228 | } 229 | ], 230 | "metadata": { 231 | "kernelspec": { 232 | "display_name": "Python 3", 233 | "language": "python", 234 | "name": "python3" 235 | }, 236 | "language_info": { 237 | "codemirror_mode": { 238 | "name": "ipython", 239 | "version": 3 240 | }, 241 | "file_extension": ".py", 242 | "mimetype": "text/x-python", 243 | "name": "python", 244 | "nbconvert_exporter": "python", 245 | "pygments_lexer": "ipython3", 246 | "version": "3.7.4" 247 | } 248 | }, 249 | "nbformat": 4, 250 | "nbformat_minor": 2 251 | } 252 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Graphics/BugTime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/A Beginners Guide to Python/Graphics/BugTime.png -------------------------------------------------------------------------------- /A Beginners Guide to Python/Graphics/Errordebug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/A Beginners Guide to Python/Graphics/Errordebug.png -------------------------------------------------------------------------------- /A Beginners Guide to Python/Graphics/Google It.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/A Beginners Guide to Python/Graphics/Google It.png -------------------------------------------------------------------------------- /A Beginners Guide to Python/Graphics/IndexPic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/A Beginners Guide to Python/Graphics/IndexPic.png -------------------------------------------------------------------------------- /A Beginners Guide to Python/Graphics/Truth_table_for_AND,_OR,_and_NOT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/A Beginners Guide to Python/Graphics/Truth_table_for_AND,_OR,_and_NOT.png -------------------------------------------------------------------------------- /A Beginners Guide to Python/Graphics/indentguide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/A Beginners Guide to Python/Graphics/indentguide.png -------------------------------------------------------------------------------- /A Beginners Guide to Python/Graphics/indentguide2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/A Beginners Guide to Python/Graphics/indentguide2.png -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/.ipynb_checkpoints/08. Calling Functions (HW)-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Homework\n", 8 | "\n", 9 | "In the cell below there is a function called \"call me\". For homework I want you to call this function with several arguments such that it returns the string:\n", 10 | "\n", 11 | " \"Dave and Jerry went to the cheese factory.\"" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 4, 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "data": { 21 | "text/plain": [ 22 | "'Dave and Jerry went to the cheese factory.'" 23 | ] 24 | }, 25 | "execution_count": 4, 26 | "metadata": {}, 27 | "output_type": "execute_result" 28 | } 29 | ], 30 | "source": [ 31 | "def call_me(a, f, d, b=\"\", c=\"cheese\", e=False):\n", 32 | " if e == True:\n", 33 | " return \"{} and {} went to the {}{} {}.\".format(a, b, c, d, f)\n", 34 | " else:\n", 35 | " return \"YOU SHALL NOT PASS\"\n", 36 | "\n", 37 | "## Solution:\n", 38 | "\n", 39 | "call_me(\"Dave\", \"factory\", \"\", b=\"Jerry\", e=True)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [] 48 | } 49 | ], 50 | "metadata": { 51 | "kernelspec": { 52 | "display_name": "Python 3", 53 | "language": "python", 54 | "name": "python3" 55 | }, 56 | "language_info": { 57 | "codemirror_mode": { 58 | "name": "ipython", 59 | "version": 3 60 | }, 61 | "file_extension": ".py", 62 | "mimetype": "text/x-python", 63 | "name": "python", 64 | "nbconvert_exporter": "python", 65 | "pygments_lexer": "ipython3", 66 | "version": "3.7.4" 67 | } 68 | }, 69 | "nbformat": 4, 70 | "nbformat_minor": 2 71 | } 72 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/03. Hello World (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Hello World, Homework Problem\n", 8 | "\n", 9 | "For your homework, in the box below I want you to print out the phrase in the console below:\n", 10 | "\n", 11 | "> MY HUMAN UNDERSTANDS ME" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## Example Solution" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 1, 24 | "metadata": {}, 25 | "outputs": [ 26 | { 27 | "name": "stdout", 28 | "output_type": "stream", 29 | "text": [ 30 | "MY HUMAN UNDERSTANDS ME\n" 31 | ] 32 | } 33 | ], 34 | "source": [ 35 | "print(\"MY HUMAN UNDERSTANDS ME\")" 36 | ] 37 | } 38 | ], 39 | "metadata": { 40 | "kernelspec": { 41 | "display_name": "Python 3", 42 | "language": "python", 43 | "name": "python3" 44 | }, 45 | "language_info": { 46 | "codemirror_mode": { 47 | "name": "ipython", 48 | "version": 3 49 | }, 50 | "file_extension": ".py", 51 | "mimetype": "text/x-python", 52 | "name": "python", 53 | "nbconvert_exporter": "python", 54 | "pygments_lexer": "ipython3", 55 | "version": "3.5.2" 56 | } 57 | }, 58 | "nbformat": 4, 59 | "nbformat_minor": 2 60 | } 61 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/05. Assignment (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Homework\n", 8 | "\n", 9 | "1. create a variable called \"my_name\". Its value should be your name (a string).\n", 10 | "2. create a variable called \"kitchen_utensil\". its value should be your favourite kitchen tool. Personally, I like a good spoon (a string).\n", 11 | "3. Now type into python: \n", 12 | " print(\"Hello, my name is \" + my_name + \" and one time, at band-camp, I used a \" + kitchen_utensil + \".\")\n", 13 | " \n", 14 | "## Possible Solution" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 5, 20 | "metadata": {}, 21 | "outputs": [ 22 | { 23 | "name": "stdout", 24 | "output_type": "stream", 25 | "text": [ 26 | "Hello, my name is Chris and one time, at band-camp, I used a big fat shiny spoon.\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "my_name = \"Chris\"\n", 32 | "kitchen_utensil = \"big fat shiny spoon\"\n", 33 | "\n", 34 | "print(\"Hello, my name is \" + my_name + \" and one time, at band-camp, I used a \" + kitchen_utensil + \".\")" 35 | ] 36 | } 37 | ], 38 | "metadata": { 39 | "kernelspec": { 40 | "display_name": "Python 3", 41 | "language": "python", 42 | "name": "python3" 43 | }, 44 | "language_info": { 45 | "codemirror_mode": { 46 | "name": "ipython", 47 | "version": 3 48 | }, 49 | "file_extension": ".py", 50 | "mimetype": "text/x-python", 51 | "name": "python", 52 | "nbconvert_exporter": "python", 53 | "pygments_lexer": "ipython3", 54 | "version": "3.5.2" 55 | } 56 | }, 57 | "nbformat": 4, 58 | "nbformat_minor": 2 59 | } 60 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/06. Names (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Names, Homework\n", 8 | "\n", 9 | "Below is three lines of python code, the only thing you have seen yet is the \"*\" symbol which means multiplication. Your task comes in three parts:\n", 10 | "\n", 11 | "1. Figure out what the code is supposed to do. *(this might take some googling hint: think circles!)*\n", 12 | "2. Add a comment or two, explaining what it does.\n", 13 | "2. Change the name \"belt_size\" and \"cake\" to something more meaningful." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": { 20 | "collapsed": true 21 | }, 22 | "outputs": [], 23 | "source": [ 24 | "cake = 3.14\n", 25 | "diameter = 2\n", 26 | "\n", 27 | "belt_size = cake * diameter" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "# Example Solution" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 2, 40 | "metadata": { 41 | "collapsed": true 42 | }, 43 | "outputs": [], 44 | "source": [ 45 | "# calculate the circumference of a circle\n", 46 | "pi = 3.14\n", 47 | "diameter = 2\n", 48 | "\n", 49 | "circumference = pi * diameter" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "# Even Better Solution" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "PI = 3.14\n", 66 | "diameter = 2\n", 67 | "\n", 68 | "circumference = PI * diameter" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "So this solution is a bit better because pi is a mathmatical constant, and so therefore should probably be made into a constant. Which means the name should be in all-caps. I also removed the comment because I think what the code does is clearr from the context." 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [] 84 | } 85 | ], 86 | "metadata": { 87 | "kernelspec": { 88 | "display_name": "Python 3", 89 | "language": "python", 90 | "name": "python3" 91 | }, 92 | "language_info": { 93 | "codemirror_mode": { 94 | "name": "ipython", 95 | "version": 3 96 | }, 97 | "file_extension": ".py", 98 | "mimetype": "text/x-python", 99 | "name": "python", 100 | "nbconvert_exporter": "python", 101 | "pygments_lexer": "ipython3", 102 | "version": "3.7.4" 103 | } 104 | }, 105 | "nbformat": 4, 106 | "nbformat_minor": 2 107 | } 108 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/08. Calling Functions (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Homework\n", 8 | "\n", 9 | "In the cell below there is a function called \"call me\". For homework I want you to call this function with several arguments such that it returns the string:\n", 10 | "\n", 11 | " \"Dave and Jerry went to the cheese factory.\"" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 4, 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "data": { 21 | "text/plain": [ 22 | "'Dave and Jerry went to the cheese factory.'" 23 | ] 24 | }, 25 | "execution_count": 4, 26 | "metadata": {}, 27 | "output_type": "execute_result" 28 | } 29 | ], 30 | "source": [ 31 | "def call_me(a, f, d, b=\"\", c=\"cheese\", e=False):\n", 32 | " if e == True:\n", 33 | " return \"{} and {} went to the {}{} {}.\".format(a, b, c, d, f)\n", 34 | " else:\n", 35 | " return \"YOU SHALL NOT PASS\"\n", 36 | "\n", 37 | "## Solution:\n", 38 | "\n", 39 | "call_me(\"Dave\", \"factory\", \"\", b=\"Jerry\", e=True)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [] 48 | } 49 | ], 50 | "metadata": { 51 | "kernelspec": { 52 | "display_name": "Python 3", 53 | "language": "python", 54 | "name": "python3" 55 | }, 56 | "language_info": { 57 | "codemirror_mode": { 58 | "name": "ipython", 59 | "version": 3 60 | }, 61 | "file_extension": ".py", 62 | "mimetype": "text/x-python", 63 | "name": "python", 64 | "nbconvert_exporter": "python", 65 | "pygments_lexer": "ipython3", 66 | "version": "3.7.4" 67 | } 68 | }, 69 | "nbformat": 4, 70 | "nbformat_minor": 2 71 | } 72 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/10. Strings (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Homework:\n", 8 | "\n", 9 | "Name a variable \"cool_story_bro\" and then assign the the following text as a string:\n", 10 | "\n", 11 | ">\"Ahhh!!!! spiders!\", cried the monster.\"Don't worry\" said our hero, \"I have a sharp spoon\".\n", 12 | "\n", 13 | "Once complete, print it.\n", 14 | "\n", 15 | "## Possible Solutions:" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 10, 21 | "metadata": {}, 22 | "outputs": [ 23 | { 24 | "name": "stdout", 25 | "output_type": "stream", 26 | "text": [ 27 | "\"Ahhh!!!! spiders!\", cried the monster.\"Don't worry\" said our hero, \"I have a sharp spoon\".\n" 28 | ] 29 | } 30 | ], 31 | "source": [ 32 | "# Solution One: Triple Quotes!!\n", 33 | "cool_story_bro = \"\"\"\"Ahhh!!!! spiders!\", cried the monster.\"Don't worry\" said our hero, \"I have a sharp spoon\".\"\"\"\n", 34 | "print(cool_story_bro)" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "I’ll be honest, the above solution of using triple-quotes isn’t something I knew about before making the guide. As it turns out this is a really neat solution I think, its clean, readable, and above all simple. " 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 11, 47 | "metadata": {}, 48 | "outputs": [ 49 | { 50 | "name": "stdout", 51 | "output_type": "stream", 52 | "text": [ 53 | "\"Ahhh!!!! spiders!\", cried the monster.\"Don't worry\" said our hero, \"I have a sharp spoon\".\n" 54 | ] 55 | } 56 | ], 57 | "source": [ 58 | "# Solution Two: Escape characters...\n", 59 | "cool_story_bro = '\"Ahhh!!!! spiders!\", cried the monster.\"Don\\'t worry\" said our hero, \"I have a sharp spoon\".'\n", 60 | "print(cool_story_bro)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "For this solution we use the single quote character to enclose the string and then we use escape on the ' character in the word “Don't”. \n", 68 | "\n", 69 | " “...Don’t...” ---> “...Don\\’t...”\n", 70 | "\n", 71 | "Another clean and simple solution." 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 14, 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "\"Ahhh!!!! spiders!\", cried the monster.\"Don't worry\" said our hero, \"I have a sharp spoon\".\n" 84 | ] 85 | } 86 | ], 87 | "source": [ 88 | "# Solution Three: Splitting up the string into seperate parts...\n", 89 | "a = '\"Ahhh!!!! spiders!\", cried the monster.\"Don'\n", 90 | "b = \"'t \"\n", 91 | "c = \"worry\"\n", 92 | "d = '\" said our hero, \"I have a sharp spoon\".'\n", 93 | "\n", 94 | "cool_story_bro = a + b + c + d\n", 95 | "print(cool_story_bro)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "This third solution of splitting the word up into parts is just plain terrible compared to the other two ways of doing it; its less readable, more complex and above all else utterly necessary.\n", 103 | "\n", 104 | "As for the best method to use, I think its a close race between solution #1 and #2, but I think #1 wins it for me because this solution is a bit more scalable. I mean think about it, if the string we are handling is part of a book we have to process then its possible that there are going to be hundreds of ‘ in the document; *David’s spoon, can’t, won’t, o’clock* are just a tiny handful of possible phrases that could exist. Do we really want to go through a manuscript to find and then correct such instances? Triple quotes are simply more economical. " 105 | ] 106 | } 107 | ], 108 | "metadata": { 109 | "kernelspec": { 110 | "display_name": "Python 3", 111 | "language": "python", 112 | "name": "python3" 113 | }, 114 | "language_info": { 115 | "codemirror_mode": { 116 | "name": "ipython", 117 | "version": 3 118 | }, 119 | "file_extension": ".py", 120 | "mimetype": "text/x-python", 121 | "name": "python", 122 | "nbconvert_exporter": "python", 123 | "pygments_lexer": "ipython3", 124 | "version": "3.5.2" 125 | } 126 | }, 127 | "nbformat": 4, 128 | "nbformat_minor": 2 129 | } 130 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/13. Strings & Methods (HW 1).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Homework Assignment #1\n", 8 | "\n", 9 | "Your first homework assignment for this week is to take the variable named \"text\" (this has been defined for you) and count the number of times \"z\" occurs AND the letter \"k\" occurs. Add those numbers up and print the result.\n", 10 | "\n", 11 | "As a further complication, we **DO NOT** care about case (e.g. ‘z’ and ‘Z’ should both be included in the count).\n", 12 | "\n", 13 | "Don’t feel bad if you struggle, this homework is a step up in difficulty compared to normal. Oh and I have also included a few test cases below that should help you figure out what do to (just in case my instructions were not clear enough).\n", 14 | "\n", 15 | "For bonus difficulty, make your code work for any letter (e.g. \"a\", \"b\" returns the count of 'a' + 'A' + 'b' + 'B')." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": null, 21 | "metadata": { 22 | "collapsed": true 23 | }, 24 | "outputs": [], 25 | "source": [ 26 | "text = \"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzZZZZeeeewwwwwwwwkKewewe2324____23!!!!!fsdffskdsdzzzzZZZZZZZZZZZZZZZZroiooioi\"\n", 27 | "\n", 28 | "# Simple Examples (string --> total you should return)\n", 29 | "# \"zZ\" --> 2\n", 30 | "# \"kK\" --> 2\n", 31 | "# \"KZ\" --> 2\n", 32 | "# \"1aZZZabc\" --> 3\n", 33 | "# \"hello\" --> 0\n", 34 | "# \"ZzKk\" --> 4\n", 35 | "\n", 36 | "\n", 37 | "# Your code goes here..." 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "## Possible Solutions..." 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 4, 50 | "metadata": {}, 51 | "outputs": [ 52 | { 53 | "name": "stdout", 54 | "output_type": "stream", 55 | "text": [ 56 | "Solution 1: 57\n", 57 | "Solution 2: 57\n", 58 | "Solution 3: 57\n", 59 | "Solution 4: 57\n" 60 | ] 61 | } 62 | ], 63 | "source": [ 64 | "text = \"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzZZZZeeeewwwwwwwwkKewewe2324____23!!!!!fsdffskdsdzzzzZZZZZZZZZZZZZZZZroiooioi\"\n", 65 | "\n", 66 | "##################################### Solution #1 ###################################\n", 67 | "\n", 68 | "a = \"Z\" # set a,b to any letter you like in order to solve the bonus problem.\n", 69 | "b = \"K\"\n", 70 | "text2 = text.upper()\n", 71 | "result = text2.count(a) + text2.count(b)\n", 72 | "print(\"Solution 1: \", result)\n", 73 | "\n", 74 | "##################################### Solution #2 ###################################\n", 75 | "\n", 76 | "a1 = \"Z\"\n", 77 | "a2 = \"z\"\n", 78 | "b1 = \"K\"\n", 79 | "b2 = \"k\"\n", 80 | "result2 = text.count(a1) + text.count(a2) + text.count(b1) + text.count(b2)\n", 81 | "print (\"Solution 2: \", result2)\n", 82 | "\n", 83 | "##################################### Solution #3 ###################################\n", 84 | "\n", 85 | "# Note, we shall cover for-loops later on in this course.\n", 86 | "\n", 87 | "seq = \"KZkz\" # <--- change this to solve bonus problem\n", 88 | "counter = 0\n", 89 | "for character in text:\n", 90 | " if character in seq:\n", 91 | " counter += 1\n", 92 | "print(\"Solution 3: \", counter)\n", 93 | "\n", 94 | "##################################### Solution #4 ###################################\n", 95 | "\n", 96 | "# Note, this is an advanced solution, I don't expect you to understand it.\n", 97 | "# I just wanted to show off, lol\n", 98 | "\n", 99 | "seq = \"KZkz\"\n", 100 | "result4 = len([i for i in text if i in seq])\n", 101 | "print(\"Solution 4: \", result4)" 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": {}, 107 | "source": [ 108 | "> Okay so what’s the best solution? \n", 109 | "\n", 110 | "Well solution #1 is more concise the solution #2, instead of looking for “kK” the code just converts everything to upper-case which means it only has to count capital letters. In order to save two or three lines of code we create a new string (or overwrite the old one) and call upper on it. For very very large strings this is probably quite slower (but still probably faster than solution #2).\n", 111 | "\n", 112 | "Solution #4 is basically looking at every character in the string and if it is a character it is looking for (e.g “K” or “z”) it adds it the list and returns the length of the list. In terms of performance this solution is building a list (which could cost a lot of memory) only to discard it and return a single number (i.e. the length of the list). On the bright-side, at just two lines of code its the most concise solution we have. \n", 113 | "\n", 114 | "Overall though, I think solution #3 is probably the best; it should be decent in terms of performance (both memory and speed) and is quite readable. " 115 | ] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 3", 121 | "language": "python", 122 | "name": "python3" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 3 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython3", 134 | "version": "3.6.3" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 2 139 | } 140 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/13. Strings & Methods (HW 2).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Homework Assignment #2\n", 8 | "\n", 9 | "Your working on a program that has a greeting message and a goodbye message for several languages. Your job is to simply make the code more elegant and readable. Do what ever you think needs doing (note, there isn't really a right/wrong awnser)." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": { 16 | "collapsed": true 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "# Make this more readable...\n", 21 | "\n", 22 | "bye_spain = \"buenas noches\"\n", 23 | "english_greeting = \"hello\"\n", 24 | "english_goodbye = \"sod off, lad\"\n", 25 | "greeting_japanese = \"konichiwa\"\n", 26 | "spanish_greeting = \"hola\"\n", 27 | "hello_in_french = \"bonjour\"\n", 28 | "japanese_bye = \"sayonara\"" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "## Possible solution #1\n", 36 | "\n", 37 | "Here we sort by language, and for each language the greeting is listed before goodbye message. Empty lines are used to separate the languages. All variable names are in the format:\n", 38 | " \n", 39 | " {language}_{greeting/goodbye} " 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": { 46 | "collapsed": true 47 | }, 48 | "outputs": [], 49 | "source": [ 50 | "spanish_greeting = \"hola\"\n", 51 | "spanish_goodbye = \"buenas noches\"\n", 52 | "\n", 53 | "japanese_greeting = \"konichiwa\"\n", 54 | "japanese_goodbye = \"sayonara\"\n", 55 | "\n", 56 | "english_greeting = \"hello\"\n", 57 | "english_goodbye = \"sod off, lad\"\n", 58 | "\n", 59 | "french_greeting = \"bonjour\"\n" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "## Possible Solution #2 \n", 67 | "\n", 68 | "listed by type(greeting/goodbye), names all standardised to be {type}_{language}. Single empty line separating greetings from goodbyes." 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "metadata": { 75 | "collapsed": true 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "greeting_english = \"hello\"\n", 80 | "greeting_spanish = \"hola\"\n", 81 | "greeting_japanese = \"konichiwa\"\n", 82 | "greeting_french = \"bonjour\"\n", 83 | "\n", 84 | "goodbye_japanese = \"sayonara\"\n", 85 | "goodbye_spanish = \"buenas noches\"\n", 86 | "goodbye_english = \"sod off, lad\"\n" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "## Whats best?\n", 94 | "\n", 95 | "This homework was about elegance and readability and thus there is a good amount of subjectivity here. For me personally I feel the #1 is a bit more elegant than #2. In my mind, if I were building a big project think it is better to group by language rather than type, but maybe either is totally fine." 96 | ] 97 | } 98 | ], 99 | "metadata": { 100 | "kernelspec": { 101 | "display_name": "Python 3", 102 | "language": "python", 103 | "name": "python3" 104 | }, 105 | "language_info": { 106 | "codemirror_mode": { 107 | "name": "ipython", 108 | "version": 3 109 | }, 110 | "file_extension": ".py", 111 | "mimetype": "text/x-python", 112 | "name": "python", 113 | "nbconvert_exporter": "python", 114 | "pygments_lexer": "ipython3", 115 | "version": "3.6.3" 116 | } 117 | }, 118 | "nbformat": 4, 119 | "nbformat_minor": 2 120 | } 121 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/17. If, else, Logic (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Homework \n", 8 | "\n", 9 | "Your challenge this week is to evaluate the following formula as fast as possible:\n", 10 | " \n", 11 | " (a or b) and ( (b and not b) or c )\n", 12 | " \n", 13 | "Where:\n", 14 | "\n", 15 | "* a takes 2 seconds to return a true/false value\n", 16 | "* b takes 3 seconds to return a true/false value\n", 17 | "* c takes 4 seconds to return a true/false value\n", 18 | "\n", 19 | "Have a bit of play and see how quickly you can make it execute. \n", 20 | "\n", 21 | "Just be careful not to change the meaning of the expression. The parenthesis, just like in maths group the elements. For example \"(a or b) and c\" is not the same as \"a or (b and c)\".\n" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 3, 27 | "metadata": {}, 28 | "outputs": [ 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "Time Taken was 9.0 secs\n", 34 | "\n", 35 | "\n" 36 | ] 37 | } 38 | ], 39 | "source": [ 40 | "import time\n", 41 | "import random\n", 42 | "from functools import partial\n", 43 | "\n", 44 | "\n", 45 | "def sleep_bool(x, b):\n", 46 | " \"\"\"\n", 47 | " waits for x secs, then returns true/false\n", 48 | " \"\"\"\n", 49 | " time.sleep(x)\n", 50 | " return b\n", 51 | "\n", 52 | "\n", 53 | "a = partial(sleep_bool, 2, True) \n", 54 | "b = partial(sleep_bool, 3, False)\n", 55 | "c = partial(sleep_bool, 4, False) \n", 56 | "\n", 57 | "\n", 58 | "t1 = time.time()\n", 59 | "expression = ( a() or b() ) and ( (b() and not b() ) or c() ) ## <-- change this line\n", 60 | "t2 = time.time()\n", 61 | "\n", 62 | "print(\"Time Taken was {} secs\".format(round(t2-t1, 1)))\n", 63 | "print(\"\\n\")\n", 64 | "\n", 65 | "## Can you beat 9 secs ??? " 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "## Possible Solution:\n", 73 | "\n", 74 | " c and (a or b)\n", 75 | " \n", 76 | "Why does this work?\n", 77 | "\n", 78 | "Firstly observe that it doesn't actually matter what b is, (b and not b) is a contradiction (always false). Since it is always false we can actually simplify the expression by getting rid of it altogether. \n", 79 | "\n", 80 | "Thus:\n", 81 | "\n", 82 | " (a or b) and ( (b and not b) or c ) \n", 83 | " \n", 84 | " which reduces to:\n", 85 | " \n", 86 | " (a or b) and (false or c)\n", 87 | " \n", 88 | " which reduces to:\n", 89 | " \n", 90 | " (a or b) and c\n", 91 | " \n", 92 | "'And' is 'associative', therefore:\n", 93 | "\n", 94 | " (a or b) and c <= is identical to => c and (a or b)\n", 95 | "\n", 96 | "Now is c and (a or b) faster/slower than (a or b) and c. The awnser depends on the input. Which we can see below (note cf means c = false, ctf means it doesn't matter whether c is true or false). \n", 97 | "\n", 98 | " c and (a or b)\n", 99 | " \n", 100 | " cf, atf, btf ==> 4 secs\n", 101 | " ct, af, btf ==> 9 secs\n", 102 | " ct, at, btf ==> 6 secs\n", 103 | "\n", 104 | " (a or b) and c\n", 105 | " \n", 106 | " at, btf, ctf ==> 6 secs\n", 107 | " af, bt, ctf ==> 9 secs\n", 108 | " af, bf, ctf ==> 5 secs\n", 109 | "\n", 110 | "This analysis shows that c and (a or b) is slightly faster, on average for the given timings. As a general rule, sometimes all you can do is improve performance 'on average'. Lazy evaluation doesn't always work, and trying to optimise for it is sometimes very tricky. \n", 111 | "\n", 112 | "In such cases, your best bet is to optimise for readability instead of performance. To that end, I'd argue that c and (a or b) is the better choice in terms of readability. Why? Well the main reason is that if another developer looks at the code and sees (a or b) and c one of the first things they might try is to swap the terms because listing c first just 'feels more correct'. " 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [] 121 | } 122 | ], 123 | "metadata": { 124 | "kernelspec": { 125 | "display_name": "Python 3", 126 | "language": "python", 127 | "name": "python3" 128 | }, 129 | "language_info": { 130 | "codemirror_mode": { 131 | "name": "ipython", 132 | "version": 3 133 | }, 134 | "file_extension": ".py", 135 | "mimetype": "text/x-python", 136 | "name": "python", 137 | "nbconvert_exporter": "python", 138 | "pygments_lexer": "ipython3", 139 | "version": "3.7.4" 140 | } 141 | }, 142 | "nbformat": 4, 143 | "nbformat_minor": 2 144 | } 145 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/18. Indentation (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Homework Assignment\n", 8 | "\n", 9 | "Directly below is houses and kittens, a D&D knock-off. The game was ready to be published by unfortunately mysterious computer pixies (sometimes known as 'byte imps') have messed up the indentation of the code and it no longer works. On the bright-side the byte imps have only tinkered with the indentation and nothing else.\n", 10 | "\n", 11 | "With this knowledge can you fix the game?" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": { 18 | "collapsed": true 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "## HOUSES AND KITTENS, A D&D KNOCK-OFF ### \n", 23 | "\n", 24 | "#### THIS CODE IS A MESS, FIX THE INDENTATION\n", 25 | "\n", 26 | " quest = \"KILL KITTEN\"\n", 27 | " current_xp = 20\n", 28 | "next_level_xp = 100\n", 29 | " weapon_of_choice = \"sponge mallet\"\n", 30 | " is_dead = False\n", 31 | " attack_dmg = 10\n", 32 | " enemy_health = 10\n", 33 | "\n", 34 | "print('\\nGAMEMASTER says: \"{} does {} and the enemy has {} health do you want to attack?\"\\n'.format(weapon_of_choice, attack_dmg, enemy_health))\n", 35 | " atk = input('Enter \"Y\" to attack, else \"N\"')\n", 36 | " do_attack = True if atk == \"Y\" else False\n", 37 | "\n", 38 | "\n", 39 | "if do_attack:\n", 40 | " enemy_health -= attack_dmg\n", 41 | " if enemy_health == 0:\n", 42 | "is_dead = True\n", 43 | "\n", 44 | " if is_dead:\n", 45 | " print('INKEEPER says: \"OMG WHAT DID YOU DO!!!!, WHY DID YOU KILL THAT POOR LITTLE KITTEN WITH YOUR {}? ..YOU..MONSTER!!!\"'.format(weapon_of_choice.upper()))\n", 46 | " if quest == \"KILL KITTEN\":\n", 47 | " print('\\nGAMEMASTER says: \"Our brave hero completes his quest. + 80 xp\"\\n')\n", 48 | " current_xp += 80\n", 49 | " print('INKEEPER says: \"I have a baby seal in the swimming pool if you want to club that too?\"'.format(weapon_of_choice))\n", 50 | "\n", 51 | " new_quest_accept = input('GAMEMASTER says: \"DO YOU ACCEPT THE CLUB POOR SEAL QUEST? Type Y or N\"\\n') \n", 52 | "\n", 53 | " if new_quest_accept == \"Y\":\n", 54 | " quest = \"CLUB BABY SEAL\"\n", 55 | " print('INKEEPER says: \"YES!? I was being sarcastic you twit, why on earth would I give you a quest to harm by baby seal?\"')\n", 56 | " else:\n", 57 | " print('INKEEPER says: \"NO? Well THANKYOU for not killing every living thing in my house. Speaking of which, Why are you even in my house? GET OUT GET OUT YOU FOUL BEAST!!\"')\n", 58 | "\n", 59 | " elif do_attack and not is_dead:\n", 60 | "print('INKEEPER says: \"SNUFFLES!!! WHAT DID HE DO TO YOU!!! SOMEONE PLEASE FETCH A CAT DOCTOR\"')\n", 61 | "\n", 62 | " if current_xp == next_level_xp:\n", 63 | " print('\\nGAMEMASTER says: \"LEVEL UP!!, {} now does +2 attack\"\\n'.format(weapon_of_choice))\n", 64 | " attack_dmg += 2\n", 65 | "\n", 66 | " else:\n", 67 | "print('INKEEPER says: \"Thankyou kind sir for not maiming my little kitten with your {}\"'.format(weapon_of_choice))\n" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "## Example Solution" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 1, 80 | "metadata": {}, 81 | "outputs": [ 82 | { 83 | "name": "stdout", 84 | "output_type": "stream", 85 | "text": [ 86 | "\n", 87 | "GAMEMASTER says: \"sponge mallet does 10 and the enemy has 10 health do you want to attack?\"\n", 88 | "\n", 89 | "Enter \"Y\" to attack, else \"N\"Y\n", 90 | "INKEEPER says: \"OMG WHAT DID YOU DO!!!!, WHY DID YOU KILL THAT POOR LITTLE KITTEN WITH YOUR SPONGE MALLET? ..YOU..MONSTER!!!\"\n", 91 | "\n", 92 | "GAMEMASTER says: \"Our brave hero completes his quest. + 80 xp\"\n", 93 | "\n", 94 | "INKEEPER says: \"I have a baby seal in the swimming pool if you want to club that too?\"\n", 95 | "GAMEMASTER says: \"DO YOU ACCEPT THE CLUB POOR SEAL QUEST? Type Y or N\"\n", 96 | "Y\n", 97 | "INKEEPER says: \"YES!? I was being sarcastic you twit, why on earth would I give you a quest to harm by baby seal?\"\n", 98 | "\n", 99 | "GAMEMASTER says: \"LEVEL UP!!, sponge mallet now does +2 attack\"\n", 100 | "\n" 101 | ] 102 | } 103 | ], 104 | "source": [ 105 | "## HOUSES AND KITTENS, A D&D KNOCK-OFF ### \n", 106 | "\n", 107 | "#### THIS CODE IS A MESS, FIX THE INDENTATION\n", 108 | "\n", 109 | "quest = \"KILL KITTEN\"\n", 110 | "current_xp = 20\n", 111 | "next_level_xp = 100\n", 112 | "weapon_of_choice = \"sponge mallet\"\n", 113 | "is_dead = False\n", 114 | "attack_dmg = 10\n", 115 | "enemy_health = 10\n", 116 | "\n", 117 | "print('\\nGAMEMASTER says: \"{} does {} and the enemy has {} health do you want to attack?\"\\n'.format(weapon_of_choice, attack_dmg, enemy_health))\n", 118 | "atk = input('Enter \"Y\" to attack, else \"N\"')\n", 119 | "do_attack = True if atk == \"Y\" else False\n", 120 | "\n", 121 | "\n", 122 | "if do_attack:\n", 123 | " enemy_health -= attack_dmg\n", 124 | " if enemy_health == 0:\n", 125 | " is_dead = True\n", 126 | "\n", 127 | " if is_dead:\n", 128 | " print('INKEEPER says: \"OMG WHAT DID YOU DO!!!!, WHY DID YOU KILL THAT POOR LITTLE KITTEN WITH YOUR {}? ..YOU..MONSTER!!!\"'.format(weapon_of_choice.upper()))\n", 129 | " if quest == \"KILL KITTEN\":\n", 130 | " print('\\nGAMEMASTER says: \"Our brave hero completes his quest. + 80 xp\"\\n')\n", 131 | " current_xp += 80\n", 132 | " print('INKEEPER says: \"I have a baby seal in the swimming pool if you want to club that too?\"'.format(weapon_of_choice))\n", 133 | "\n", 134 | " new_quest_accept = input('GAMEMASTER says: \"DO YOU ACCEPT THE CLUB POOR SEAL QUEST? Type Y or N\"\\n') \n", 135 | "\n", 136 | " if new_quest_accept == \"Y\":\n", 137 | " quest = \"CLUB BABY SEAL\"\n", 138 | " print('INKEEPER says: \"YES!? I was being sarcastic you twit, why on earth would I give you a quest to harm by baby seal?\"')\n", 139 | " else:\n", 140 | " print('INKEEPER says: \"NO? Well THANKYOU for not killing every living thing in my house. Speaking of which, Why are you even in my house? GET OUT GET OUT YOU FOUL BEAST!!\"')\n", 141 | "\n", 142 | " elif do_attack and not is_dead:\n", 143 | " print('INKEEPER says: \"SNUFFLES!!! WHAT DID HE DO TO YOU!!! SOMEONE PLEASE FETCH A CAT DOCTOR\"')\n", 144 | "\n", 145 | " if current_xp == next_level_xp:\n", 146 | " print('\\nGAMEMASTER says: \"LEVEL UP!!, {} now does +2 attack\"\\n'.format(weapon_of_choice))\n", 147 | " attack_dmg += 2\n", 148 | "\n", 149 | "else:\n", 150 | " print('INKEEPER says: \"Thankyou kind sir for not maiming my little kitten with your {}\"'.format(weapon_of_choice))\n" 151 | ] 152 | } 153 | ], 154 | "metadata": { 155 | "kernelspec": { 156 | "display_name": "Python 3", 157 | "language": "python", 158 | "name": "python3" 159 | }, 160 | "language_info": { 161 | "codemirror_mode": { 162 | "name": "ipython", 163 | "version": 3 164 | }, 165 | "file_extension": ".py", 166 | "mimetype": "text/x-python", 167 | "name": "python", 168 | "nbconvert_exporter": "python", 169 | "pygments_lexer": "ipython3", 170 | "version": "3.7.4" 171 | } 172 | }, 173 | "nbformat": 4, 174 | "nbformat_minor": 2 175 | } 176 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/19. For Loops (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Homework Assignment\n", 8 | "\n", 9 | "Your task this week is to make a program named \"fizzbuzz\". The rules\n", 10 | "\n", 11 | "* Your program should go through the numbers 1 to 100,\n", 12 | "* if the number is even, print \"fizz\"\n", 13 | "* if the number is divisible by 5 print \"buzz\"\n", 14 | "* if the number is both even and divisible by 5 print \"fizzbuzz\"\n", 15 | "* otherwise just print the number. \n", 16 | "\n", 17 | "**For extra points**:\n", 18 | "\n", 19 | "For extra points you need to make your code easily modifiable. I want to be able to:\n", 20 | "\n", 21 | "* change the string printed out (e.g change 'fizz' to 'dave', or some other string)\n", 22 | "* be able to change the total\n", 23 | "* change one(or both) of the rules (e.g. change the rule to be divisible by 6, not 5)\n", 24 | "\n", 25 | "However, I am a stupid robot that can only type 3 characters at a time. Therefore, to modify your code I cannot go inside it and change stuff by myself. I need you to guide my hand all the way. *(Hint you should use Pythons \"input\" Function).\n", 26 | "\n", 27 | "## Possible solution #1 (easy)" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 3, 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "name": "stdout", 37 | "output_type": "stream", 38 | "text": [ 39 | "1\n", 40 | "fizz\n", 41 | "3\n", 42 | "fizz\n", 43 | "buzz\n", 44 | "fizz\n", 45 | "7\n", 46 | "fizz\n", 47 | "9\n", 48 | "fizzbuzz\n", 49 | "11\n", 50 | "fizz\n", 51 | "13\n", 52 | "fizz\n", 53 | "buzz\n", 54 | "fizz\n", 55 | "17\n", 56 | "fizz\n", 57 | "19\n", 58 | "fizzbuzz\n", 59 | "21\n", 60 | "fizz\n", 61 | "23\n", 62 | "fizz\n", 63 | "buzz\n", 64 | "fizz\n", 65 | "27\n", 66 | "fizz\n", 67 | "29\n", 68 | "fizzbuzz\n", 69 | "31\n", 70 | "fizz\n", 71 | "33\n", 72 | "fizz\n", 73 | "buzz\n", 74 | "fizz\n", 75 | "37\n", 76 | "fizz\n", 77 | "39\n", 78 | "fizzbuzz\n", 79 | "41\n", 80 | "fizz\n", 81 | "43\n", 82 | "fizz\n", 83 | "buzz\n", 84 | "fizz\n", 85 | "47\n", 86 | "fizz\n", 87 | "49\n", 88 | "fizzbuzz\n", 89 | "51\n", 90 | "fizz\n", 91 | "53\n", 92 | "fizz\n", 93 | "buzz\n", 94 | "fizz\n", 95 | "57\n", 96 | "fizz\n", 97 | "59\n", 98 | "fizzbuzz\n", 99 | "61\n", 100 | "fizz\n", 101 | "63\n", 102 | "fizz\n", 103 | "buzz\n", 104 | "fizz\n", 105 | "67\n", 106 | "fizz\n", 107 | "69\n", 108 | "fizzbuzz\n", 109 | "71\n", 110 | "fizz\n", 111 | "73\n", 112 | "fizz\n", 113 | "buzz\n", 114 | "fizz\n", 115 | "77\n", 116 | "fizz\n", 117 | "79\n", 118 | "fizzbuzz\n", 119 | "81\n", 120 | "fizz\n", 121 | "83\n", 122 | "fizz\n", 123 | "buzz\n", 124 | "fizz\n", 125 | "87\n", 126 | "fizz\n", 127 | "89\n", 128 | "fizzbuzz\n", 129 | "91\n", 130 | "fizz\n", 131 | "93\n", 132 | "fizz\n", 133 | "buzz\n", 134 | "fizz\n", 135 | "97\n", 136 | "fizz\n", 137 | "99\n", 138 | "fizzbuzz\n" 139 | ] 140 | } 141 | ], 142 | "source": [ 143 | "for number in range(1,101): # remember, end point is exclusive\n", 144 | " fizz = \"fizz\" if number % 2 == 0 else False\n", 145 | " buzz = \"buzz\" if number % 5 == 0 else False \n", 146 | " \n", 147 | " if fizz and buzz:\n", 148 | " print(fizz + buzz)\n", 149 | " elif fizz:\n", 150 | " print(fizz)\n", 151 | " elif buzz:\n", 152 | " print(buzz)\n", 153 | " else:\n", 154 | " print(number)" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": {}, 160 | "source": [ 161 | "## Possible Solution #2 (Hard)" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 1, 167 | "metadata": {}, 168 | "outputs": [ 169 | { 170 | "name": "stdout", 171 | "output_type": "stream", 172 | "text": [ 173 | "please give me a string to replace 'fizz' with dave\n", 174 | "please give me a string to replace 'buzz' with jerry\n", 175 | "we should go up to the number...24\n", 176 | "dave should be divisble by...2\n", 177 | "jerry should be divisible by...7\n", 178 | "LET THE GAMES BEGIN!\n", 179 | "1\n", 180 | "dave\n", 181 | "3\n", 182 | "dave\n", 183 | "5\n", 184 | "dave\n", 185 | "jerry\n", 186 | "dave\n", 187 | "9\n", 188 | "dave\n", 189 | "11\n", 190 | "dave\n", 191 | "13\n", 192 | "davejerry\n", 193 | "15\n", 194 | "dave\n", 195 | "17\n", 196 | "dave\n", 197 | "19\n", 198 | "dave\n", 199 | "jerry\n", 200 | "dave\n", 201 | "23\n", 202 | "dave\n" 203 | ] 204 | } 205 | ], 206 | "source": [ 207 | "msg_1 = input(\"please give me a string to replace 'fizz' with \" )\n", 208 | "msg_2 = input(\"please give me a string to replace 'buzz' with \")\n", 209 | "game_length = int(input(\"we should go up to the number...\"))\n", 210 | "\n", 211 | "mod_1 = int(input(\"{} should be divisble by...\".format(msg_1)))\n", 212 | "mod_2 = int(input(\"{} should be divisible by...\".format(msg_2)))\n", 213 | "\n", 214 | "print(\"LET THE GAMES BEGIN!\")\n", 215 | "\n", 216 | "for number in range(1, game_length + 1):\n", 217 | " \n", 218 | " rule_1 = msg_1 if number % int(mod_1) == 0 else False\n", 219 | " rule_2 = msg_2 if number % int(mod_2) == 0 else False\n", 220 | " \n", 221 | " if rule_1 and rule_2:\n", 222 | " print(rule_1 + rule_2)\n", 223 | " \n", 224 | " elif rule_1 and not rule_2:\n", 225 | " print(rule_1)\n", 226 | " \n", 227 | " elif rule_2 and not rule_1:\n", 228 | " print(rule_2)\n", 229 | " \n", 230 | " else:\n", 231 | " print(number)" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": null, 237 | "metadata": { 238 | "collapsed": true 239 | }, 240 | "outputs": [], 241 | "source": [] 242 | } 243 | ], 244 | "metadata": { 245 | "kernelspec": { 246 | "display_name": "Python 3", 247 | "language": "python", 248 | "name": "python3" 249 | }, 250 | "language_info": { 251 | "codemirror_mode": { 252 | "name": "ipython", 253 | "version": 3 254 | }, 255 | "file_extension": ".py", 256 | "mimetype": "text/x-python", 257 | "name": "python", 258 | "nbconvert_exporter": "python", 259 | "pygments_lexer": "ipython3", 260 | "version": "3.7.4" 261 | } 262 | }, 263 | "nbformat": 4, 264 | "nbformat_minor": 2 265 | } 266 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/20. Functions (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Homework Assignment\n", 8 | "\n", 9 | "Your homework assignment this week is to write a function called 'average'. it takes a list as input and returns the arithmetic average. You should assume the list only contains numbers.\n", 10 | "\n", 11 | "It should have a docstring explaining what it does (hint: \"\"\"text\"\"\").\n", 12 | "\n", 13 | "Hints:\n", 14 | "* len(input) will give you the length of the list.\n", 15 | "* sum(input) will add everything up. \n", 16 | "* If the list is empty, return the string \"EMPTY LIST\"\n", 17 | "\n", 18 | "** FOR BONUS POINTS ** \n", 19 | "\n", 20 | "* You are ONLY allowed to use addition and for-loops (The use of LEN and SUM is not allowed!).\n", 21 | "\n", 22 | "The bonus problem is a bit tricky but I believe in you guys. Good luck!\n", 23 | "\n", 24 | "## Possible Solution (easy)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 11, 30 | "metadata": { 31 | "collapsed": true 32 | }, 33 | "outputs": [], 34 | "source": [ 35 | "def average(L):\n", 36 | " \"\"\"L is a list, we return the average of L (a float)\"\"\"\n", 37 | " if not L:\n", 38 | " return \"EMPTY LIST\"\n", 39 | " return sum(L)/len(L)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "## Possible Solution (hard)" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 10, 52 | "metadata": { 53 | "collapsed": true 54 | }, 55 | "outputs": [], 56 | "source": [ 57 | "def average2(L):\n", 58 | " \"\"\"L is a list, we return the average of L (a float)\"\"\"\n", 59 | " if not L:\n", 60 | " return \"EMPTY LIST\"\n", 61 | " \n", 62 | " total = 0 \n", 63 | " length = 0\n", 64 | " for num in L:\n", 65 | " total += num\n", 66 | " length +=1\n", 67 | " \n", 68 | " return total / length\n", 69 | "\n" 70 | ] 71 | } 72 | ], 73 | "metadata": { 74 | "kernelspec": { 75 | "display_name": "Python 3", 76 | "language": "python", 77 | "name": "python3" 78 | }, 79 | "language_info": { 80 | "codemirror_mode": { 81 | "name": "ipython", 82 | "version": 3 83 | }, 84 | "file_extension": ".py", 85 | "mimetype": "text/x-python", 86 | "name": "python", 87 | "nbconvert_exporter": "python", 88 | "pygments_lexer": "ipython3", 89 | "version": "3.7.4" 90 | } 91 | }, 92 | "nbformat": 4, 93 | "nbformat_minor": 2 94 | } 95 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/21. The Joy of Fast Cars (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## The Joy of Fast Cars, Homework Assignment\n", 8 | "\n", 9 | "In this weeks (optional) homework, your task it to try and write a bit of code that is *faster* than my code. And there is going to be two basic ways to do it; you can get you hands dirty and try some low-level optimisation or you can ditch all that and favour a high-level approach.\n", 10 | "\n", 11 | "Unlike most of the homeworks, this more about being clever than it is about understanding Python.\n", 12 | "\n", 13 | " The Challenge: BEAT MY TIME!!\n", 14 | " \n", 15 | "The below code will create a list of all *ODD* square numbers starting at 1 and ending at x. Example:\n", 16 | "\n", 17 | " If x is 100, the squares are:\n", 18 | " [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]\n", 19 | " \n", 20 | " Of which, we only want the odd numbers:\n", 21 | " [1, 9, 25, 49, 81]\n", 22 | "\n", 23 | "A few hints...\n", 24 | "* Remember that \"a and b\" can be slower than \"b and a\" (see logic lecture). Basically, **the order** in which you do things can make a difference.\n", 25 | "* Finding a needle in a haystack is probably slower than [BLANK] ? \n", 26 | "\n", 27 | "Please study the code below. Your jump is to either make it faster by tinkering with it. Or alternatively you may wish to use your own algorithm.\n", 28 | "\n", 29 | "### Possible Solutions:" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 5, 35 | "metadata": { 36 | "scrolled": false 37 | }, 38 | "outputs": [ 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | "CORRECTNESS TEST = PASSED\n", 44 | "...Now testing speed. Please, note, this may take a while...\n", 45 | " Also, I'd advise a margin or error of about +- 0.2 seconds\n", 46 | "\n", 47 | "-------- Solution Comparision, where input size is 50000000. -------- \n", 48 | "\n", 49 | "✿ Stats for Teacher's Squares function.\n", 50 | " 100003541 function calls in 23.496 seconds\n", 51 | "✿ Stats for Solution #1: 'Tinkering with Range' function.\n", 52 | " 50003541 function calls in 11.734 seconds\n", 53 | "✿ Stats for Solution #2: 'List comprehension of #1' function.\n", 54 | " 50000006 function calls in 11.476 seconds\n", 55 | "✿ Stats for Solution #3: 'Building, not searching' function.\n", 56 | " 3543 function calls in 0.001 seconds\n", 57 | "✿ Stats for Solution #4: 'List Comprehension of #3' function.\n", 58 | " 8 function calls in 0.000 seconds\n" 59 | ] 60 | } 61 | ], 62 | "source": [ 63 | "import sys\n", 64 | "sys.path.append(\"..\\misc\") # Adding to sys.path allows us to find \"profile_code.py\" \n", 65 | "from profile_code import profile\n", 66 | "\n", 67 | "import math \n", 68 | "\n", 69 | "##################################\n", 70 | "# BASE SOLUTION, GOTTA BEAT THIS!\n", 71 | "def hamster_squares(x):\n", 72 | " lst = [] \n", 73 | " for number in range(1, x+1): \n", 74 | " square = math.sqrt(number) \n", 75 | " if square.is_integer():\n", 76 | " if number % 2 != 0: \n", 77 | " lst.append(number) \n", 78 | " return lst\n", 79 | "\n", 80 | "# Possible Solution #1, (low-level):\n", 81 | "def my_squares(x):\n", 82 | " lst = []\n", 83 | " for number in range(1, x+1, 2): \n", 84 | " # by using a step of 2, we don't even need to test for odd/even.\n", 85 | " square = math.sqrt(number)\n", 86 | " if square.is_integer():\n", 87 | " lst.append(number)\n", 88 | " return lst\n", 89 | " \n", 90 | "# Possible Solution #2, (low-level):\n", 91 | "def my_squares2(x):\n", 92 | " # Uses the logic described in #1, but uses a list comprehension and is therefore faster.\n", 93 | " return [i for i in range(1, x+1, 2) if math.sqrt(i).is_integer()]\n", 94 | "\n", 95 | "# Possible Solution #3, (high-level)\n", 96 | "def my_squares3(x):\n", 97 | " # Here we generate the list rather than search the haystack\n", 98 | " # sqrt(n) is the same as i*i = n. \n", 99 | " # also note that i*i is odd if i is odd.\n", 100 | " # Combining these things means finding all odd squares <= x is the same as finding all odd i*i where i*i <= x\n", 101 | " lst = []\n", 102 | " for i in range(1, math.ceil(math.sqrt(x)), 2):\n", 103 | " lst.append(i*i)\n", 104 | " return lst\n", 105 | "\n", 106 | "# Possible Solution #4, (High-level, with low-level tweaking)\n", 107 | "def my_squares4(x):\n", 108 | " return [i*i for i in range(1, math.floor(math.sqrt(x)+1), 2)]\n", 109 | "\n", 110 | "\n", 111 | "################## THE CONTROL PANEL ################################\n", 112 | "#####################################################################\n", 113 | "verbose = False # set to False if you dont want the time on line-by-line basis.\n", 114 | "X = 50_000_000 \n", 115 | "# Lower X if tests are taking too long on your machine. \n", 116 | "# Raise X if you want higher accuracy.\n", 117 | "#####################################################################\n", 118 | "\n", 119 | "# CORRECTNESS TEST...\n", 120 | "k = 10000\n", 121 | "correct = hamster_squares(k) == my_squares(k) == my_squares2(k) == my_squares3(k) == my_squares4(k)\n", 122 | "\n", 123 | "# SPEED TESTS ... (just ignore this code)\n", 124 | "if correct:\n", 125 | " print(\"CORRECTNESS TEST = PASSED\")\n", 126 | " print(\"...Now testing speed. Please, note, this may take a while...\\n\", \n", 127 | " \"Also, I'd advise a margin or error of about +- 0.2 seconds\\n\")\n", 128 | " \n", 129 | " def string(i, func, detail): \n", 130 | " i = i.split(\"\\n\") \n", 131 | " s= \"✿ Stats for {} function.\\n{}\".format(func, i[2])\n", 132 | " if detail:\n", 133 | " s = s + \"\\n\" + \"\\n\".join(i[3:-7]) + \"\\n\"\n", 134 | " return s\n", 135 | " \n", 136 | " hs = profile(hamster_squares, X)\n", 137 | " print(\"-------- Solution Comparision, where input size is {}. -------- \\n\".format(X))\n", 138 | " print(string(hs, \"Teacher's Squares\", verbose))\n", 139 | " \n", 140 | " ss = profile(my_squares, X)\n", 141 | " print(string(ss, \"Solution #1: 'Tinkering with Range'\", verbose))\n", 142 | " \n", 143 | " ss2 = profile(my_squares2, X)\n", 144 | " print(string(ss2, \"Solution #2: 'List comprehension of the above'\", verbose))\n", 145 | " \n", 146 | " ss3 = profile(my_squares3, X)\n", 147 | " print(string(ss3, \"Solution #3: 'Building, not searching'\", verbose))\n", 148 | " \n", 149 | " ss4 = profile(my_squares4, X)\n", 150 | " print(string(ss4, \"Solution #4: 'List Comprehension of the above'\", verbose))\n" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "metadata": {}, 157 | "outputs": [], 158 | "source": [] 159 | } 160 | ], 161 | "metadata": { 162 | "kernelspec": { 163 | "display_name": "Python 3", 164 | "language": "python", 165 | "name": "python3" 166 | }, 167 | "language_info": { 168 | "codemirror_mode": { 169 | "name": "ipython", 170 | "version": 3 171 | }, 172 | "file_extension": ".py", 173 | "mimetype": "text/x-python", 174 | "name": "python", 175 | "nbconvert_exporter": "python", 176 | "pygments_lexer": "ipython3", 177 | "version": "3.7.4" 178 | } 179 | }, 180 | "nbformat": 4, 181 | "nbformat_minor": 2 182 | } 183 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/Homework Solutions/24. Getting Help (HW).ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Where to Get Help: Homework Assignment\n", 8 | "\n", 9 | "You need to be think a little bit about your search, the better that is the more likely you are to find what you want. Let me give you a real example I stuggled with:" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [ 17 | { 18 | "name": "stdout", 19 | "output_type": "stream", 20 | "text": [ 21 | "['ZZ', 2, 2]\n", 22 | "['ZZ', 2, 2]\n", 23 | "['ZZ', 2, 2]\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "x = [ [2] * 3 ] * 3\n", 29 | "\n", 30 | "x[0][0] = \"ZZ\"\n", 31 | "print(*x, sep=\"\\n\")" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "What I wanted to do was build a nested list, x is supposed to look like:\n", 39 | "\n", 40 | " [[2, 2, 2],\n", 41 | " [2, 2, 2],\n", 42 | " [2, 2, 2]]\n", 43 | " \n", 44 | "And then I wanted to change the value at index \\[0\\][0] but notice that instead of a single value changing the first item in every list changes. I wanted:\n", 45 | "\n", 46 | " [[\"ZZ\", 2, 2],\n", 47 | " [ 2, 2, 2],\n", 48 | " [ 2, 2, 2]]\n", 49 | " \n", 50 | "But I got:\n", 51 | "\n", 52 | " [[\"ZZ\", 2, 2],\n", 53 | " [\"ZZ\", 2, 2],\n", 54 | " [\"ZZ\", 2, 2]]\n", 55 | "\n", 56 | "Wierd right?\n", 57 | "\n", 58 | "Your homework for this week it to search google for an awnser to this problem. **Why** doesn't X behave like I want it too and what to I need to make it work?\n", 59 | "\n", 60 | "I know for a fact the awnser is on stackoverflow already (and probably hundreds of other websites too), so this is a test of your googling skills: \n", 61 | "\n", 62 | " What search query is likely to return the information you need?\n", 63 | "\n", 64 | "This excerise is a really useful I think. Through-out your programming carrear you are going to stumped on tough questions. In many cases, the fastest way to solve your issue is going to be google search. **BUT** to get the most out of a search engine is going to require you to carefully think about your problem and what query might contain the awnser." 65 | ] 66 | }, 67 | { 68 | "attachments": {}, 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "## Possible Solution\n", 73 | "\n", 74 | "Google to the rescue! Okay so let's think about this problem a little bit; what \"buzz words” might we need to feed google in order to get the answer we want?\n", 75 | "\n", 76 | "Lets try...\n", 77 | "\n", 78 | "> Python\n", 79 | "\n", 80 | "Err...yeah, I think we are going to need to be a bit more specific than that. \n", 81 | "\n", 82 | "> Python nested list\n", 83 | "\n", 84 | "This search is a bit better, I mean, from the context alone Google has probably figured out that we are not interested in snakes! But again, still probably not specific enough.\n", 85 | "\n", 86 | "> Python nested list sublist assignment\n", 87 | "\n", 88 | "This query seems decent right? It seems pretty descriptive of the problem, afterall.\n", 89 | "\n", 90 | "Lets run it!\n", 91 | "\n", 92 | "Google Search (15th June 2017)\n", 93 | "![Google%20It.png](../graphics/Google%20It.png)" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "The third hit sounds promising, lets [go there and see.](https://stackoverflow.com/questions/10941032/why-cant-i-change-only-a-single-element-in-a-nested-list-in-python)\n", 101 | "\n", 102 | "...And sure enough, it sounds like someone is dealing with the EXACT ISSUE we had. The top-voted reply not only explains the issue but also the fix.\n", 103 | "\n", 104 | "Basically, the issue is that when you write [ [0]\\*3] \\*3 ] we are actually storing a reference to the **same list**." 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 3, 110 | "metadata": {}, 111 | "outputs": [ 112 | { 113 | "name": "stdout", 114 | "output_type": "stream", 115 | "text": [ 116 | "140386886422408\n", 117 | "140386886422408\n" 118 | ] 119 | } 120 | ], 121 | "source": [ 122 | "out=[[0]*3]*3\n", 123 | "print( id(out[0]) )\n", 124 | "print( id(out[1]) ) # want to know what \"id\" is? Why not read the documentation!" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "To see what's happening lets rewrite the code to make the issue even clearer:" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": 4, 137 | "metadata": {}, 138 | "outputs": [ 139 | { 140 | "name": "stdout", 141 | "output_type": "stream", 142 | "text": [ 143 | "[2, 2, 2]\n", 144 | "[2, 2, 2]\n", 145 | "[2, 2, 2]\n", 146 | "\n", 147 | "['ZZ', 2, 2]\n", 148 | "['ZZ', 2, 2]\n", 149 | "['ZZ', 2, 2]\n" 150 | ] 151 | } 152 | ], 153 | "source": [ 154 | "a = [2] * 3\n", 155 | "x = [a] * 3\n", 156 | "print(*x, sep=\"\\n\")\n", 157 | "\n", 158 | "print()\n", 159 | "\n", 160 | "a[0] = \"ZZ\"\n", 161 | "print(*x, sep=\"\\n\")" 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "So basically the issue is was that when we write [2]\\*3 and try to add it to a list python isn't making three separate lists, rather, **its adding the same list three times!** \n", 169 | "\n", 170 | "The fix then, we need to make sure Python knows we want three separate lists, which we can do with a for loop:" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": 5, 176 | "metadata": {}, 177 | "outputs": [ 178 | { 179 | "name": "stdout", 180 | "output_type": "stream", 181 | "text": [ 182 | "[2, 2, 2]\n", 183 | "[2, 2, 2]\n", 184 | "[2, 2, 2]\n", 185 | "\n", 186 | "['ZZ', 2, 2]\n", 187 | "[2, 2, 2]\n", 188 | "[2, 2, 2]\n" 189 | ] 190 | } 191 | ], 192 | "source": [ 193 | "x = []\n", 194 | "for i in range(3):\n", 195 | " x.append([2]*3)\n", 196 | " \n", 197 | "print(*x, sep=\"\\n\")\n", 198 | "\n", 199 | "print()\n", 200 | "\n", 201 | "x[0][0] = \"ZZ\"\n", 202 | "print(*x, sep=\"\\n\")" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": null, 208 | "metadata": {}, 209 | "outputs": [], 210 | "source": [] 211 | } 212 | ], 213 | "metadata": { 214 | "kernelspec": { 215 | "display_name": "Python 3", 216 | "language": "python", 217 | "name": "python3" 218 | }, 219 | "language_info": { 220 | "codemirror_mode": { 221 | "name": "ipython", 222 | "version": 3 223 | }, 224 | "file_extension": ".py", 225 | "mimetype": "text/x-python", 226 | "name": "python", 227 | "nbconvert_exporter": "python", 228 | "pygments_lexer": "ipython3", 229 | "version": "3.7.4" 230 | } 231 | }, 232 | "nbformat": 4, 233 | "nbformat_minor": 2 234 | } 235 | -------------------------------------------------------------------------------- /A Beginners Guide to Python/misc/minesweeper.py: -------------------------------------------------------------------------------- 1 | import random 2 | from functools import partial 3 | import sys 4 | 5 | EMPTY_SQUARE_CHARACTER = "-" 6 | BOMB_CHARACTER = "B" 7 | FLAG_CHARACTER = "F" 8 | 9 | def build_board(num_rows, num_cols, bomb_count=0, empty_character=EMPTY_SQUARE_CHARACTER): 10 | assert num_rows >= 1 and num_cols >= 1, "DIMS ERROR" 11 | 12 | board_temp = [BOMB_CHARACTER] * bomb_count + [empty_character] * ( (num_rows * num_cols) - bomb_count) 13 | 14 | if bomb_count: 15 | random.shuffle(board_temp) 16 | 17 | board = [] 18 | for i in range(0, num_rows * num_cols, num_rows): 19 | board.append(board_temp[i:i+num_rows]) 20 | return board 21 | 22 | def set_square(x, y, new_val, board): 23 | """ 24 | This function indexes into the given board at position (x, y). 25 | We then change that value to new_val. Returns nothing. 26 | """ 27 | board[x][y] = new_val 28 | 29 | def get_square(x, y, board): 30 | """ 31 | This function takes a board and returns the value at that square(x,y). 32 | """ 33 | return board[x][y] 34 | 35 | def display_board(board): 36 | print(*board, sep="\n") 37 | 38 | def neighbour_squares(x, y, num_rows, num_cols): 39 | """ 40 | (x, y) 0-based index co-ordinate pair. 41 | num_rows, num_cols: specifiy the max size of the board 42 | 43 | returns all valid (x, y) coordinates from starting position. 44 | """ 45 | offsets = [(-1,-1), (-1,0), (-1,1), 46 | ( 0,-1), ( 0,1), 47 | ( 1,-1), ( 1,0), ( 1,1)] 48 | 49 | result = [] 50 | for x2, y2 in offsets: 51 | 52 | px = x + x2 53 | py = y + y2 54 | 55 | #row_check = 0 <= px < num_rows 56 | #col_check = 0 <= py < num_cols 57 | 58 | row_check = 0 <= px < num_cols 59 | col_check = 0 <= py < num_rows 60 | 61 | if row_check and col_check: 62 | point = (px, py) 63 | result.append(point) 64 | 65 | return result 66 | 67 | def count_occurence_of_character_in_neighbour_squares(x, y, board, character): 68 | """ 69 | returns the number of neighbours of (x,y) that are bombs. Max is 8, min is 0. 70 | """ 71 | num_rows = len(board[0]) 72 | num_cols = len(board) 73 | 74 | squares = neighbour_squares(x, y, num_rows, num_cols) 75 | 76 | character_found = 0 77 | for px, py in squares: 78 | 79 | square_value = get_square(px, py, board) 80 | 81 | if square_value == character: 82 | character_found += 1 83 | 84 | return character_found 85 | 86 | def flag_square(row, col, player_board): 87 | p_square = get_square(row, col, player_board) 88 | 89 | if p_square in "012345678": 90 | # do nothing 91 | return 92 | 93 | ## set flag 94 | if p_square == EMPTY_SQUARE_CHARACTER: 95 | set_square(row, col, FLAG_CHARACTER, player_board) 96 | 97 | ## Deflag if flag is already set 98 | if p_square == FLAG_CHARACTER: 99 | set_square(row, col, EMPTY_SQUARE_CHARACTER, player_board) 100 | return 101 | 102 | def reveal_square(row, col, player_board, game_board): 103 | p_square = get_square(row, col, player_board) 104 | 105 | if p_square in "012345678" or p_square == FLAG_CHARACTER: 106 | ## do nothing 107 | return 108 | 109 | g_square = get_square(row, col, game_board) 110 | 111 | if g_square == BOMB_CHARACTER: 112 | return 113 | #return game_over() 114 | 115 | else: 116 | bomb_count = count_occurence_of_character_in_neighbour_squares(row, col, game_board, BOMB_CHARACTER) 117 | set_square(row, col, str(bomb_count), player_board) 118 | 119 | class PlayGame(): 120 | 121 | def __init__(self): 122 | self.player_board = [[]] 123 | self.game_board = [[]] 124 | 125 | self.is_playing = True 126 | 127 | ## Command -> (function, help text) 128 | self.COMMANDS = { 129 | "flag": (self.flag, "Flags/deflags square(x,y). Example useage: flag x y"), 130 | "pick": (self.pick, "Selects square(x, y) to reveal, its game over if you reveal a bomb. Example useage: pick x y"), 131 | "hint": (self.hint, "The computer checks if square(x, y) is a bomb or not. Example useage: hint x y"), 132 | "new" : (self.new_game, "Starts a new game with a board size of (x,y) with z bombs. Example useage: new x y z"), 133 | "cheat": (self.cheat, "Shows the location of all bombs. Example useage: cheat"), 134 | "help": (self.help, "Returns information about a instruction. Example useage: help cheat"), 135 | "commands": (self.get_command_keys, "Returns a list of valid commands."), 136 | "exit": (self.exit, "Exit the application. Example useage: exit") 137 | } 138 | 139 | def exit(self): 140 | self.is_playing = False 141 | 142 | 143 | def new_game(self, rows, cols, bomb_count): 144 | self.game_board = build_board(rows, cols, bomb_count = bomb_count) 145 | self.player_board = build_board(rows, cols, bomb_count=0) 146 | 147 | def pick(self, row, col): 148 | reveal_square(row, col, self.player_board, self.game_board) 149 | 150 | g_square = get_square(row, col, self.game_board) 151 | if g_square == BOMB_CHARACTER: 152 | return self.game_over() 153 | 154 | def flag(self, row, col): 155 | flag_square(row, col, self.player_board) 156 | 157 | def cheat(self): 158 | display_board(self.game_board) 159 | print("\n") 160 | 161 | def hint(self, row, col): 162 | g_square = get_square(row, col, self.game_board) 163 | 164 | is_bomb = g_square == BOMB_CHARACTER 165 | print(f"Is square({row},{col}) a bomb?: {str(is_bomb)}") 166 | 167 | 168 | def game_over(self): 169 | print("============") 170 | print("GAME OVER") 171 | print("=============") 172 | display_board(self.game_board) 173 | self.game_board = [[]] 174 | self.player_board = [[]] 175 | 176 | 177 | def get_command_keys(self): 178 | print(self.COMMANDS.keys()) 179 | 180 | def help(self, topic=None): 181 | if topic is None: 182 | print(self.COMMANDS["help"][1]) 183 | 184 | elif topic in self.COMMANDS: 185 | print(self.COMMANDS[topic][1]) 186 | 187 | else: 188 | print(f"help {topic} was not understood") 189 | 190 | def parse_command(self, command): 191 | instruction, *arguments = command.split(" ") 192 | 193 | for i, arg in enumerate(arguments): 194 | if arg.isdigit(): 195 | arguments[i] = int(arg) 196 | 197 | if instruction in self.COMMANDS: 198 | self.COMMANDS[instruction][0](*arguments) 199 | else: 200 | print(f"FAILED TO PARSE COMMAND: {command}") 201 | 202 | def main(): 203 | DEBUG = False #True 204 | 205 | if DEBUG: 206 | random.seed(243) 207 | 208 | print("+--------------------------------+") 209 | print("| WELCOME TO MINSWEEPER 1.0! |") 210 | print("+--------------------------------+") 211 | print("How to play: type 'commands' for a list of valid inputs. Then type 'help x' for information about how to use command 'x'") 212 | print("") 213 | 214 | game = PlayGame() 215 | 216 | while game.is_playing: 217 | s = input("Command: ") 218 | game.parse_command(s) 219 | display_board(game.player_board) 220 | print("\n") 221 | 222 | if __name__ == "__main__": 223 | main() -------------------------------------------------------------------------------- /A Beginners Guide to Python/misc/profile_code.py: -------------------------------------------------------------------------------- 1 | def profile(function, *args, **kwargs): 2 | """ Returns performance statistics (as a string) for the given function. 3 | """ 4 | def _run(): 5 | function(*args, **kwargs) 6 | import cProfile as profile 7 | import pstats 8 | import os 9 | import sys; sys.modules['__main__'].__profile_run__ = _run 10 | id = function.__name__ + '()' 11 | profile.run('__profile_run__()', id) 12 | p = pstats.Stats(id) 13 | p.stream = open(id, 'w') 14 | p.sort_stats('tottime').print_stats(20) 15 | p.stream.close() 16 | s = open(id).read() 17 | os.remove(id) 18 | return s -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## If you wanna help and you are a beginner: 2 | 3 | * Basically, go through the lectures and tell me how useful they are 4 | * Is the text/code comments/format clear, helpful, etc? 5 | * Is the difficulty just right? or too hard/easy? 6 | * Are the homeworks engaging? 7 | * Etc, Etc 8 | 9 | ## If you wanna help and you are an experienced user: 10 | 11 | * Please point out any errors of fact, oversimplications, etc 12 | * Is is possible to refactor code examples to be more clear/consise/beginner friendly? 13 | * How to improve formating with Markdown 14 | * Etc, Etc 15 | 16 | ## Other Contributions... 17 | 18 | * pictures/diagrams are often helpful, so if anyone wants to give me graphics let me know. 19 | * As for other sorts of contributions, just hit me up with a proposal, worst case scenario I say no. :P 20 | * Pointing out bad spelling / typo's / grammar, etc. 21 | -------------------------------------------------------------------------------- /Graphics Folder for Install Lecture/Editing Mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/Graphics Folder for Install Lecture/Editing Mode.png -------------------------------------------------------------------------------- /Graphics Folder for Install Lecture/Reading Mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/Graphics Folder for Install Lecture/Reading Mode.png -------------------------------------------------------------------------------- /Graphics Folder for Install Lecture/Run Button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/Graphics Folder for Install Lecture/Run Button.png -------------------------------------------------------------------------------- /Graphics Folder for Install Lecture/Running Code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/Graphics Folder for Install Lecture/Running Code.png -------------------------------------------------------------------------------- /Graphics Folder for Install Lecture/download help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fluffy-hamster/A-Beginners-Guide-to-Python/1fa788b3fe86070ef7d0182d7b2bf18cc5a30651/Graphics Folder for Install Lecture/download help.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Chris 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Beginners-Guide-to-Python (Beta) 2 | 3 | This project is intended as a beginers guide for Python, which is currently a work in progress. The lessons are Juypter Notebooks. 4 | If you are unfamiliar with Jupyter notebook you may also want to check out the "install help" lecture, or alternatively you can check out Juypter's documentation. See Here: http://jupyter.readthedocs.io/en/latest/install.html 5 | 6 | If you wanna help out please visit the 'contributing' file. 7 | --------------------------------------------------------------------------------