├── .gitbook └── assets │ ├── image.png │ ├── yes.gif │ ├── image (1).png │ ├── image (2).png │ ├── image (3).png │ ├── image (4).png │ ├── image (6).png │ ├── image (7).png │ ├── image (8).png │ ├── image (9).png │ ├── variables.md │ └── undraw_code_review_l1q9.svg ├── object-orientated-programming ├── advanced.md └── introduction.md ├── what-is-python ├── what-is-python-1 │ ├── README.md │ ├── intrepreted.md │ ├── general-purpose.md │ └── high-level.md ├── intrepreted.md ├── general-purpose.md ├── operators.md ├── virtual-environments │ ├── pyenv.md │ └── README.md ├── hello-world.md ├── tooling.md ├── loops.md ├── functions │ ├── scope.md │ └── README.md ├── if-statements.md ├── python-libraries.md ├── object-orientated-programming.md ├── boolean-values.md ├── high-level.md └── variables.md ├── README.md ├── advanced ├── introduction.md └── set-theory.md ├── getting-started ├── operators.md ├── hello-world.md └── variables.md ├── SUMMARY.md └── tooling └── installing-python.md /.gitbook/assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/image.png -------------------------------------------------------------------------------- /.gitbook/assets/yes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/yes.gif -------------------------------------------------------------------------------- /.gitbook/assets/image (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/image (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/image (2).png -------------------------------------------------------------------------------- /.gitbook/assets/image (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/image (3).png -------------------------------------------------------------------------------- /.gitbook/assets/image (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/image (4).png -------------------------------------------------------------------------------- /.gitbook/assets/image (6).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/image (6).png -------------------------------------------------------------------------------- /.gitbook/assets/image (7).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/image (7).png -------------------------------------------------------------------------------- /.gitbook/assets/image (8).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/image (8).png -------------------------------------------------------------------------------- /.gitbook/assets/image (9).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee-san/Python-Zero-to-Hero/HEAD/.gitbook/assets/image (9).png -------------------------------------------------------------------------------- /object-orientated-programming/advanced.md: -------------------------------------------------------------------------------- 1 | # Advanced 2 | 3 | * Table doubling 4 | * Python linked lists in hashmaps 5 | * how hashmaps work 6 | * open addressing 7 | 8 | -------------------------------------------------------------------------------- /what-is-python/what-is-python-1/README.md: -------------------------------------------------------------------------------- 1 | # What is Python? 2 | 3 | Python is a programming language created by Guido \(pronounced gree-do\) Van Rossum. Specifically, Python is an _intrepreted_, _high-level_, _general purpose_ programming language. 4 | 5 | Let's talk about what these mean. 6 | 7 | -------------------------------------------------------------------------------- /what-is-python/intrepreted.md: -------------------------------------------------------------------------------- 1 | # Intrepreted 2 | 3 | Python is an interpreted language. That means that instead of translating the whole code into machine code at once, it translates the code piece by piece. And once it's converted a piece of code, it runs it, and then continues until the program stops running. 4 | 5 | -------------------------------------------------------------------------------- /what-is-python/what-is-python-1/intrepreted.md: -------------------------------------------------------------------------------- 1 | # Intrepreted 2 | 3 | Python is an interpreted language. That means that instead of translating the whole code into machine code at once, it translates the code piece by piece. And once it's converted a piece of code, it runs it, and then continues until the program stops running. 4 | 5 | -------------------------------------------------------------------------------- /what-is-python/general-purpose.md: -------------------------------------------------------------------------------- 1 | # General Purpose 2 | 3 | General Purpose means that Python was created to do everything. Some programming languages like Matlab or R were created for data science. Others like HTML / CSS were created for web development. 4 | 5 | Python aims to do everything, it is generalised. This is both a fault and an advantage. You can do everything you want in Python, but it does not have one area where it shines. 6 | 7 | -------------------------------------------------------------------------------- /what-is-python/what-is-python-1/general-purpose.md: -------------------------------------------------------------------------------- 1 | # General Purpose 2 | 3 | General Purpose means that Python was created to do everything. Some programming languages like Matlab or R were created for data science. Others like HTML / CSS were created for web development. 4 | 5 | Python aims to do everything, it is generalised. This is both a fault and an advantage. You can do everything you want in Python, but it does not have one area where it shines. 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Zero to Hero 2 | 3 | ![](.gitbook/assets/undraw_code_review_l1q9.svg) 4 | 5 | Hey! This is my introduction to Python. Generally you should already know a little about Python, as this aims to take you to becoming an expert Pythonista! 6 | 7 | You can view this book here: 8 | 9 | {% embed url="https://beesec.gitbook.io/python-zero-to-hero/" %} 10 | 11 | You can find the GitHub repo here: 12 | 13 | {% embed url="https://github.com/bee-san/Python-Zero-to-Hero" %} 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /advanced/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | If you create or want to create tools like Ciphey, Autorecon, Sherlock, and more this is the section for you. 4 | 5 | If you try to build a large project using only what I taught you in the basics, you will fail. Mainly because: 6 | 7 | * Your code will become unmaintainable and thus you will lose all motivation 8 | * Your code will be incredibly slow due to not understanding algorithms / data structures 9 | 10 | This section aims to teach you the advance stuff. 11 | 12 | -------------------------------------------------------------------------------- /what-is-python/operators.md: -------------------------------------------------------------------------------- 1 | # Operators 2 | 3 | Let's talk about operators. An operator is something between 2 variables / values and does something to them. 4 | 5 | For example, the addition operator: 6 | 7 | ```python 8 | x = 3 + 1 9 | # x = 4 10 | ``` 11 | 12 | Python supports many maths operators: 13 | 14 | ```python 15 | 3 + 1 16 | 3 / 1 # divided by 17 | 3 * 4 # times 18 | 2 ** 2 # 2 to the power of 4 19 | 2 % 3 # 2 mod 3 20 | ``` 21 | 22 | Now the cool thing, operators don't just work on numbers. They work on strings too. And lists. And dictionaries. 23 | 24 | ```python 25 | [3, 2] + [6, 7] 26 | # [3, 2, 6, 7] 27 | "Hello, " + "World!" 28 | # "Hello, World!" 29 | ``` 30 | 31 | Well, **operators work on any data structure that has implemented a magic method for them**. 32 | 33 | Magic methods are rather wild, but require prequesite knolwedge of object orientated programming fiest. 34 | 35 | -------------------------------------------------------------------------------- /getting-started/operators.md: -------------------------------------------------------------------------------- 1 | # Operators 2 | 3 | Let's talk about operators. An operator is something between 2 variables / values and does something to them. 4 | 5 | For example, the addition operator: 6 | 7 | ```python 8 | x = 3 + 1 9 | # x = 4 10 | ``` 11 | 12 | Python supports many maths operators: 13 | 14 | ```python 15 | 3 + 1 16 | 3 / 1 # divided by 17 | 3 * 4 # times 18 | 2 ** 2 # 2 to the power of 4 19 | 2 % 3 # 2 mod 3 20 | ``` 21 | 22 | Now the cool thing, operators don't just work on numbers. They work on strings too. And lists. And dictionaries. 23 | 24 | ```python 25 | [3, 2] + [6, 7] 26 | # [3, 2, 6, 7] 27 | "Hello, " + "World!" 28 | # "Hello, World!" 29 | ``` 30 | 31 | Well, **operators work on any data structure that has implemented a magic method for them**. 32 | 33 | Magic methods are rather wild, but require prerequisite knowledge of object orientated programming first. 34 | 35 | -------------------------------------------------------------------------------- /what-is-python/virtual-environments/pyenv.md: -------------------------------------------------------------------------------- 1 | # PyEnv 2 | 3 | PyEnv is a tool that let's us switch between multiple versions of Python easily. 4 | 5 | **Note**: PyEnv does not support Windows. 6 | 7 | To install PyEnv, run: 8 | 9 | ```text 10 | curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash 11 | ``` 12 | 13 | Taken from here [https://github.com/pyenv/pyenv](https://github.com/pyenv/pyenv) 14 | 15 | Now let's install 3.7 16 | 17 | ```text 18 | pyenv install 3.7.0 19 | ``` 20 | 21 | We can use PyEnv locally or globally. 22 | 23 | Globally means we change our entire Python version on our computer. Locally means that for a specific project or directory we use a different Python version. 24 | 25 | In our `my-new-project` directory, run `pyenv local 3.7.0`. 26 | 27 | And just like that we can use different Python versions for different things. 28 | 29 | If we wanted to use 3.7.0 globally instead of 3.8: 30 | 31 | ```python 32 | pyenv global 3.7.0 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /what-is-python/hello-world.md: -------------------------------------------------------------------------------- 1 | # Hello, World! 2 | 3 | It is very traditional for every programmer, when starting out, to start with a hello world program. 4 | 5 | Create a new file called `hello.py` and open it up in your text editor of choice \(the one you downloaded in the last section\). 6 | 7 | In this new file, copy and paste this line: 8 | 9 | ```python 10 | print("Hello, World!") 11 | ``` 12 | 13 | Let's explain what this does: 14 | 15 | * Print 16 | 17 | Print is a function. We give it some text and it'll print it to the screen. 18 | 19 | * "Hello, World!" 20 | 21 | Is what we call a string \(a string of characters\). It's just text. 22 | 23 | Now, open up a Terminal, navigate to your directory and run: 24 | 25 | ```text 26 | python hello.py 27 | ``` 28 | 29 | \_Make sure you use `python` or `python3`, whichever one worked for you in the last section. 30 | 31 | And you'll see on your screen printed: 32 | 33 | ```text 34 | $ Hello, World! 35 | ``` 36 | 37 | Congratulations! You have just run your first Python program! 🥳 38 | 39 | -------------------------------------------------------------------------------- /getting-started/hello-world.md: -------------------------------------------------------------------------------- 1 | # Hello, World! 2 | 3 | It is very traditional for every programmer, when starting out, to start with a hello world program. 4 | 5 | Create a new file called `hello.py` and open it up in your text editor of choice \(the one you downloaded in the last section\). 6 | 7 | In this new file, copy and paste this line: 8 | 9 | ```python 10 | print("Hello, World!") 11 | ``` 12 | 13 | Let's explain what this does: 14 | 15 | * Print 16 | 17 | Print is a function. We give it some text and it'll print it to the screen. 18 | 19 | * "Hello, World!" 20 | 21 | Is what we call a string \(a string of characters\). It's just text. 22 | 23 | Now, open up a Terminal, navigate to your directory and run: 24 | 25 | ```text 26 | python hello.py 27 | ``` 28 | 29 | \_Make sure you use `python` or `python3`, whichever one worked for you in the last section. 30 | 31 | And you'll see on your screen printed: 32 | 33 | ```text 34 | $ Hello, World! 35 | ``` 36 | 37 | Congratulations! You have just run your first Python program! 🥳 38 | 39 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Python Zero to Hero](README.md) 4 | 5 | ## What is Python? 6 | 7 | * [What is Python?](what-is-python/what-is-python-1/README.md) 8 | * [High Level](what-is-python/what-is-python-1/high-level.md) 9 | * [Intrepreted](what-is-python/what-is-python-1/intrepreted.md) 10 | * [General Purpose](what-is-python/what-is-python-1/general-purpose.md) 11 | * [Tooling](what-is-python/tooling.md) 12 | * [Hello, World!](what-is-python/hello-world.md) 13 | * [Variables](what-is-python/variables.md) 14 | * [Operators](what-is-python/operators.md) 15 | * [Object Orientated Programming](what-is-python/object-orientated-programming.md) 16 | * [Boolean Values](what-is-python/boolean-values.md) 17 | * [If Statements](what-is-python/if-statements.md) 18 | * [Loops](what-is-python/loops.md) 19 | * [Functions](what-is-python/functions/README.md) 20 | * [Scope](what-is-python/functions/scope.md) 21 | * [Python Libraries](what-is-python/python-libraries.md) 22 | * [Virtual Environments](what-is-python/virtual-environments/README.md) 23 | * [PyEnv](what-is-python/virtual-environments/pyenv.md) 24 | 25 | ## Advanced 26 | 27 | * [Introduction](advanced/introduction.md) 28 | * [Set Theory](advanced/set-theory.md) 29 | 30 | -------------------------------------------------------------------------------- /what-is-python/tooling.md: -------------------------------------------------------------------------------- 1 | # Tooling 2 | 3 | Before we begin writing Python code, let's get the tooling right. 4 | 5 | Here we'll install Python and a text editor / IDE. 6 | 7 | Check if you have Python installed already with: 8 | 9 | ```text 10 | python --version 11 | ``` 12 | 13 | If this number is below 3, try: 14 | 15 | ```text 16 | python3 --version 17 | ``` 18 | 19 | * If `python3` works, whenever I say `python` type `python3` instead. 20 | * If neither of these worked and presented a version higher than 3 then: 21 | 22 | Install the latest release of Python from [here](https://www.python.org/downloads/). Note that on Windows, this website defaults to 32-bit Python. Please install 64-bit Python, tool developers will thank you. 23 | 24 | Now, let's install a text editor or IDE. I would suggest an IDE, but they are rather heavy on resources. 25 | 26 | An IDE will show you errors before you run the code, and will help you to automatically fix those errors. 27 | 28 | The best Python IDE is [PyCharm](https://www.jetbrains.com/pycharm/). 29 | 30 | However, if your computer has limited resources you may want to use a text editor. I use [Visual Studio Code](https://code.visualstudio.com/) but you can use Atom or Sublime. 31 | 32 | Honestly if you're not going to use PyCharm the choice of text editor at this stage doesn't matter too much. In the wise words of someone I once knew: 33 | 34 | > Deciding on the tooling is another form of procrastination. Choose something and get it over with. 35 | 36 | Download Visual Studio Code if PyCharm didn't work. 37 | 38 | -------------------------------------------------------------------------------- /tooling/installing-python.md: -------------------------------------------------------------------------------- 1 | # Installing Python 2 | 3 | Before we begin writing Python code, let's get the tooling right. 4 | 5 | Here we'll install Python and a text editor / IDE. 6 | 7 | Check if you have Python installed already with: 8 | 9 | ```text 10 | python --version 11 | ``` 12 | 13 | If this number is below 3, try: 14 | 15 | ```text 16 | python3 --version 17 | ``` 18 | 19 | * If `python3` works, whenever I say `python` type `python3` instead. 20 | * If neither of these worked and presented a version higher than 3 then: 21 | 22 | Install the latest release of Python from [here](https://www.python.org/downloads/). Note that on Windows, this website defaults to 32-bit Python. Please install 64-bit Python, tool developers will thank you. 23 | 24 | Now, let's install a text editor or IDE. I would suggest an IDE, but they are rather heavy on resources. 25 | 26 | An IDE will show you errors before you run the code, and will help you to automatically fix those errors. 27 | 28 | The best Python IDE is [PyCharm](https://www.jetbrains.com/pycharm/). 29 | 30 | However, if your computer has limited resources you may want to use a text editor. I use [Visual Studio Code](https://code.visualstudio.com/) but you can use Atom or Sublime. 31 | 32 | Honestly if you're not going to use PyCharm the choice of text editor at this stage doesn't matter too much. In the wise words of someone I once knew: 33 | 34 | > Deciding on the tooling is another form of procrastination. Choose something and get it over with. 35 | 36 | Download Visual Studio Code if PyCharm didn't work. 37 | 38 | -------------------------------------------------------------------------------- /what-is-python/loops.md: -------------------------------------------------------------------------------- 1 | # Loops 2 | 3 | Now what if we had the same name checking code from the last task, but instead of not allowing entry, we waited until the right person showed up? 4 | 5 | How do we repeatedly ask for the persons name and check to see if their name matches? 6 | 7 | We can do this using something called a `loop`. 8 | 9 | `while` loops will loop until a condition is met \(much like our if statements from earlier\). 10 | 11 | ```python 12 | name = "" 13 | while name != "Jabba": 14 | name = input("What is your name? ") 15 | ``` 16 | 17 | Since while loops take conditionals, what happens if we assign a True value to it? 18 | 19 | ```python 20 | while True: 21 | print("This loop runs!") 22 | ``` 23 | 24 | The loop runs forever, as the condition never changes. 25 | 26 | This is quite useful for input / output where you expect to repeatedly receive input. Or perhaps you want to repeatedly do something \(such as check TryHackMe for new rooms\). 27 | 28 | We can tell our loop to break using a the keyword `break`. 29 | 30 | ```python 31 | while True: 32 | name = input("What is your name? ") 33 | if name == "Jabba": 34 | break 35 | ``` 36 | 37 | The `break` keyword tells Python to break out of the while loop. If we do this, our code is no longer in the `while` and will continue to run. 38 | 39 | While loops are very good for pointers. A pointer is a variable which keeps track of where it is in a list. 40 | 41 | ![](../.gitbook/assets/image%20%289%29.png) 42 | 43 | ```python 44 | names = ["Skidy", "DorkStar", "Ashu", "Elf"] 45 | pointer = 0 46 | while pointer <= len(names): 47 | print(names[i]) 48 | pointer += 1 49 | ``` 50 | 51 | -------------------------------------------------------------------------------- /what-is-python/functions/scope.md: -------------------------------------------------------------------------------- 1 | # Scope 2 | 3 | Scope is one of the largest problems a Python programmer will face. 4 | 5 | Let's see a little example. 6 | 7 | ```python 8 | name = "0xEmma" 9 | 10 | def hello(name): 11 | name = "Blob Bros" 12 | print(f"Hello, {'DorkStar' if name == 'Dork' else name}") 13 | 14 | hello() 15 | print(name) 16 | # Hello, Blob Bros 17 | # 0xEmma 18 | ``` 19 | 20 | We changed the variable in the function, so why did it not change the variable outside the function? The answer is that the function has a scope that is smaller than the scope of the variable \(which is the global scope\). 21 | 22 | ![](../../.gitbook/assets/image%20%288%29.png) 23 | 24 | Imagine this line going through the program. Everything not in a function is considered the global scope of that file \(the main program, in this case\). 25 | 26 | When we build a function, it creates a new parallel line. This parallel line creates a new scope, which means it cannot change things outside of itself \(the global scope\). 27 | 28 | If that parallel line was to create another function, another scope — it can change things in there. 29 | 30 | Just like how the global scope can change things in functions. 31 | 32 | When we build more functions and code, we want to stay as low down in the nest of scope as possible. If we have so many functions each calling eachother, it will be confusing for us to work out where the problem is. The code becomes messy. 33 | 34 | Each function should do one thing, and one thing only. And we should minimise how many other functions call that function. If we do not, we might end up in a spiderweb of function calls which would be impossible to debug. 35 | 36 | Now, back to scope. 37 | 38 | ![https://www.geeksforgeeks.org/namespaces-and-scope-in-python/](../../.gitbook/assets/image%20%286%29.png) 39 | 40 | Scope is closely linked to something called a "namespace" in Python. There's 3 types of scope. 41 | 42 | The built-in namespace \(what default functions / data structures use\), the global namespace and the local namespace. 43 | 44 | There's a lot more to scope, but honestly the only thing you need to remember is the line idea. Everytime we make a new scope, we diverge from the original scope we were in. 45 | 46 | If we repeatedly make new scopes, our line gets more and more branches resulting in more confusion. 47 | 48 | [Here's a nice article on the concept.](https://realpython.com/python-scope-legb-rule/#nested-functions-the-enclosing-scope) 49 | 50 | -------------------------------------------------------------------------------- /what-is-python/virtual-environments/README.md: -------------------------------------------------------------------------------- 1 | # Virtual Environments 2 | 3 | Virtual Environments allow you to have seperate boxes of packages for each project you work on. 4 | 5 | Let's say Project X requires Ciphey 4.2.0, but project Y requires 5.10.0. To get around the fact they both need different versions, we use a virtual environment. 6 | 7 | Essentially we create a container for both projects. That way we can install whatever we want without conflicts in the confinement of this container! 8 | 9 | The default tool for Virtual Environments is rather bad, and no one really uses it anymore. 10 | 11 | So we'll install a new one. 12 | 13 | ```text 14 | pip install virtualenvwrapper 15 | ``` 16 | 17 | **Windows** use [https://pypi.org/project/virtualenvwrapper-win/](https://pypi.org/project/virtualenvwrapper-win/) instead 18 | 19 | Pay attention to the output in the terminal. We need to know the location of [`virtualenvwrapper.sh`](http://virtualenvwrapper.sh/). 20 | 21 | Now in our `.bashrc` or `.zshrc` \(the file that runs everytime a terminal is opened\) add these lines: 22 | 23 | ```text 24 | export WORKON_HOME=$HOME/.virtualenvs 25 | export PROJECT_HOME=$HOME/projects 26 | source /usr/local/bin/virtualenvwrapper.sh 27 | ``` 28 | 29 | Replacing the `source /usr/local....` with the file location outputted in the terminal. 30 | 31 | Now, source your .bashrc: 32 | 33 | ```text 34 | source .bashrc 35 | ``` 36 | 37 | **Note**: this is confusing and you may get this wrong the first time. If so, please read more about .bashrc via Google 😄 38 | 39 | Now, make a new folder and call it "my-new-project" or something. 40 | 41 | `cd` into that folder and run: 42 | 43 | ```text 44 | mkvirtualenv my-new-project 45 | ``` 46 | 47 | This automatically creates the virtual environment for you, and drops you into it. 48 | 49 | Now we can `pip` install anything we want, and it will only be associated with this virtual environment. 50 | 51 | We can leave our virtual environment with `deactivate`. We no longer have access to the package we installed in the virtual environment. 52 | 53 | To go back, run `workon`. 54 | 55 | ```text 56 | $ workon 57 | my-new-project 58 | ``` 59 | 60 | This tells us the name\(s\) of our virtual environments. And then: 61 | 62 | ```text 63 | workon my-new-project 64 | ``` 65 | 66 | Takes us back there. 67 | 68 | And just like that, we have now fixed our packaging problem with this neat tool \(and trust me when I say, this is easier than the default tool\). 69 | 70 | Now, remember how I said that Ciphey works on 3.7 and up, but what if we have another piece of software that only works on 3.6 and below? How would we use different versions of Python? 71 | 72 | This is solved by.... 73 | 74 | -------------------------------------------------------------------------------- /what-is-python/if-statements.md: -------------------------------------------------------------------------------- 1 | # If Statements 2 | 3 | If statements are one of the most powerful statements in all of programming. 4 | 5 | We want to do something _if_ a condition is met. 6 | 7 | So for example, if the list is not empty: 8 | 9 | ```python 10 | x = [6] 11 | if x: 12 | print("I run!") 13 | ``` 14 | 15 | Because x is non-empty, it has a truthy value. Which means this reads as "If True" and it runs. If it read as "If False" it does not run. 16 | 17 | If statements only run if the condition is True. 18 | 19 | Now let's see it in action. 20 | 21 | We can take user input using the `input()` function \(we'll talk about functions soon\). 22 | 23 | ```python 24 | name = input("What is your name? ") 25 | ``` 26 | 27 | Now let's say we are a wide bouncer at the TryHackMe Official Pub. We only want to let people in that have a name in our special club. 28 | 29 | First, we need to create the list of names. Can you guess what we'll be using for this? 30 | 31 | ```python 32 | names = ["Skidy", "DorkStar", "Ashu", "Elf"] 33 | ``` 34 | 35 | Great! And now if we have a string, such as Jabba, how do we check if the name is in the list? 36 | 37 | ```python 38 | "Jabba" in names 39 | # False 40 | ``` 41 | 42 | Now we want to print a special little message if and only if the users inputted name appears in our list. We can do this with: 43 | 44 | ```python 45 | names = ["Skidy", "DorkStar", "Ashu", "Elf"] 46 | 47 | name = input("What is your name? ") 48 | 49 | if name in names: 50 | print("The Wide One has allowed you to come in.") 51 | ``` 52 | 53 | Now, what if their name does not appear in the list of names? We can use an else clause. 54 | 55 | ```python 56 | names = ["Skidy", "DorkStar", "Ashu", "Elf"] 57 | 58 | name = input("What is your name? ") 59 | 60 | if name in names: 61 | print("The Wide One has allowed you to come in.") 62 | else: 63 | print("The Wide One has not allowed you to come in.") 64 | ``` 65 | 66 | ## One Line If Statements 67 | 68 | We can also build one line if statements pretty nicely in Python. 69 | 70 | ```python 71 | age = 12 72 | 73 | name = "Jabba" if age == 12 else "Skidy" 74 | 75 | print(name) 76 | # 'Jabba' 77 | ``` 78 | 79 | This will be made redundant with the next type of loop, however for things with 2+ pointers \(which happens in many optimal algorithms\) while loops still reign supreme. 80 | 81 | For loops are best described how they are read: 82 | 83 | ```python 84 | names = ["Skidy", "DorkStar", "Ashu", "Elf"] 85 | for name in names: 86 | print(name) 87 | ``` 88 | 89 | For every name in the list of names, do something \(in this case — print the name\). 90 | 91 | For loops can iterate over the elements of any iterable. Let's look at a function which returns an iterable, `range`. 92 | 93 | Range returns a list of numbers in a range. So to loop between 1 and 9 we would do: 94 | 95 | ```python 96 | range(1, 9) 97 | ``` 98 | 99 | Range is inclusive, so 1 and 9 are included. 100 | 101 | Now to loop over this: 102 | 103 | ```python 104 | for i in range(1, 9): 105 | print(i) 106 | ``` 107 | 108 | Note: We often use i as the variable in a for loop as it stands for "item". 109 | 110 | -------------------------------------------------------------------------------- /what-is-python/python-libraries.md: -------------------------------------------------------------------------------- 1 | # Python Libraries 2 | 3 | Now let's talk about the Python packaging ecosystem! 4 | 5 | Imagine you wanted to write code to download something from a website. Without knowing about packaging, you would have to manually write all the code yourself. 6 | 7 | But what if I told you that someone else has written the code for you? And what if I told you it's easy to download their code and use it in your projects? 8 | 9 | Python ships with a neat bit of software called `pip`. `pip` allows you to install other peoples code \(called packages\). 10 | 11 | These packages are stored in a repository called PyPi. 12 | 13 | We can search for packages on PyPi \(although most of the time, we don't need to. We'll know the name of a package from Stack Overflow telling us to install it. 14 | 15 | Here's a good example. 16 | 17 | [https://pypi.org/project/requests/](https://pypi.org/project/requests/) 18 | 19 | The Requests package is managed by the Python Software Foundation. It's a package that allows you to do cool HTTP/s stuff and download webpages. 20 | 21 | In a Terminal \(not in Python\) run: 22 | 23 | ```text 24 | pip install requests 25 | ``` 26 | 27 | **Note**: If you have to run `python3`, run `pip3` here instead. 28 | 29 | And just like that we have someone elses code! 30 | 31 | We can now import Requests and use it. 32 | 33 | ```python 34 | import requests 35 | r = requests.get("https://tryhackme.com") 36 | print(r.status_code) 37 | # Since you are reading this, TryHackMe should 38 | # be up so it should return 200 39 | ``` 40 | 41 | To import code, we run the command `import {name}` where `{name}` is the name of the module / library / package we want. As we just installed requests, we can import it. 42 | 43 | We can also import some others built into Python, such as `math`. 44 | 45 | ```python 46 | import math 47 | ``` 48 | 49 | Here's a common misconception. Some people say "if you write code in Python, you can be sure it'll run everywhere that Python runs". This is not true. 50 | 51 | A great example of this is a package I wrote, Ciphey. 52 | 53 | Ciphey only runs on Python 3.7 higher \(at the time, Ubuntu server uses 3.6.9\). 54 | 55 | This is because Ciphey uses a feature in 3.7 \(type hints\) that breaks lower versions. 56 | 57 | Ciphey can only run on Windows / Linux too. No Mac support! 58 | 59 | This is because Python is a "glue" language, you can use other languages in Python. Ciphey uses C++ and the combination of C++ and Python on Mac breaks. 60 | 61 | This is definitely my fault, not Pythons — but it's a good example of why "write once, run everywhere" doesn't always apply to Python. 62 | 63 | These kind of issues can happen everywhere. Even using default Python, if you was to use a `ulimit` library you would no longer be able to distribute on Windows unless you did conditional imports. 64 | 65 | Also, the version you use in your code may not be the latest version. 66 | 67 | Let's say you use Ciphey 4.2.0, but the latest version is 5.10.0. 68 | 69 | Your code works fine, as you use 4.2.0, but everyone else who downloads gets Ciphey 5.10.0 which breaks your code. 70 | 71 | You have to do something called _version pinning._ And by doing this, you are essentially installing multiple versions of the same piece of software. This gets confusing, **fast**. And breaks everything. That's why in Python we need..... 72 | 73 | -------------------------------------------------------------------------------- /object-orientated-programming/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Object orientated programming revolves around objects. Don't worry, we won't talk about them for long. 4 | 5 | An object can be anything you want. 6 | 7 | Imagine a bicycle. The bike is an object with the name "bike". 8 | 9 | The wheels of the bike are objects too, which are said to be attributes \(objects can be attributes of other objects in Python\) of the parent class bike. 10 | 11 | Let's go right into an example. 12 | 13 | ```python 14 | class Wheel: 15 | ``` 16 | 17 | We define a class by calling `class :`. Our class is called wheel here. 18 | 19 | What do wheels have? Well, they have tyres so let's add one. 20 | 21 | ```python 22 | class Wheel: 23 | self.tyre = "Michelin" 24 | ``` 25 | 26 | Now our wheel has a Michelin tyre. 27 | 28 | Classes are templates for objects. We can build a class such as a wheel, and when we build an object from our class we are saying "every object is based on this one template class". 29 | 30 | When we build a new Wheel object: 31 | 32 | ```python 33 | x = Wheel() 34 | y = Wheel() 35 | 36 | x.tyre 37 | # "Michelin" 38 | y.tyre 39 | # "Michelin" 40 | ``` 41 | 42 | It will always have the items in the class definition. In this instance, every single wheel of our bike will always have a Michelin tyre. 43 | 44 | Now let's get into magic methods. 45 | 46 | Imagine you have a Person class: 47 | 48 | ```python 49 | class Person: 50 | def __init__(self, first_name, last_name): 51 | self.first_name = first_name 52 | self.last_name = last_name 53 | ``` 54 | 55 | The `__init__` stands for `initialisation`. When we _initialise_ \(create\) an object from this class, this function runs. The function has 3 arguments. 56 | 57 | * `self` 58 | 59 | Every function \(called a method in OOP\) requires a `self` attribute \(in Python\). 60 | 61 | * `first_name` 62 | 63 | The first name of the person. 64 | 65 | * `last_name` 66 | 67 | The last name of the person. 68 | 69 | Because we have the argument `self`, we can change the classes _attributes_ \(the values of the object, think back to our wheel example having the attribute that all tyres are "Michelin"\). 70 | 71 | So we can do this: 72 | 73 | ```python 74 | skidy = Person("Skidy", "Shallot") 75 | skidy.first_name 76 | # "Skidy" 77 | skidy.last_name 78 | # "Shallot" 79 | ``` 80 | 81 | What if we have another person, Dark? 82 | 83 | ```python 84 | dark = Person("Dork", "Star") 85 | ``` 86 | 87 | Now, Dark and Skidy want to get married. In the imaginery land of TryHackMe marriage happens by adding the 2nd persons lastname onto the first. So if Skidy & Dark got married, their combined last name would be `Shallot-Star`. 88 | 89 | How do we program this so that any person getting married has a new last name that matches this? 90 | 91 | With magic methods! 92 | 93 | ```python 94 | class Person: 95 | def __init__(self, first_name, last_name): 96 | self.first_name = first_name 97 | self.last_name = last_name 98 | 99 | def __add__(self, person): 100 | # Adds the 2 strings together and updates our lastname 101 | self.last_name = self.last_name + "-" + person.last_name 102 | # Updates 2nd persons last name to match ours 103 | person.last_name = self.last_name 104 | return person 105 | ``` 106 | 107 | **Tip: all magic methods follow the format `__X__` with double underscores on either side. They are sometimes called "dunder methods" because of this.** 108 | 109 | The way this works is that whenever we do `skidy + dark` where `skidy` and `dark` are objects of the class `Person` we will add Dark's lastname to Skidy's last name, and we will return Dark with their new last name too. 110 | 111 | Our code looks like: 112 | 113 | ```python 114 | skidy = Person("Skidy", "Shallot") 115 | dark = Person("Dork", "Star") 116 | 117 | dark = skidy + dark 118 | 119 | skidy.last_name 120 | # Shallot-Star 121 | dark.last_name 122 | # Shallot-Star 123 | ``` 124 | 125 | But the real magic here is that we implemented addition for our own code! This is the power of magic methods, and I'll go into much more detail later on. Anyway, back to operators! 126 | 127 | ### What data structures have magic methods? 128 | 129 | Almost all of them implement the basic magic methods which are: 130 | 131 | * Addition 132 | * Subtraction 133 | 134 | Division / Mod / Comparison \(==, ≠ \(talked about soon\)\) are rarer, but can still be seen in some operators. 135 | 136 | -------------------------------------------------------------------------------- /what-is-python/object-orientated-programming.md: -------------------------------------------------------------------------------- 1 | # Object Orientated Programming 2 | 3 | Object orientated programming revolves around objects. Don't worry, we won't talk about them for long. 4 | 5 | An object can be anything you want. 6 | 7 | Imagine a bicycle. The bike is an object with the name "bike". 8 | 9 | The wheels of the bike are objects too, which are said to be attributes \(objects can be attributes of other objects in Python\) of the parent class bike. 10 | 11 | Let's go right into an example. 12 | 13 | ```python 14 | class Wheel: 15 | ``` 16 | 17 | We define a class by calling `class :`. Our class is called wheel here. 18 | 19 | What do wheels have? Well, they have tyres so let's add one. 20 | 21 | ```python 22 | class Wheel: 23 | self.tyre = "Michelin" 24 | ``` 25 | 26 | Now our wheel has a Michelin tyre. 27 | 28 | Classes are templates for objects. We can build a class such as a wheel, and when we build an object from our class we are saying "every object is based on this one template class". 29 | 30 | When we build a new Wheel object: 31 | 32 | ```python 33 | x = Wheel() 34 | y = Wheel() 35 | 36 | x.tyre 37 | # "Michelin" 38 | y.tyre 39 | # "Michelin" 40 | ``` 41 | 42 | It will always have the items in the class definition. In this instance, every single wheel of our bike will always have a Michelin tyre. 43 | 44 | Now let's get into magic methods. 45 | 46 | Imagine you have a Person class: 47 | 48 | ```python 49 | class Person: 50 | def __init__(self, first_name, last_name): 51 | self.first_name = first_name 52 | self.last_name = last_name 53 | ``` 54 | 55 | The `__init__` stands for `initialisation`. When we _initialise_ \(create\) an object from this class, this function runs. The function has 3 arguments. 56 | 57 | 1. `self` 58 | 59 | Every function \(called a method in OOP\) requires a `self` attribute \(in Python\). 60 | 61 | 1. `first_name` 62 | 63 | The first name of the person. 64 | 65 | 1. `last_name` 66 | 67 | The last name of the person. 68 | 69 | Because we have the argument `self`, we can change the classes _attributes_ \(the values of the object, think back to our wheel example having the attribute that all tyres are "Michelin"\). 70 | 71 | So we can do this: 72 | 73 | ```python 74 | skidy = Person("Skidy", "Shallot") 75 | skidy.first_name 76 | # "Skidy" 77 | skidy.last_name 78 | # "Shallot" 79 | ``` 80 | 81 | What if we have another person, Dark? 82 | 83 | ```python 84 | dark = Person("Dork", "Star") 85 | ``` 86 | 87 | Now, Dark and Skidy want to get married. In the imaginery land of TryHackMe marriage happens by adding the 2nd persons lastname onto the first. So if Skidy & Dark got married, their combined last name would be `Shallot-Star`. 88 | 89 | How do we program this so that any person getting married has a new last name that matches this? 90 | 91 | With magic methods! 92 | 93 | ```python 94 | class Person: 95 | def __init__(self, first_name, last_name): 96 | self.first_name = first_name 97 | self.last_name = last_name 98 | 99 | def __add__(self, person): 100 | # Adds the 2 strings together and updates our lastname 101 | self.last_name = self.last_name + "-" + person.last_name 102 | # Updates 2nd persons last name to match ours 103 | person.last_name = self.last_name 104 | return person 105 | ``` 106 | 107 | **Tip: all magic methods follow the format `__X__` with double underscores on either side. They are sometimes called "dunder methods" because of this.** 108 | 109 | The way this works is that whenever we do `skidy + dark` where `skidy` and `dark` are objects of the class `Person` we will add Dark's lastname to Skidy's last name, and we will return Dark with their new last name too. 110 | 111 | Our code looks like: 112 | 113 | ```python 114 | skidy = Person("Skidy", "Shallot") 115 | dark = Person("Dork", "Star") 116 | 117 | dark = skidy + dark 118 | 119 | skidy.last_name 120 | # Shallot-Star 121 | dark.last_name 122 | # Shallot-Star 123 | ``` 124 | 125 | But the real magic here is that we implemented addition for our own code! This is the power of magic methods, and I'll go into much more detail later on. Anyway, back to operators! 126 | 127 | ## What data structures have magic methods? 128 | 129 | Almost all of them implement the basic magic methods which are: 130 | 131 | * Addition 132 | * Subtraction 133 | 134 | Division / Mod / Comparison \(==, ≠ \(talked about soon\)\) are rarer, but can still be seen in some operators. 135 | 136 | -------------------------------------------------------------------------------- /.gitbook/assets/variables.md: -------------------------------------------------------------------------------- 1 | # Object Orientated Programming 2 | 3 | Object orientated programming revolves around objects. Don't worry, we won't talk about them for long. 4 | 5 | An object can be anything you want. 6 | 7 | Imagine a bicycle. The bike is an object with the name "bike". 8 | 9 | The wheels of the bike are objects too, which are said to be attributes \(objects can be attributes of other objects in Python\) of the parent class bike. 10 | 11 | Let's go right into an example. 12 | 13 | ```python 14 | class Wheel: 15 | ``` 16 | 17 | We define a class by calling `class :`. Our class is called wheel here. 18 | 19 | What do wheels have? Well, they have tyres so let's add one. 20 | 21 | ```python 22 | class Wheel: 23 | self.tyre = "Michelin" 24 | ``` 25 | 26 | Now our wheel has a Michelin tyre. 27 | 28 | Classes are templates for objects. We can build a class such as a wheel, and when we build an object from our class we are saying "every object is based on this one template class". 29 | 30 | When we build a new Wheel object: 31 | 32 | ```python 33 | x = Wheel() 34 | y = Wheel() 35 | 36 | x.tyre 37 | # "Michelin" 38 | y.tyre 39 | # "Michelin" 40 | ``` 41 | 42 | It will always have the items in the class definition. In this instance, every single wheel of our bike will always have a Michelin tyre. 43 | 44 | Now let's get into magic methods. 45 | 46 | Imagine you have a Person class: 47 | 48 | ```python 49 | class Person: 50 | def __init__(self, first_name, last_name): 51 | self.first_name = first_name 52 | self.last_name = last_name 53 | ``` 54 | 55 | The `__init__` stands for `initialisation`. When we _initialise_ \(create\) an object from this class, this function runs. The function has 3 arguments. 56 | 57 | 1. `self` 58 | 59 | Every function \(called a method in OOP\) requires a `self` attribute \(in Python\). 60 | 61 | 1. `first_name` 62 | 63 | The first name of the person. 64 | 65 | 1. `last_name` 66 | 67 | The last name of the person. 68 | 69 | Because we have the argument `self`, we can change the classes _attributes_ \(the values of the object, think back to our wheel example having the attribute that all tyres are "Michelin"\). 70 | 71 | So we can do this: 72 | 73 | ```python 74 | skidy = Person("Skidy", "Shallot") 75 | skidy.first_name 76 | # "Skidy" 77 | skidy.last_name 78 | # "Shallot" 79 | ``` 80 | 81 | What if we have another person, Dark? 82 | 83 | ```python 84 | dark = Person("Dork", "Star") 85 | ``` 86 | 87 | Now, Dark and Skidy want to get married. In the imaginery land of TryHackMe marriage happens by adding the 2nd persons lastname onto the first. So if Skidy & Dark got married, their combined last name would be `Shallot-Star`. 88 | 89 | How do we program this so that any person getting married has a new last name that matches this? 90 | 91 | With magic methods! 92 | 93 | ```python 94 | class Person: 95 | def __init__(self, first_name, last_name): 96 | self.first_name = first_name 97 | self.last_name = last_name 98 | 99 | def __add__(self, person): 100 | # Adds the 2 strings together and updates our lastname 101 | self.last_name = self.last_name + "-" + person.last_name 102 | # Updates 2nd persons last name to match ours 103 | person.last_name = self.last_name 104 | return person 105 | ``` 106 | 107 | **Tip: all magic methods follow the format `__X__` with double underscores on either side. They are sometimes called "dunder methods" because of this.** 108 | 109 | The way this works is that whenever we do `skidy + dark` where `skidy` and `dark` are objects of the class `Person` we will add Dark's lastname to Skidy's last name, and we will return Dark with their new last name too. 110 | 111 | Our code looks like: 112 | 113 | ```python 114 | skidy = Person("Skidy", "Shallot") 115 | dark = Person("Dork", "Star") 116 | 117 | dark = skidy + dark 118 | 119 | skidy.last_name 120 | # Shallot-Star 121 | dark.last_name 122 | # Shallot-Star 123 | ``` 124 | 125 | But the real magic here is that we implemented addition for our own code! This is the power of magic methods, and I'll go into much more detail later on. Anyway, back to operators! 126 | 127 | ### What data structures have magic methods? 128 | 129 | Almost all of them implement the basic magic methods which are: 130 | 131 | * Addition 132 | * Subtraction 133 | 134 | Division / Mod / Comparison \(==, ≠ \(talked about soon\)\) are rarer, but can still be seen in some operators. 135 | -------------------------------------------------------------------------------- /advanced/set-theory.md: -------------------------------------------------------------------------------- 1 | # Set Theory 2 | 3 | A set is simply a set of objects. They don't have to be the same type, or have any relation to one another. 4 | 5 | ```python 6 | set = (apples, pears, oranges) 7 | ``` 8 | 9 | Sets are denoted with parenthesis `( )`. With the separation of elements being a comma. Or sometimes `{ }`. 10 | 11 | Sets follow 2 rules: 12 | 13 | * Only unique items. 14 | 15 | Sets can only contain unique items. It cannot contain the same item twice or more. 16 | 17 | * The set is unordered. 18 | 19 | There is no order or structure to a set. 20 | 21 | The first rule is quite useful. Say, for example we have a list of words from a book: 22 | 23 | ```python 24 | words = ["hello", "my", "name", "is", "brandon", "and", 25 | "your", "name", "is", "brandon"] 26 | ``` 27 | 28 | To find all the unique words, we put the words into a set: 29 | 30 | ```python 31 | words = ["hello", "my", "name", "is", "brandon", "and", 32 | "your", "name", "is", "brandon"] 33 | 34 | unique = set(words) 35 | # {'hello', 'is', 'and', 'brandon', 'my', 'your', 'name'} 36 | ``` 37 | 38 | The 2nd rule ties in nicely with the 1st rule. **A set aims to replicate how we see things in our lives.** 39 | 40 | Imagine we are on a road trip with Jahan, Olivia, and Ryan. 41 | 42 | Next year, we want to go on a field trip again. It doesn't make much sense to invite Jahan, Olivia, Jahan, Ryan, Jahan. 43 | 44 | And it also doesn't make sense to assign an "order" to them. They're people, not elements in an array! 45 | 46 | There are other types of sets too. Such as a a [multiset](https://en.wikipedia.org/wiki/Multiset) which allows non-unique elements but no order. 47 | 48 | **Note** sets are a computer science / maths topic. I will quickly go over the maths, and we will explore how this is applied in Python, 49 | 50 | ## 🦁 Cardinality 51 | 52 | The cardinality of a set is the length of the set. For the set: 53 | 54 | ```python 55 | A={1,2,3,4,5,6} 56 | ``` 57 | 58 | The cardinality is 59 | 60 | ```python 61 | |A|=6 62 | ``` 63 | 64 | ## 🚴‍♀️ Equality of Sets 65 | 66 | 2 sets are equal when all the elements match. 67 | 68 | ```python 69 | a={1,2,3} 70 | b={3,2,1} 71 | a==b 72 | # True 73 | ``` 74 | 75 | Remember, order doesn't matter - so sets are equal despite being in the 'wrong' order! 76 | 77 | ## 🚇 Infinite Sets 78 | 79 | Some sets are infinite. Such as the set containing all the natural numbers, or all the real numbers. 80 | 81 | We can express infinite sets using a little bit of maths. Heard of [list comprehensions](https://skerritt.blog/learn-functional-python-in-10-minutes/)? It looks the same syntactically, but operates infinitely. 82 | 83 | The set of all even numbers is: 84 | 85 | $$ 86 | A={2n:n ∈ Z} 87 | $$ 88 | 89 | Read this as "for each number, n, in the set of all integers, Z, multiply the number by 2". Which will give us the set of all even numbers. 90 | 91 | In a list comprehension, it would look like: 92 | 93 | ```python 94 | [2 * n for n in naturalNumbers] 95 | ``` 96 | 97 | However, this won't work as Python doesn't allow infinite sets. 98 | 99 | ## 🐈‍⬛ The Empty Set 100 | 101 | The empty set is the set containing nothing at all. It is much like 0. It is nothing, and serves the purpose as a negated value. We don't have 0 apples, we have no apples. 102 | 103 | The empty set serves the same purpose. We don't have a set containing all the words, we have nothing. 104 | 105 | Its symbol is ∅. 106 | 107 | ## 🌌 The Universal Set 108 | 109 | The Universal Set U is the set which contains all objects, including itself. 110 | 111 | If our universe contains only integers, 1, 2, 3, ..., then the universal set is the set of all integers. 112 | 113 | ## 🏥 Operations 114 | 115 | Just like with other data types, sets have operations! Let's start with some operations you may already know. 116 | 117 | ### ❌ Union 118 | 119 | The union is combining 2 sets together \(think addition\). The symbol for the union is ∪. Let's look at an example. 120 | 121 | ```python 122 | A = {1, 2, 3} 123 | B = {3, 4, 5} 124 | B U A = {1, 2, 3, 4, 5} 125 | ``` 126 | 127 | Notice how when we perform a union, we have two 3's. Since sets only contain unique elements, we simply toss the extra 3 away. Also note, there is no order. So B ∪ 128 | 129 | A does not result in \(3, 4, 5...\) as the order doesn't exist. We can even say `B ∪ A = {3, 5, 1, 4, 2}`.What if we union an empty set with a non-empty set? Or an empty set with another empty set? 130 | 131 | ```python 132 | ∅∪{1,2,3}={1,2,3} 133 | ∅∪∅=∅ 134 | ``` 135 | 136 | When we get onto subsets and the likes we'll learn to appreciate the empty set and this simplistic maths. 137 | 138 | -------------------------------------------------------------------------------- /getting-started/variables.md: -------------------------------------------------------------------------------- 1 | # Variables 2 | 3 | Now in the last section, I said "String \(a string of characters\)". 4 | 5 | What does that mean? 6 | 7 | In programming we need to have data types. Every bit of data has a type in common with it. You already know some. 8 | 9 | If I said: 10 | 11 | ```text 12 | 1, 2, 3, 4, 5, 6, 7, 8, 9 13 | ``` 14 | 15 | "Are these sentences?" 16 | 17 | No! They're numbers. 18 | 19 | See, you already know data types 😜 20 | 21 | In Python, it's the same. We have some essential data types that hold things: 22 | 23 | * String \(a string of characters\) 24 | * Integer - a whole number \(-50, 50, 60, 91\) 25 | * Float - a floating point number \(21.3, -5.1921\) 26 | * List - a list of items \(\[1, 2, 3\], \["hi", 6, 7.91\]\) 27 | 28 | And more. 29 | 30 | Now, let's dis-spell a myth. 31 | 32 | Variables are like buckets in the sense that you can store things in them. Imagine a bucket and you want to put a sentence into it: 33 | 34 | ![](../.gitbook/assets/image%20%285%29.png) 35 | 36 | We make a bucket called `hello` and in the bucket we put in the string `"Hello, World!"`. 37 | 38 | We use the equals sign as an _assignment operator_. It assigns the value on the right hand side to the bucket on the left. 39 | 40 | Now let's say we wanted to add this variable to another variable. A common misconception is that we take the bucket itself and use that. 41 | 42 | But in Python, we don't. We _pass by reference_. As in, we merely pass a location of the variable — we do not pass the variable itself. The alternative is _pass by value_. 43 | 44 | This is very important to understand, as it can cause a significant amount of headaches later on. 45 | 46 | ![](../.gitbook/assets/yes.gif) 47 | 48 | [Gif from here](https://blog.penjee.com/passing-by-value-vs-by-reference-java-graphical/) 49 | 50 | Remember lists from earlier? 51 | 52 | ```python 53 | hellos = ["Hello", "yo", "sup?", "alright?"] 54 | ``` 55 | 56 | How we can store items in lists. 57 | 58 | Lists have different methods which allow us to manipulate the list. A popular one is appending an item to a list, like this 59 | 60 | ```python 61 | hellos = ["Hello", "yo", "sup?", "alright?"] 62 | hellos.append("TryHackMe") 63 | print(hellos) 64 | # ["Hello", "yo", "sup?", "alright?", "TryHackMe"] 65 | ``` 66 | 67 | `.append(item)` appends the item to the end of the list. 68 | 69 | Let's see this bug in action. 70 | 71 | ```python 72 | list1 = [1, 2] 73 | list2 = [3, 4] 74 | list1.append(list2) 75 | # List1 is now [1, 2, [3, 4]] 76 | # We appended the list, not the contents of the list 77 | ``` 78 | 79 | When we append a list to another list, we do not merge the elements together. Instead we append the entire list \(including the list itself\) to the other list. 80 | 81 | ```python 82 | # Continueing from last code block 83 | list2.append(6) 84 | print(list1) 85 | # [1, 2, [3, 4, 6]] 86 | ``` 87 | 88 | Now, let's look at the bug in more detail: 89 | 90 | ```text 91 | list1 = [1, 2] 92 | list2 = [3, 4] 93 | list1.append(list2) 94 | list2.append(6) 95 | print(list1) 96 | # [1, 2, [3, 4, 6]] 97 | ``` 98 | 99 | When we appended `list2` to `list1`, we did not actually append the list. We appended the reference to the list. 100 | 101 | When we changed `list2`, because `list1` had the reference appended it "updates" itself to match the newly updated `list2`. 102 | 103 | In Python, this type of bug can happen all the time. We never pass the values of things, always the references. So be sure to keep an eye open for this type of thing. 104 | 105 | In some languages like Rust you get the option of value or reference. But in Python, you only get the option of reference. This is because if we started passing values, Python would have to spend more time on their garbage collection system. 106 | 107 | Garbage collection is where we store variables in the system and remove them when they are no longer needed. Higher level languages do this automatically. Lower level languages you might have to do it yourself. 108 | 109 | Here's a quick table for data structures in Python: 110 | 111 | | Name | Description | Example | Converter | 112 | | :--- | :--- | :--- | :--- | 113 | | String | A string of characters, used for text. | `"Hello"` | `str(x)` | 114 | | Boolean | True or False value. | `True`, `False` | `bool(x)` | 115 | | Integer | A whole number. | `60` | `int(x)` | 116 | | Float | A floating point number. | `4.6` | `float(x)` | 117 | | List | A list of items. | `[3, 7, 2]` | `list(x)` | 118 | | Dictionary | A key:value pairing. Discussed later. | `{1: "One"}` | `dict(x)` | 119 | 120 | The converter column is how we can convert data types. For example, to convert the string "6" into an integer, we do int\("6"\). 121 | 122 | -------------------------------------------------------------------------------- /what-is-python/boolean-values.md: -------------------------------------------------------------------------------- 1 | # Boolean Values 2 | 3 | Boolean Algebra & Operators are so useful, I had to devote an entire section to them! 4 | 5 | Binary is a bunch of 0's and 1's, but how do we display computational complexity in binary? If we convert programming languages into binary, how does the computer know that "11" means "1" and not "0"? 6 | 7 | We have to use some operators for this. In fact, we have to use some boolean operators! 8 | 9 | **Bee's Fun Facts: Binary was invented before Boolean algebra. But it still took us hundreds of years to figure out that we can use Binary in our electronic systems. Thanks, George Boole!** 10 | 11 | The two values for the data type boolean are `True` and `False`. 12 | 13 | True and False are extremely valuable. In binary, 1 represents True and 0 represents False. 14 | 15 | Through these 2 values we can represent all data on a computer, provided we are using logic gates. 16 | 17 | Those logic gates appear in Python as operators. We'll go through one you may already know: 18 | 19 | ```python 20 | True or False 21 | # True 22 | ``` 23 | 24 | The `or` operator returns true when either the left side or right side is True. 25 | 26 | Let's quickly go through all the others: 27 | 28 | ```python 29 | True and True 30 | # True 31 | ``` 32 | 33 | This returns True if and only if both the left and right sides are True. 34 | 35 | ```python 36 | not True 37 | # False 38 | ``` 39 | 40 | `not` negates the right hand side expression. So the opposite of `True` is False. 41 | 42 | We can negate the Or statement like so: 43 | 44 | ```python 45 | not (True or False) 46 | # False 47 | ``` 48 | 49 | Now it only returns True when both sides of the `or` are `False`. 50 | 51 | What if we wanted an exclusive or \(xor\)? It only returns True when only 1 side of the equation is True, not both \(otherwise it's more like an Or with an And\). 52 | 53 | Python can do this with: 54 | 55 | ```python 56 | True ^ False 57 | # True 58 | True ^ True 59 | # False 60 | ``` 61 | 62 | For more on the history of boolean algebra, check out [CODE](https://www.goodreads.com/book/show/44882.Code). 63 | 64 | Now, let's see something wacky. 65 | 66 | Remember how I said True was 1 and False was 0? 67 | 68 | ```python 69 | x = 0 70 | x += True 71 | # += True is short-hand for x = x + True 72 | x += True 73 | x += True 74 | print(x) 75 | # 3 76 | ``` 77 | 78 | You've got to be real careful if you add booleans together, they don't work how you might expect them to 😅 79 | 80 | We also have many operators that return booleans. 81 | 82 | For example: 83 | 84 | ```python 85 | "a" in ["a", "b", "c"] 86 | # True 87 | ``` 88 | 89 | The in operator checks to see if the item is in an iterable \(an iterable is anything we can iterate over, such as a list\). 90 | 91 | ```python 92 | None is None 93 | ``` 94 | 95 | The is operator checks to see if the left hand side is the right hand side. 96 | 97 | ```python 98 | True == False 99 | # False 100 | ``` 101 | 102 | The `==` operator checks to see if they both have the _same value_. 103 | 104 | Remember earlier when I showed you that fun trickery with Python's pass-by-reference variables? 105 | 106 | Let me show you something cooler! 107 | 108 | ```python 109 | x = [] 110 | y = [] 111 | 112 | x == y 113 | # True 114 | 115 | x is y 116 | # False 117 | ``` 118 | 119 | They have the same value, an empty list, but they are not referencing the same object. 120 | 121 | Make sure to watch out for this one as it can happen a lot when you create your own data structures. 122 | 123 | To use `not` with an equality operator we need to use `!` like so: 124 | 125 | ```python 126 | 9 != 6 127 | # 9 not equal 6 128 | # True 129 | ``` 130 | 131 | Now there are some other cool things, like less than or more than. 132 | 133 | ```python 134 | 6 < 6 135 | # 6 less than 6 136 | # True 137 | 138 | 6 > 6 139 | # 6 more than 6 140 | # False 141 | 142 | 6 <= 6 143 | # 6 less than or equal to 6 144 | # True 145 | 146 | 6 >= 6 147 | # 6 more than or equal to 6 148 | # True 149 | ``` 150 | 151 | You can implement these methods in your own classes using magic methods. Greater than or equal to is `__ge__`. 152 | 153 | Okay, one last funny trick for this section! Remember how I said that True and False are 1 and 0? 154 | 155 | ```python 156 | False < True 157 | # True 158 | ``` 159 | 160 | What a funny quirk! 161 | 162 | Now, onto something more important. 163 | 164 | All empty data structures have a Falsey value, and all non-empty data structures have a Truthy value. 165 | 166 | ```python 167 | x = [] 168 | bool(x) 169 | # False 170 | 171 | y = [6] 172 | bool(y) 173 | # True 174 | ``` 175 | 176 | This will come in very useful in the next section. 177 | 178 | -------------------------------------------------------------------------------- /what-is-python/what-is-python-1/high-level.md: -------------------------------------------------------------------------------- 1 | # High Level 2 | 3 | ## High Level 4 | 5 | Let's use a different language as an example, C++. When we write code in C++ code, we write it in a language similar to English. 6 | 7 | ```cpp 8 | #include 9 | int main() 10 | { 11 | std::cout << "Hello, World!" << std::endl; 12 | return 0; 13 | } 14 | ``` 15 | 16 | This code prints "Hello, World!" to the screen. Looks confusing, right? But if you read the words you can see some English words. `main`, include, end, "Hello, World!", return and some more. 17 | 18 | When we write code, we write it in a language that is similar to English but also technical enough for the computer to understand. 19 | 20 | Normal English is a bad programming language, since we can mean different things from the same sentence. For example: 21 | 22 | "Alright" and "Alright" mean 2 different things in British English \(Alright means "hello" and "it's good"\). 23 | 24 | The computer would have no idea how to interpret this. English is a bad programming language, so we have to use something that's a mixture of something the computer can understand and something we can understand. 25 | 26 | In the case of C++ that mixture is more 50% human, 50% computer \(arbitrary numbers\). The more the mixture leans to the human side, the more "high level" it is 27 | 28 | ![](../../.gitbook/assets/image%20%281%29.png) 29 | 30 | Python is more high level, so it leans more to the human side. 31 | 32 | ![](../../.gitbook/assets/image.png) 33 | 34 | Take a look at this Python code: 35 | 36 | ```python 37 | def hello_world(): 38 | print("Hello, World!") 39 | ``` 40 | 41 | If I told you that `def` was short for `define` you'd now know every single word in that program. Whereas with C++ it was a lot harder to understand. 42 | 43 | This is what we mean by high level and low level. 44 | 45 | **Python is high level because it is more understandable by humans with no programming experience.** Whereas C++ is less understandable. 46 | 47 | Now, what if I told you that I lied to you? The computer doesn't understand any human language at all. 48 | 49 | That's right! Even C++ it doesn't understand. What if I told you that there's an even more un-readable language called Assembly? 50 | 51 | Here's an example I stole from the [web](https://cs.lmu.edu/~ray/notes/x86assembly/), "Hello, World!" in x86 Assembly. 52 | 53 | ```text 54 | global _start 55 | 56 | section .text 57 | _start: mov rax, 1 ; system call for write 58 | mov rdi, 1 ; file handle 1 is stdout 59 | mov rsi, message ; address of string to output 60 | mov rdx, 13 ; number of bytes 61 | syscall ; invoke operating system to do the write 62 | mov rax, 60 ; system call for exit 63 | xor rdi, rdi ; exit code 0 64 | syscall ; invoke operating system to exit 65 | 66 | section .data 67 | message: db "Hello, World", 10 ; note the newline at the end 68 | ``` 69 | 70 | This language right here is very machine-like, but the computer still cannot understand it! 71 | 72 | ![](../../.gitbook/assets/image%20%283%29.png) 73 | 74 | So, what does the computer understand? In terms of our very weird see-saw: 75 | 76 | ![](../../.gitbook/assets/image%20%282%29.png) 77 | 78 | Imagine someone takes our see-saw, they carry the plank to Mars and they stand it up. That's what it's like. The computer does not understand the human language **at all**. 79 | 80 | If computers cannot understand the human language, why do we write human language? Why do we not write in machine language? How does the computer understand human language, the? 81 | 82 | 1.Why do we write human language, not machine language? 83 | 84 | Abstraction. Abstraction is where we take something complex, we remove some of the complexity and make it simpler. 85 | 86 | Abstraction is the backbone of every computer scientist in the world, and all machines. Abstraction is what causes exploits in machines, but it's also what causes better & more secure code to be written. 87 | 88 | The "Hello, World!" function in x86 assembly you saw is 12 lines. In Python, we can make it one line: 89 | 90 | ```python 91 | print("Hello, World!") 92 | ``` 93 | 94 | If we had to write 12 lines for every 1 line of Python, we'd never finish any software. 95 | 96 | Not to mention that it's far easier for us to introduce bugs in code if there are more lines then less. 97 | 98 | With Python, we know that other people smarter than us have read the `print` code and can confirm it cannot be exploited. 99 | 100 | With our hand-written Assembly, we cannot. 101 | 102 | In fact, we cannot even confirm that our assembly code is the most efficient method. In C++ we use something called zero cost abstractions for this. See my Rust room for more information `room code: rust`. 103 | 104 | 1. How does the computer understand human language? 105 | 106 | Bingo! This is where I was going with this. 107 | 108 | Let's say you're from the United Kingdom. And you visit China. Here's a typical conversation: 109 | 110 | > You: "Oi bruv givs a botla ov wotr" 111 | > 112 | > Shop Keeper: 你这个傻小子,我们这里不说这种语言 113 | 114 | Do you see the problem here? 115 | 116 | Now, how would you go about talking to the shop keeper? 117 | 118 | You'd use a translator. Either a person, or an app. 119 | 120 | How does our human-readable code talk to the computer? We use a translator called a _compiler_. 121 | 122 | The compiler converts our code into binary code for the computer to understand. And at the end, we get an executable file we can run. 123 | 124 | Translating is rather slow and expensive. We don't want to spend 5 minutes translating! 125 | 126 | This brings us onto.... 127 | 128 | -------------------------------------------------------------------------------- /what-is-python/functions/README.md: -------------------------------------------------------------------------------- 1 | # Functions 2 | 3 | One of the principles of writing clean code is DRY: 4 | 5 | > Don't Repeat Yourself \(DRY\) 6 | 7 | But, inevitably we will repeat ourselves. Since up to now, code is linear. We run code and move onto the next section after it. 8 | 9 | This is where functions come in. 10 | 11 | Functions are little boxes you put something in and get a result out. They can be used multiple times, preventing us from repeating ourselves if used correctly. 12 | 13 | ![](../../.gitbook/assets/image%20%287%29.png) 14 | 15 | We input something into the box like 2, the box does something with our input and it outputs something like 4. 16 | 17 | In this case, the box squares the input number. 18 | 19 | If we wanted to square a bunch of numbers, we would have to write something like: 20 | 21 | ```python 22 | 2**2 23 | 3**2 24 | 4**2 25 | ``` 26 | 27 | But what if, eventually, we wanted to square more numbers? Or if we wanted to square a users input? We cannot possibly cover all cases. So let's put it into a function. 28 | 29 | ```python 30 | def square(num): 31 | return num**2 32 | ``` 33 | 34 | Now we can square any number we want with this function. 35 | 36 | The function is the black box. 37 | 38 | Every function in Python is defined by the keyword `def` \(which means, literally, define\). 39 | 40 | After the `def` keyword we name the function. Let's call it Skidy. 41 | 42 | ```python 43 | def skidy 44 | ``` 45 | 46 | Next up we add the function arguments. Arguments are variables we input into the function. 47 | 48 | Remember our magical box? We had inputs into it. The function's arguments are the inputs. 49 | 50 | Let's say the function `skidy` returns "Hello, DorkStar" if the name is "dork" else it will return "Goodbye, {name}". 51 | 52 | We need one of the inputs to be a name. 53 | 54 | ```python 55 | def skidy(name) 56 | ``` 57 | 58 | And then finally, as we saw with if statements we need to include a : on the end of the definition. This means that our next line will be tabbed by 4 spaces. 59 | 60 | ```python 61 | def skidy(name): 62 | ``` 63 | 64 | Now we check to see if the name is "dork" and return "Hello, Dorkstar". 65 | 66 | ```python 67 | def skidy(name): 68 | if name == "dork": 69 | return "Hello, DorkStar" 70 | ``` 71 | 72 | Remember the magic box from earlier? It output something. The `return` statement is the output. 73 | 74 | Now, we want to return "Hello, {name}" if their name isn't Dork: 75 | 76 | ```python 77 | def skidy(name): 78 | if name == "dork": 79 | return "Hello, DorkStar" 80 | else: 81 | return f"Hello, {name}" 82 | ``` 83 | 84 | We now have our function! But you may have noticed something unusual. What's that `f"Goodbye, {name}"`? 85 | 86 | This is called an `f-string` in Python. It stands for "Formatted String". 87 | 88 | Strings are kinda boring. They don't really convey information. If we rewrote the code: 89 | 90 | ```python 91 | def skidy(): 92 | return "Hello, Celestron" 93 | ``` 94 | 95 | What if Cmnatic does not run our program? What if it's someone else? 96 | 97 | We need a way to take in a variable, and change what we print based on the variable. 98 | 99 | We do this with formatted strings. 100 | 101 | To make an f-string, start the string with the letter `f`. 102 | 103 | ```python 104 | f"This is an f-string" 105 | ``` 106 | 107 | And now to use a variable in the string, include it in some curly braces `{`. 108 | 109 | ```python 110 | name = "Patrick" 111 | f"Hello, this is {name}". 112 | ``` 113 | 114 | Let's go back to our code. 115 | 116 | ```python 117 | def skidy(name): 118 | if name == "dork": 119 | return "Hello, DorkStar" 120 | else: 121 | return f"Hello, {name}" 122 | ``` 123 | 124 | This code is messy. Do you know why? Hint: `f-strings`. 125 | 126 | Python has a poem called `The Zen of Python` which details what makes Pythonic code. 127 | 128 | ```text 129 | >>> import this 130 | The Zen of Python, by Tim Peters 131 | 132 | Beautiful is better than ugly. 133 | Explicit is better than implicit. 134 | Simple is better than complex. 135 | Complex is better than complicated. 136 | Flat is better than nested. 137 | Sparse is better than dense. 138 | Readability counts. 139 | Special cases aren't special enough to break the rules. 140 | Although practicality beats purity. 141 | Errors should never pass silently. 142 | Unless explicitly silenced. 143 | In the face of ambiguity, refuse the temptation to guess. 144 | There should be one-- and preferably only one --obvious way to do it. 145 | Although that way may not be obvious at first unless you're Dutch. 146 | Now is better than never. 147 | Although never is often better than *right* now. 148 | If the implementation is hard to explain, it's a bad idea. 149 | If the implementation is easy to explain, it may be a good idea. 150 | Namespaces are one honking great idea -- let's do more of those! 151 | ``` 152 | 153 | This code is both nested, complex and isn't the most obvious way. 154 | 155 | We can rewrite our code using one line if statements and f-strings like so: 156 | 157 | ```python 158 | def skidy(name): 159 | print(f"Hello, {'DorkStar' if name == 'Dork' else name}") 160 | ``` 161 | 162 | To include quotation marks in strings, we have 2 options. 163 | 164 | 1. We use the other kind of quotation marks. So if we do `print(" 'hi' ")` we would have to use `'`. Same for the other way around. 165 | 2. We use triple quotation marks `print("""Hello "this is a good example" """)`. 166 | 167 | And now our code is clean! 168 | 169 | Refactoring code is a very important part of programming. As the code grows, we'll have new functions and new ways to make the code clean. 170 | 171 | How do you think we can call our new function? Hint: we have been using functions from the start. `print()` is a function. 172 | 173 | ```python 174 | def skidy(name): 175 | print(f"Hello, {'DorkStar' if name == 'Dork' else name}") 176 | 177 | skidy("Dork") 178 | # Hello, DorkStar 179 | skidy("skidy") 180 | # Hello, skidy 181 | ``` 182 | 183 | -------------------------------------------------------------------------------- /what-is-python/high-level.md: -------------------------------------------------------------------------------- 1 | # High Level 2 | 3 | Python is a programming language created by Guido \(pronounced gree-do\) Van Rossum. Specifically, Python is an _intrepreted_, _high-level_, _general purpose_ programming language. 4 | 5 | Let's talk about what these mean. 6 | 7 | ## High Level 8 | 9 | Let's use a different language as an example, C++. When we write code in C++ code, we write it in a language similar to English. 10 | 11 | ```cpp 12 | #include 13 | int main() 14 | { 15 | std::cout << "Hello, World!" << std::endl; 16 | return 0; 17 | } 18 | ``` 19 | 20 | This code prints "Hello, World!" to the screen. Looks confusing, right? But if you read the words you can see some English words. `main`, include, end, "Hello, World!", return and some more. 21 | 22 | When we write code, we write it in a language that is similar to English but also technical enough for the computer to understand. 23 | 24 | Normal English is a bad programming language, since we can mean different things from the same sentence. For example: 25 | 26 | "Alright" and "Alright" mean 2 different things in British English \(Alright means "hello" and "it's good"\). 27 | 28 | The computer would have no idea how to interpret this. English is a bad programming language, so we have to use something that's a mixture of something the computer can understand and something we can understand. 29 | 30 | In the case of C++ that mixture is more 50% human, 50% computer \(arbitrary numbers\). The more the mixture leans to the human side, the more "high level" it is 31 | 32 | ![](../.gitbook/assets/image%20%281%29.png) 33 | 34 | Python is more high level, so it leans more to the human side. 35 | 36 | ![](../.gitbook/assets/image.png) 37 | 38 | Take a look at this Python code: 39 | 40 | ```python 41 | def hello_world(): 42 | print("Hello, World!") 43 | ``` 44 | 45 | If I told you that `def` was short for `define` you'd now know every single word in that program. Whereas with C++ it was a lot harder to understand. 46 | 47 | This is what we mean by high level and low level. 48 | 49 | **Python is high level because it is more understandable by humans with no programming experience.** Whereas C++ is less understandable. 50 | 51 | Now, what if I told you that I lied to you? The computer doesn't understand any human language at all. 52 | 53 | That's right! Even C++ it doesn't understand. What if I told you that there's an even more un-readable language called Assembly? 54 | 55 | Here's an example I stole from the [web](https://cs.lmu.edu/~ray/notes/x86assembly/), "Hello, World!" in x86 Assembly. 56 | 57 | ```text 58 | global _start 59 | 60 | section .text 61 | _start: mov rax, 1 ; system call for write 62 | mov rdi, 1 ; file handle 1 is stdout 63 | mov rsi, message ; address of string to output 64 | mov rdx, 13 ; number of bytes 65 | syscall ; invoke operating system to do the write 66 | mov rax, 60 ; system call for exit 67 | xor rdi, rdi ; exit code 0 68 | syscall ; invoke operating system to exit 69 | 70 | section .data 71 | message: db "Hello, World", 10 ; note the newline at the end 72 | ``` 73 | 74 | This language right here is very machine-like, but the computer still cannot understand it! 75 | 76 | ![](../.gitbook/assets/image%20%283%29.png) 77 | 78 | So, what does the computer understand? In terms of our very weird see-saw: 79 | 80 | ![](../.gitbook/assets/image%20%282%29.png) 81 | 82 | Imagine someone takes our see-saw, they carry the plank to Mars and they stand it up. That's what it's like. The computer does not understand the human language **at all**. 83 | 84 | If computers cannot understand the human language, why do we write human language? Why do we not write in machine language? How does the computer understand human language, the? 85 | 86 | 1.Why do we write human language, not machine language? 87 | 88 | Abstraction. Abstraction is where we take something complex, we remove some of the complexity and make it simpler. 89 | 90 | Abstraction is the backbone of every computer scientist in the world, and all machines. Abstraction is what causes exploits in machines, but it's also what causes better & more secure code to be written. 91 | 92 | The "Hello, World!" function in x86 assembly you saw is 12 lines. In Python, we can make it one line: 93 | 94 | ```python 95 | print("Hello, World!") 96 | ``` 97 | 98 | If we had to write 12 lines for every 1 line of Python, we'd never finish any software. 99 | 100 | Not to mention that it's far easier for us to introduce bugs in code if there are more lines then less. 101 | 102 | With Python, we know that other people smarter than us have read the `print` code and can confirm it cannot be exploited. 103 | 104 | With our hand-written Assembly, we cannot. 105 | 106 | In fact, we cannot even confirm that our assembly code is the most efficient method. In C++ we use something called zero cost abstractions for this. See my Rust room for more information `room code: rust`. 107 | 108 | 1. How does the computer understand human language? 109 | 110 | Bingo! This is where I was going with this. 111 | 112 | Let's say you're from the United Kingdom. And you visit China. Here's a typical conversation: 113 | 114 | > You: "Oi bruv givs a botla ov wotr" 115 | > 116 | > Shop Keeper: 你这个傻小子,我们这里不说这种语言 117 | 118 | Do you see the problem here? 119 | 120 | Now, how would you go about talking to the shop keeper? 121 | 122 | You'd use a translator. Either a person, or an app. 123 | 124 | How does our human-readable code talk to the computer? We use a translator called a _compiler_. 125 | 126 | The compiler converts our code into binary code for the computer to understand. And at the end, we get an executable file we can run. 127 | 128 | Translating is rather slow and expensive. We don't want to spend 5 minutes translating! 129 | 130 | This brings us onto.... 131 | 132 | -------------------------------------------------------------------------------- /what-is-python/variables.md: -------------------------------------------------------------------------------- 1 | # Variables 2 | 3 | Now in the last section, I said "String \(a string of characters\)". 4 | 5 | What does that mean? 6 | 7 | In programming we need to have data types. Every bit of data has a type in common with it. You already know some. 8 | 9 | If I said: 10 | 11 | ```python 12 | 1, 2, 3, 4, 5, 6, 7, 8, 9 13 | ``` 14 | 15 | "Are these sentences?" 16 | 17 | No! They're numbers. 18 | 19 | See, you already know data types 😜 20 | 21 | In Python, it's the same. We have some essential data types that hold things: 22 | 23 | * String \(a string of characters\) 24 | * Integer - a whole number \(-50, 50, 60, 91\) 25 | * Float - a floating point number \(21.3, -5.1921\) 26 | * List - a list of items \(\[1, 2, 3\], \["hi", 6, 7.91\]\) 27 | 28 | And more. 29 | 30 | Now, let's dis-spell a myth. 31 | 32 | Variables are like buckets in the sense that you can store things in them. Imagine a bucket and you want to put a sentence into it: 33 | 34 | ![](../.gitbook/assets/image%20%284%29.png) 35 | 36 | We make a bucket called hello and in the bucket we put in the string \`Hello, World!" 37 | 38 | ```python 39 | hello = "Hello, World!" 40 | ``` 41 | 42 | We use the equals sign as an _assignment operator_. It assigns the value on the right hand side to the bucket on the left. 43 | 44 | Now let's say we wanted to add this variable to another variable. A common misconception is that we take the bucket itself and use that. 45 | 46 | But in Python, we don't. We _pass by reference_. As in, we merely pass a location of the variable — we do not pass the variable itself. The alternative is _pass by value_. 47 | 48 | This is very important to understand, as it can cause a significant amount of headaches later on. 49 | 50 | ![Gif from here](../.gitbook/assets/yes.gif) 51 | 52 | Remember lists from earlier? 53 | 54 | ```python 55 | hellos = ["Hello", "yo", "sup?", "alright?"] 56 | ``` 57 | 58 | Lists have different methods which allow us to manipulate the list. A popular one is appending an item to a list, like this: 59 | 60 | ```python 61 | hellos = ["Hello", "yo", "sup?", "alright?"] 62 | hellos.append("TryHackMe") 63 | print(hellos) 64 | # ["Hello", "yo", "sup?", "alright?", "TryHackMe"] 65 | ``` 66 | 67 | Let's see this bug in action. 68 | 69 | ```python 70 | list1 = [1, 2] 71 | list2 = [3, 4] 72 | list1.append(list2) 73 | # List1 is now [1, 2, [3, 4]] 74 | # We appended the list, not the contents of the list 75 | ``` 76 | 77 | When we append a list to another list, we do not merge the elements together. Instead we append the entire list \(including the list itself\) to the other list. 78 | 79 | ```python 80 | # Continueing from last code block 81 | list2.append(6) 82 | print(list1) 83 | # [1, 2, [3, 4, 6]] 84 | ``` 85 | 86 | Now, let's look at the bug in more detail: 87 | 88 | ```python 89 | list1 = [1, 2] 90 | list2 = [3, 4] 91 | list1.append(list2) 92 | list2.append(6) 93 | print(list1) 94 | # [1, 2, [3, 4, 6]] 95 | ``` 96 | 97 | When we appended `list2` to `list1`, we did not actually append the list. We appended the reference to the list. 98 | 99 | When we changed `list2`, because `list1` had the reference appended it "updates" itself to match the newly updated `list2`. 100 | 101 | In Python, this type of bug can happen all the time. We never pass the values of things, always the references. So be sure to keep an eye open for this type of thing. 102 | 103 | In some languages like Rust you get the option of value or reference. But in Python, you only get the option of reference. This is because if we started passing values, Python would have to spend more time on their garbage collection system. 104 | 105 | Garbage collection is where we store variables in the system and remove them when they are no longer needed. Higher level languages do this automatically. Lower level languages you might have to do it yourself. 106 | 107 | There are a whole bunch of other data types in Python, but I'll explain most of them throuhout this room. 108 | 109 | Here's a quick table for data structures in Python: 110 | 111 | | String | A string of characters | `"Hello"` | `str(x)` | 112 | | :--- | :--- | :--- | :--- | 113 | | Boolean | True or False value | `True`, `False` | `bool(x)` | 114 | | Integer | A whole number | `50` | `int(x)` | 115 | | Float | A floating point number | `6.11` | `float(x)` | 116 | | List | A list of items | `[1, 2, 3]` | `list(x)` | 117 | | Dictionary | A key:value pairing. Talked about later. | `{1: "One"}` | `dict(x)` | 118 | 119 | ## How do lists work, really? 120 | 121 | Lists are quite strange because they have no set length. Python is written in C, and in C arrays \(lists\) have set lengths -- so how come Python lists do not have lengths? 122 | 123 | That's because they do, but they are abstracted in such a way that you don't need to worry about it. 124 | 125 | Let's look at a naieve approach for arrays. 126 | 127 | ```text 128 | [1, 2, 3, None, None, None] 129 | ``` 130 | 131 | Imagine this is an array of length 6, where None represents empty space. We fill up the array with data: 132 | 133 | ```text 134 | [1, 2, 3, 4, 5, 6] 135 | ``` 136 | 137 | Now we want to append one more item to the array, `7`. The array is fixed length, so we cannot append to it with this size. 138 | 139 | Our naieve approach is to increase the array by size 1. 140 | 141 | ```text 142 | [1, 2, 3, 4, 5, 6, None] 143 | ``` 144 | 145 | And then append the value to it: 146 | 147 | ```text 148 | [1, 2, 3, 4, 5, 6, 7] 149 | ``` 150 | 151 | But everytime we want to append a value we have to create a whole new array, copy all the previous values in and insert our new value. 152 | 153 | This is obviously a slow algorithm. 154 | 155 | Python uses an algorithm called **table doubling** to battle this slowness. I bet you can guess what it does! 156 | 157 | When we reach the limit of an array and we want to increase the size, we create a new array double the size of the previous array. 158 | 159 | This saves us time from creating a new array with every append, while also keeping the size to a minimum. It's problematic to create an array that's only 1 element larger than our last array. 160 | 161 | It's problematic to create an array that is the maximum possible size \(as it costs memory\). 162 | 163 | Table doubling is the perfect balance between them both. 164 | 165 | ### Removing Elements 166 | 167 | Let's say we have a table of size 6. 168 | 169 | We add one element. 170 | 171 | Our table size doubles to 12. 172 | 173 | We remove one element. 174 | 175 | To save space, we delete the 6 extra array elements. 176 | 177 | We then add another element, and double the table again. 178 | 179 | It is costly to double the table in this instance, where we rapidly remove one element and add another element. Instead what we do is only reduce the table when we go below 3 times the doubled size. 180 | 181 | With our above example, we double to 12. We remove 1 item so we have 5 items. We do not reduce the size of the array. Only if we hit 4 elements \(12 / 3 = 4, 3 times smaller\) do we reduce the size. 182 | 183 | This fixes our above problem. 184 | 185 | Something to note is that I'm not sure whether Python uses 3, or 4, or 5 to decide when to shrink a table. It's unimportant so long as it's >2. 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /.gitbook/assets/undraw_code_review_l1q9.svg: -------------------------------------------------------------------------------- 1 | code review --------------------------------------------------------------------------------