{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Python essentials to get you started\n", "\n", "This notebook is designed to familiarize you with some basic programming constructs before the start of actual instruction. If you've coded before, this will show you how stuff you already know are implemented in the Python programming language. If you've never coded before, you'll probably be a bit confused. Don't worry! The class hasn't started yet!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variable types and assignments" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variables are the building blocks of programs. You tell a compute what to do largely by maniulating the values of variables. Variables come in different types such as `string`, `integer`, `boolean`, and `float`. Because Python is what's called a dynamically typed language, you don't have to declare the type of variable before assigning a value to it. For example, let's look at these 6 (very badly named) variables." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "var_1 = \"five\"\n", "var_2 = 5\n", "var_3 = \"5\"\n", "var_4 = 5.0\n", "var_5 = True\n", "var_6 = \"True\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's print them out" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "var_1 = five\n", "var_2 = 5\n", "var_3 = 5\n", "var_4 = 5.0\n", "var_5 = True\n", "var_6 = True\n" ] } ], "source": [ "print('var_1 = ',var_1)\n", "print('var_2 = ',var_2)\n", "print('var_3 = ',var_3)\n", "print('var_4 = ',var_4)\n", "print('var_5 = ',var_5)\n", "print('var_6 = ',var_6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's print out the **types** of variables these are:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "var_1 = \n", "var_2 = \n", "var_3 = \n", "var_4 = \n", "var_5 = \n", "var_6 = \n" ] } ], "source": [ "print('var_1 = ',type(var_1))\n", "print('var_2 = ',type(var_2))\n", "print('var_3 = ',type(var_3))\n", "print('var_4 = ',type(var_4))\n", "print('var_5 = ',type(var_5))\n", "print('var_6 = ',type(var_6))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that `var_2` and `var_3` have exactly the same printed value (5). `var_5` and `var_6` also have the same value (True). In both cases, however, they are of different types, e.g., `var_2` is an integer while `var_3` is a string; `var_5` is a boolean while `var_6` is a string.\n", "\n", "Does this matter? Yes it does! Have a look at what happens when we try to add 3 to `var_2` vs. `var_3`" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Adding 3 to var_2 gets us 8\n" ] }, { "ename": "TypeError", "evalue": "can only concatenate str (not \"int\") to str", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m/Users/glupyan/gitRepos/psych750.github.io/notebooks/python_basics.ipynb Cell 10\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39mAdding 3 to var_2 gets us \u001b[39m\u001b[39m\"\u001b[39m, var_2\u001b[39m+\u001b[39m\u001b[39m3\u001b[39m)\n\u001b[0;32m----> 2\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39mAdding 3 to var_3 gets us \u001b[39m\u001b[39m\"\u001b[39m, var_3\u001b[39m+\u001b[39;49m\u001b[39m3\u001b[39;49m)\n", "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" ] } ], "source": [ "print(\"Adding 3 to var_2 gets us \", var_2+3)\n", "print(\"Adding 3 to var_3 gets us \", var_3+3)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first one is 8 because. 5+3=8. \n", "\n", "The second one throws a TypeError because you tried to combine two types (a string and an integer) in a way that could not be resolved. The string '5' + the integer 3 is not defined. Computers are literal-minded. Just because something looks like the number 5 doesn't make it a five! \n", "\n", "```{note}\n", "You will be seeing a lot of error messages like the one above. Don't let them intimidate you. Generally, the very last line will tell you what kind of error it is (in this case, a TypeError meaning that something went wrong when combining different variable types). The text above tells you where in your code the error is coming from.\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now have a look at this. Try to predict what happens before looking at the output" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "53\n" ] } ], "source": [ "print(var_3+'3')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What happened here?! The Python interpreter was asked to add the string '3' to the string '5'. A human is cognizant that these are numbers, but the Python interpreter doesn't care. To it, these are just text strings. What's a reasonable thing to do when asked to add two strings? Python defines string addition as **concatenation**, i.e.,`string1a+string2=string1string2`. That's why we get `52` (which is itself a string!!) as the answer.\n", "\n", "So, in the context of numbers (integers and floats) `+` is arithmetic addition. In the context of strings, it's concatenation. This is called [operator overloading](https://www.geeksforgeeks.org/operator-overloading-in-python/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's try this one. Let's *multiply* `var_2` and `var_3` by 3. What do you think will happen?" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "15\n", "555\n" ] } ], "source": [ "print(var_2*3)\n", "print(var_3*3)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## A bit more about printing" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Although printing is not something we'll be doing much of as an end in itself, it's massively useful for debugging your code, i.e., for knowing what a value of vertain variables is at a certain point in your code. We'll talk more about this when we discuss debugging. \n", "\n", "When you print, Python will try to convert what you are printing to a string. But if you try to print several different data types or combine the printing of strings and variables -- both of which is something you'll be doing a lot of when debugging -- it gets cumbersome. Observe:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Simple enough:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "name = \"George's dog\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But what about this?" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "George's dog\n" ] } ], "source": [ "name = \"George\"\n", "print(name+\"'s \"+\"dog\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Yuck... that's a lot of quotes and figuring out where the spaces should go. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python 3 provides a bit of \"syntactic sugar\" for printing combinations of raw strings and variables of different types:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "George's dog\n" ] } ], "source": [ "name = \"George\"\n", "print(f\"{name}'s dog\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To use so-called f strings (f stands for formatted) just encase the variables in curly-braces and write out the regular text part of the string as normal. Read more about these f-strings [here](https://realpython.com/python-f-strings/)" ] }, { "cell_type": "markdown", "metadata": { "hide_input": false }, "source": [ "## Lists and `for` loops " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A data structure you'll be using a whole lot in Python is a [list](https://learnpython.com/blog/python-array-vs-list/). For those coming from other programming languages, lists are largely the same as arrays, although Python lists can mix different types of variables. For example:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, '1', 'two', 'three', 4]\n", "1 is a \n" ] } ], "source": [ "a_list = [1, '1', 'two', 'three', 4]\n", "print(a_list)\n", "print(a_list[0], 'is a', type(a_list[0]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A common way of iterating through lists is by using a `for` loop. " ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "dog\n", "cat\n", "pig\n" ] } ], "source": [ "animals = ['dog', 'cat', 'pig']\n", "for animal in animals:\n", " print(animal)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A common use of `for` loops is to do something a certain number of times. For example, let's print the first 10 integers, beginning from 0:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n" ] } ], "source": [ "for cur_num in range(10):\n", " print(cur_num)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{dropdown} What happened here?\n", "`range()` generated a list of numbers in the specified range, beginning from 0. Then `for` iterates through those numbers, printing the value of each.\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You don't have to start at 0. Pass a starting number to `range()` like so." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n", "6\n", "7\n", "8\n", "9\n" ] } ], "source": [ "for cur_num in range (5,10):\n", " print(cur_num)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "Technically range() returns a `range object` which is a [\"lazy iterable\"](https://treyhunner.com/2018/02/python-range-is-not-an-iterator/) and is executed only later, when we try to access its values. This is different from Python 2 where `range()` returns a regular list.\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What about counting by 2s or counting down? Simple" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "2\n", "4\n", "6\n", "8\n" ] } ], "source": [ "for cur_num in range(0,10,2):\n", " print(cur_num)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n", "9\n", "8\n", "7\n", "6\n", "5\n", "4\n", "3\n", "2\n", "1\n" ] } ], "source": [ "for cur_num in range(10,0,-1):\n", " print(cur_num)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ":::{tip}\n", "If all you need to do is to execute some command a certain number of times, there's a Python convention to use `_` as a throwaway index variable, for example, let's generate 5 random integers between 1-10:\n", "```python\n", "import random\n", "for _ in range(25):\n", " print(random.randrange(1,10+1))\n", "```\n", ":::" ] }, { "cell_type": "markdown", "metadata": { "scrolled": false, "tags": [ "hide-output" ] }, "source": [ "## A `while` loop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another kind of loop we'll use is a `while` loop. We use this to iterate until a condition is met (i.e., something that's `false` becomes `true`), or a condition is no longer met (i.e., something that's `true` becomes `false`)." ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I'm a 5 and I'm less than or equal to 5!\n", "I'm a 4 and I'm less than or equal to 5!\n", "I'm a 3 and I'm less than or equal to 5!\n", "I'm a 2 and I'm less than or equal to 5!\n", "I'm a 1 and I'm less than or equal to 5!\n" ] } ], "source": [ "another_num=5\n", "while another_num>0:\n", " print(f\"I'm a {another_num} and I'm greater than 0!\")\n", " another_num -= 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{dropdown} What happened here?\n", "The first line of the while loop evaluates the truth value of another_num being greater than 0. As long as both of these conditions are met, we execute the loop. On each iteration, we decrease the value of another_num by 1 until it's no longer greater than 0 at which point the while loop exits.\n", "```" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "z\n", "zz\n", "zzz\n", "zzzz\n", "zzzzz\n", "zzzzzz\n", "zzzzzzz\n", "zzzzzzzz\n", "zzzzzzzzz\n", "zzzzzzzzzz\n" ] } ], "source": [ "s = \"\"\n", "while len(s)<10: \n", " s+=\"z\"\n", " print(s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "`+=` is shorthand for add and self-assign, i.e., \n", "s+=\"z\" is equivalent to s = s+\"z\"\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Primer on conditionals (`if` statements)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "it's a 5!\n" ] } ], "source": [ "my_num = 5\n", "\n", "if my_num == 5:\n", " print(\"it's a 5!\")\n", "else:\n", " print(\"it's not a 5!\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "if 5<2:\n", " print('yes indeed')\n", "elif 10<2:\n", " print('this is true too!')" ] }, { "cell_type": "markdown", "metadata": { "scrolled": false, "tags": [ "hide-output" ] }, "source": [ "Predict what each of these statements will return. Then check." ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "it's not a 5!\n" ] } ], "source": [ "my_num = '5'\n", "if my_num == 5:\n", " print(\"it's a 5!\")\n", "else:\n", " print(\"it's not a 5!\")" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print('s'==True)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(1==True)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print (0==True)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print (True==False)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print ((True or False)==True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's end with a weird one..." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "uh oh\n" ] } ], "source": [ "if print==True or print==False:\n", " print('all is good')\n", "else:\n", " print('uh oh')" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "tags": [ "hide-output" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "False\n", "False\n" ] } ], "source": [ "print(type(print))\n", "print(print==True)\n", "print(print==False)" ] } ], "metadata": { "celltoolbar": "Edit Metadata", "kernelspec": { "display_name": "Python 3.8.13 ('psych750')", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.13" }, "vscode": { "interpreter": { "hash": "57beecaf6908bae4f97de5e2dc8e8d0311fae5bc989593c172c307d13e31f6e4" } } }, "nbformat": 4, "nbformat_minor": 2 }