{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Python for C programmers\n", "=============\n", "\n", "The basics of Python are fairly simple to learn, if you already know how another structured language (like C) works. So we will walk through these basics here. This is only intended to be a quick overview, not a deep dive into how Python works. We will spend more time talking about certain topics (such as higher order functions) in later lectures, but for more details about the \"basics,\" please talk to the instructors or the TA, or take a look at the [Python reference pages](https://docs.python.org/2/reference/index.html)\n", "\n", "One big difference between C and Python is that C is _compiled_ while Python is _interpreted_. This means that to run a C program, you first have to compile it (e.g., with `gcc`) and _then_ run it; but once you compile the program, you have a standalone executable (e.g., `a.out`). With a Python program, you do not have to compile the program but to _run_ the program you need to run it in the Python interpreter (e.g., `> python hw0.py`)\n", "\n", "In practice, at least for this class, this distinction will not really matter (it can matter more once you get to long-running programs that operate over large amounts of data)\n", "\n", "Variables and Types\n", "-----\n", "\n", "Perhaps the biggest difference between C and Python is that C variables are _statically typed_ -- you need to say whether a variable `x` is an `int` or a `float` right up front. In Python, you don't:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1\n", "type(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that this means that we don't need to \"declare\" variables -- we can just use them whenever we need to.\n", "\n", "What's interesting about Python, though, is that while we say the type of `x` is an `int`, what's really happening is that `x` is a reference to an _integer object_, which happes to have the value 1. `x` itself doesn't have a fixed type. We can re-assign it:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1.2\n", "type(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can even make `x` a string:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = \"hello\"\n", "type(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python does its type checking _dynamically_. It will not tell you until you try to do something with a variable whether the operation is legal or not:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "len(x) #this will work because x is a string" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1.2\n", "len(x) #what will happen here?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Python will also perform _type coercion_: when it makes sense, it will convert an object from one type to another to let an operation work:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "p = 1\n", "print (type(p)) #the parentheses around the argument to print are optional\n", "\n", "q = .2\n", "print (type(q))\n", "\n", "r = p + q\n", "print (type(r))\n", "print (\"value of r: {}\".format(r)) #compare this to printf!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Control statements\n", "------------\n", "\n", "Control statements in Python look a lot like their counterparts in C: `if` statements, `while` loops, `for` loops. The _biggest_ difference is that in Python _whitespace matters_. We do not use `{` and `}` to separate blocks. Instead, we use colons (`:`) to mark the beginning of a block and indentation to mark what is in the block. \n", "\n", "**If Statements**\n", "\n", "Here is the equivalent of the C statement:\n", "\n", "`if (r < 3) printf(\"x\\n\"); else printf(\"y\\n\");`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if r < 3:\n", " print (\"x\")\n", "else:\n", " print (\"y\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And an example of multiline blocks:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "if r < 1:\n", " print (\"x\")\n", " print (\"less than 1\")\n", "elif r < 2:\n", " print (\"y\")\n", " print (\"less than 2\")\n", "elif r < 3:\n", " print (\"z\")\n", " print (\"less than 3\")\n", "else:\n", " print (\"w\")\n", " print (\"otherwise!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**While Loops**\n", "\n", "`while` loops are similar:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1\n", "y = 1\n", "while (x <= 10) :\n", " y *= x\n", " x += 1\n", "\n", "print (y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 1\n", "y = 1\n", "while (x <= 10) :\n", " if x % 2 == 0 :\n", " y *= x\n", " x += 1\n", "\n", "print (y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**For Loops**\n", "\n", "`for` loops are a little trickier. They do _not_ take the same form as C for loops. Instead, for loops iterate over collections in Python (e.g., lists). These are more like `foreach` loops that you might see in other languages (or the `for (x : list)` construct you see in Java). So let's start by talking about lists:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = [1, 4, 9, 0, 4, 2, 6, 1, 2, 8, 4, 5, 0, 7]\n", "print (data)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "hist = 5 * [0]\n", "print (hist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lists work like a combination of arrays in C (you can access them using `[]`) and lists (you can append elements, remove elements, etc.)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "length = len(data)\n", "print (\"data length: {} data[{}] = {}\".format(length, length - 1, data[length - 1]))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data.append(8)\n", "length = len(data)\n", "print (\"data length: {} data[{}] = {}\".format(length, length - 1, data[length - 1]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can then _iterate_ over the elements of the list:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for d in data :\n", " print (d)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for d in data :\n", " hist[d // 2] += 1\n", "print (hist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "How do you write a `for` loop with an index variable that counts from 0 to 4, like you might in C?\n", "`for (int i = 0; i < 5; i++)`\n", "\n", "Use the standard function `range`, which lets you count from a lower bound to an upper bound (with an optional step):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "r = range(0,5)\n", "print (r)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for i in range(0, 5):\n", " print (i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Functions\n", "---------\n", "\n", "Basic functions in Python work a lot like functions in C. The key differences are:\n", "1. You don't have to specify a return type. In fact, you can return more than one thing!\n", "2. You don't have to specify the types of the arguments\n", "3. When calling functions, you can name the arguments (and thus change the order of the call)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def foo(x) :\n", " return x * 2\n", "\n", "print (foo(10))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def foo2(x) :\n", " return x * 2, x * 4\n", "\n", "(a, b) = foo2(10)\n", "print (a, b)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def foo3(x, y) :\n", " return 2 * x + y\n", "\n", "print (foo3(7, 10))\n", "print (foo3(y = 10, x = 7))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are more complicated things you can do with functions -- nested functions, functions as arguments, functions as return values, etc. We will look at these in the lecture when we talk about Map and Reduce" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.2" } }, "nbformat": 4, "nbformat_minor": 2 }