{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Programming basics\n", "\n", "## Objectives:\n", "\n", "* Learn the 5 components of the Python Syntax\n", "* Understand Python's object system\n", "* Learn to interact with the IPython prompt in the Jupyter notebook" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Jupyter, IPython, Python, oh my!\n", "\n", "Just to keep the computational model straight, we are using:\n", "\n", "* Python 3.6, a interpreted programming language\n", "* A REPL, which **R**eads a line, **E**valuates it, then **P**rints it (in a **L**oop)\n", " - `print` not needed to see the last un-captured value in a cell\n", "* IPython, which is an enhancement to make Python more **I**nteractive\n", " - You can't use these enhancements in a library, but they generally are only useful interactivally anyway\n", "* Jupyter notebooks, which is a web based display of a Kernel, such as IPython (or many other language kernels)." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "```\n", "Jupyter notebook -> IPython -> Python\n", "----------------- ------------------ ------------------\n", "This is what you Checks for special Does the real work\n", "see syntax, then sends\n", " it on\n", "```\n", "\n", "> Note: The very new JupyterLab takes this one step further, by providing an nice environment for notebooks, which themselves are an environment for IPython... It's really nice and beautiful, though." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Basics of programming\n", "\n", "Computing can be broken down to two things:\n", "\n", "* Variables: These hold data\n", "* Functions: These are procedures (usually operating on variables)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This is a variable\n", "variable = 3\n", "\n", "# This is a function\n", "def function(x):\n", " return pow(x, 2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "function(variable)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Don't worry about the details of the Python syntax quite yet, just focus on the two concepts: *data* and *procedures*. And, yes, `x**2` is nicer than `pow(x,2)`." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Try it yourself\n", "\n", "The *great* thing about programming in an interpreted language like Python is that *you can try everything* yourself, in real time. Play around with the above variables and answer these questions:\n", "\n", "* Can you name a variable `def`? Why or why not?\n", "* Can you name a variable `pow`? Why or why not?\n", "* Why might you not want to make a variable named `pow`?\n", "* How can you get rid of your variable named `pow`? (Hint: Try `del` or restarting your kernel (top menu))." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Python's syntax\n", "* **Operators**: special symbols or words that have a specific meaning. You can usually control what they do in classes. Some general parts of the syntax, like whitespace, commas, colons, and brackets, are not called operators.\n", "* **Keywords**: special words that have language level meaning and cannot be used elsewhere or changed.\n", "* **Builtins**: functions and objects that are pre-defined, but not special.\n", "* **Numbers**: several different number types available\n", "* **Strings**: add text to the program or help\n", "* **Comments**: start with a `#` and are ignored by Python\n", "\n", "> Note: Builtins can't be undefined due to the way the Python lookup system works." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# Does not take anything or return anything\n", "def funct():\n", " \"This is the function documentation\"\n", " print(\"Called f\", 1 * 1, \"time\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Operators**, **Keywords**, **Builtins**, **Numbers**, **Strings**, **Comments**\n", "\n", "#### Answer this:\n", "\n", "* What color is each of these in your notebook?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Objects and Types/Classes\n", "\n", "We can go one step further from variables and functions: objects and classes.\n", "\n", "* Object: A related collection of data and functions for that data\n", " * Members: Variables that hold the data for the object\n", " * Methods: Functions that operate on the object data\n", "* Class: The \"type\" of an object; objects that have the same methods/members have the same class" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Why are objects so important in Python? Because unlike many other languages, *everything* in Python is an object! This is **very powerful**.\n", "\n", "---\n", "> Note: Syntax such as keywords are not objects. (though builtins are)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "number = 1.5\n", "string = \"hello world\"\n", "complex_number = 2 + 3j" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Try running some of the methods and look at the members of the objects defined above.\n", "\n", "IPython + Jupyter keyboard hints:\n", "\n", "* Use **Tab** to see completions, either when typing a word or after a `.`\n", "* Use **Shift-Tab** to see the help for a function after typing it\n", "* Use **Shift-Enter** to execute a cell" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "We can use `type` to see the class of an object:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "type(number)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Names\n", "\n", "There are certain conventions for the names of objects and classes:\n", "\n", "| Case | Convention | Example |\n", "|---|---|---|\n", "| Objects and methods | start with lower case letter | `like_this` |\n", "| Classes | Start with upper case letter | `LikeThis` |\n", "| Globals | all uppercase | `LIKE_THIS` |\n", "| Hidden | start with underscore | `_like_this` |\n", "| In one class only| start with two underscores (rarely used) | `__like_this` |\n", "| Special python names | start and end with two underscores | `__like_this__` |\n", "\n", "Exceptions for some Python built-in types, which are all lowercase. And `True`, `False`, `None`, and `Ellipsis`, which are objects but are capitalized." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Built in Python Types\n", "\n", "The following are a mostly comprehensive list of built-in Python types" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Basic types" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "py_int = 101\n", "py_float = 3.7\n", "py_complex = 1j\n", "py_str = \"Unicode string: Python 3 is 😀\"\n", "py_bytes = b\"Binary string\"\n", "py_bool = True\n", "py_none = None" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "These types are all also constructible by calling the name of the type, such as `int(1)`. A few interesting notes:\n", "\n", "* Numbers can be constructed from strings too, like `int(\"1\")`\n", "* Strings can start with special characters, like `b`. We'll see this again someday.\n", "* Strings use `\"` or `'`. Three quotes can be used to include new lines.\n", "* `None` is the only none type. How lonely." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Try it yourself:\n", "\n", "* How large is the largest int value allowed?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Compond types\n", "\n", "These are composed, but are also very important" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "py_tuple = (1, 2, 3)\n", "py_list = [1, 2, 3]\n", "\n", "py_dict = {\"Python 3\": \"😍\", \"Python 2\": \"😖\"}\n", "\n", "py_set = {\"no\", \"duplicates\", \"in\", \"here\"}" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Accessing values is done with brackets:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(py_tuple[0])\n", "print(py_dict[\"Python 3\"])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* Indexing starts from 0, [as it should](http://developeronline.blogspot.com/2008/04/why-array-index-should-start-from-0.html)\n", "* A tuple is just like a list, but can't be changed: immutable\n", "\n", "| Mutable | Immutable |\n", "| --------|-----------|\n", "| Can be changed | Can only be replaced |\n", "| Can be a key or in a set | Can't be a key or in a set |\n", "| `list`, `dict`, `set` | `tuple`, `str`, `int`, etc. |\n", "\n", "* A set does not have an order (so you can't use `[]` to get items from it)\n", "* Dictionaries are ordered before Python 3.6 (even now you still only have direct access to keys)\n", "\n", "There are other types in the standard library, but we'll restrict ourselves to talking about these for now.\n", "\n", "> If you could put a mutable item in as a key or set item, you could then change it later and have two identical key items or set items!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Try it out: Mutation vs. replacement\n", "\n", "Can you guess what the final value of `a` is? What about `b`?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = [1, 2, 3, 4]\n", "b = a\n", "b[2] = \"😡\"\n", "b = [3, 2, 1, 3]\n", "b[2] = None\n", "\n", "print(a, b)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Key points to understanding this example:\n", "\n", "* Normal assignment *replaces* the variable on the left\n", "* Python never copies, but with immutable values and the above statement, it might seem that way\n", "\n", "There are a limited number of expressions allowed on the left (but they can be chained):\n", "* An object (replaces): `a = `\n", "* An index into an object (mutate) `a[x] = `\n", "* An object attribute (mutate): `a.x = `" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Slicing\n", "\n", "One of the most important things in computation is indexing, and Python is really good at it. You've already seen integers being used to index lists (strings work the same way too), but let's peek at another way to index lists and tuples: slicing." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "a = \"abcdefg\"\n", "print(a)\n", "print(a[0:7:1]) # start : stop (not included) : step\n", "print(a[0:7]) # step not needed\n", "print(a[1:]) # you can leave out values\n", "print(a[:-1]) # like indexing, - means from end\n", "print(a[::2])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Operators\n", "\n", "Python's operators are pretty standard. Here are the ones that tend to be a little odd:\n", "\n", "* `x**y`: Raise `x` to a power `y`\n", "* `x == y`: See if `x` is equal to `y`\n", "* `x is y`: See if `x` is the same object (in the same spot in memory) as `y`, can't be overriden\n", "* `~x`: Invert `x` (might be different than unary `-`)\n", "* `+x`: Python does have a unary `+` operator, too. Not sure why you'd want it.\n", "* `x += y`: Add y to x, in place only if mutable" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "* `x / y`: True mathematical division (Py3 default, Py2 option)\n", "* `x // y`: Truncating division\n", "* `x @ y`: Matrix product of x and y (Python 3.5+, only in libraries)\n", "* `x and y`: Boolean operator, short-circuits and can't be overriden (`or` and `not` too)\n", "* `x & y`: Bitwise and - this one can be overriden, but has odd precedence\n", "* `x | y`: Bitwise or" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Control\n", "\n", "We've already seen functions. What other control statements are out there for use to use?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = True\n", "if x:\n", " print(\"x was true\")\n", "else:\n", " print(\"x was not true\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "The for each loop works on any *iterable*:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = \"abcdefg\"\n", "for item in a:\n", " print(item, sep=\", \")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also use `for item in range(N)` to count over a range of values, or `while CONDITION:`.\n", "\n", "You can use `for` (and `if`) inside `[]`, `()`, or `{}` to build the data structures mentioned above inplace." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bad_way_to_make_a_set_of_tens = {x for x in range(100) if x % 10 == 0}\n", "bad_way_to_make_a_set_of_tens" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### With\n", "\n", "There are other useful things in Python we will cover later, but the `with` statement is too good to wait. With lets you take code like this:\n", "\n", "```python\n", "f = open(filename)\n", "txt = f.read()\n", "f.close() # Don't forget me!\n", "```\n", "\n", "and write instead:\n", "\n", "```python\n", "with open(filename) as f:\n", " txt = f.read()\n", "# File automatically closed here!\n", "```\n", "\n", "With simply runs code at the start and at the end of a block. It also promises the code at the end runs, even if there's an error! (More about errors later)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Isn't all of this restrictive?\n", "\n", "You may have noticed that each new concept in programming *restricts* rather than *enables*. If we went further into topics like functional program, this would continue to be the case. This is odd but true: we could write any program with a very small set of constructs. However, the most important feature of programming is *organization* (also called design)." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Compare this hypothetical pseudo-code:\n", "\n", "```python\n", "i = 0\n", "label start\n", "compute(i)\n", "i = i + 1\n", "if i < 10: goto start\n", "```\n", "\n", "Verses real code:\n", "\n", "```python\n", "for i in range(10):\n", " compute(i)\n", "```" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Now imagine a complex program with 1,000 of `goto` statements; you would have to work through every line of code to understand it. But if you restrict yourself to common structures, like loops, objects, functions, etc., you no longer have to look at the whole program, but just parts you recognize." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Design in programming\n", "\n", "You should:\n", "\n", "* Make small, understandable pieces *that can be run by themselves* (Easier to de**bug** and test)\n", "* Write similar code once (fewer places for **bugs**)\n", "* Reuse existing functions or libraries when possible (let someone else design and de**bug** what they are good at)\n", "\n", "Objects are very good for the second two points (and so-so for the first).\n", "\n", "Also notice the running theme above?" ] } ], "metadata": { "kernelspec": { "display_name": "compclass", "language": "python", "name": "compclass" }, "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.2" } }, "nbformat": 4, "nbformat_minor": 4 }