.. _simple-python-scripts: Simple Python Scripts ##################### .. wordcount:: .. seealso:: Text Chapter 2 .. note:: Why do we call the files we write for Python "scripts" instead of programs? Well, there is no real (good) reason, except traditionally, scripts are run by interpreters and are not compiled into fast running programs. Python does not ask you to do a separate compile step, and Python is used in a lot of places where other "scripting" languages are used, so the name tends to be used a lot. Do not worry about this, we are writing real programs, even if I slip and call them scripts. (Plus, I do teach a course called ``Introduction to scripting languages: Python``, so there!) OK, I know you are itching to try out writing a real Python program, and we will do that in this lecture. The goal here is to show you how to put a program together and run it from the command line. To work through this lecture, you will need to use a programmer's text editor, line ``gVim`` on the lab machines. .. note:: The text shows many examples that are run from the Python program itself. Any time you see a line beginning with three right-angle brackets, that is the interpreter prompt. We are going to build a program in a file, which is what you normally do as a programmer. Python does make it easy to experiment with code chunks, and I encourage you to do that! We are not really learning all the statements in Python in this exercise, we are just getting a taste of the language and how it works. We will go back and fill in details later. Open up a command prompt ************************ We begin by opening up a :term:`command prompt` window so we can run our program. .. image:: images/command-prompt.jpg :align: center .. note:: In this lecture, I am assuming you are working on a lab machine. If you are working on your personal machine, adjust the directory so you end up working in a place you set up for this class. Eventually, you will need to upload files to your GitHub account for grading. If you have any problems doing this, see me right away! Change into a directory you set up for this exercise. We will call it ``lab3``: .. code-block:: text H: cd COSC1336 mkdir lab3 cd lab3 Once these commands have been entered, you are working in the directory called ``lab3`` on your "H" drive. We will build our program here. Open up the editor ****************** Next, open up ``gVim`` by finding it in the list of programs on your system. I recommend placing a shortcut to this program, or pin the icon to the taskbar when you start up the program. You can get to this editor using :menuselection:`Start --> All programs --> vim8.0 --> gvim.exe`` Create your first script ************************ Once the editor is open, look at the cursor closely. It should show as a black block that highlights a single character on the screen. In this "mode" ``gVim`` is in ``command mode`` and what you type is a command to the editor, not something that goes into your file. To get into ``edit mode`` (or ``insert mode``) type a lower-case "i" (no quotes). The cursor should change to a vertical line in front of the place the next character you type will go. You are shown that you can ``insert`` text by the ``Insert`` message at the bottom of the screen. Once you are in this mode, you can use the arrow keys to move around in your text. .. warning:: Hopefully, you went through the ``gVim`` setup instructions so you have tabs expanded and tab stops set to 4. If not, go back and check :ref:`installing-vim`. Once you are in ``insert mode``, type this into the editor. (This will look familiar): .. code-block:: python print("My name is: first last") Obviously, you should use your name in this example. Now, hit the ``esc`` key. This takes you out of `insert mode`` and returns you to ``command mode``. Use the menu at the top of the editor to save this code in a file called ``firstprogram.py`` in your ``lab3`` directory. Use :menuselection:`File --> Save As`` then browse to the right place and enter the file name. You want this code to end up in the ``lab3`` directory. Running your program ******************** Go back to the ``command prompt`` window you opened earlier. Make sure you see your new file by doing this: .. code-block:: text H:\COSC1336\lab3> dir ... 09/12/2012 12:50 PM 35 firstprogram.py Now, from the command prompt, type this: .. code-block:: text python firstprogram.py You should see your message. Add code to your program ************************ Now that you see how to run a Python program, let's add some new code to this file. Switch back to the editor window (you should not have closed it) and add this code. You can use the cursor arrow keys to move around in the text of the program until you have it where you want to add new code. (It will not let you move into any area where no text exists. Once you are where you want to be, press lower-case "i" again and you are ready to add new text. Make your program look like this: .. code-block:: python print("My name is: first last") from math import sqrt x = 5 sqrt_x = sqrt(x) print("The square root of",x, "is",sqrt_x) Now, run this program and make sure it works. You should see something like this: .. code-block:: text My name is Roie Black The square root of 5 is 2.23606797749979 Do you see how the output is formatted. Notice that there is a space between the text in quotes (called strings) and the numbers displayed. Python adds a space when it sees a comma in the sequence of things you ask it to print. What is all this stuff? *********************** In this new code, we added a few basic things. First, we set up simple ``variables`` which are just names we want to use for places in the system we want to store data. Python figures out what kind of data by looking at what you typed in. In this case, we created a ``variable`` with the name of "x" (case matters, by the way) and gave it value of "5". In the next line we created another variable called "sqrt_x" and gave it a value as well. But that value was figured out by activating a chunk of code you did not write. Instead, that chunk of code is part of the standard things installed with Python. It is called a ``library`` of routines we will find handy. The line with the "import" word on it tells Python that we intend to use a chunk of code with the name ``sqrt`` later in our program. If you forget to include this line, Python will complain. Dealing with errors ******************* Now is a good time to see what happens if we mess all this up! Commenting out lines of code ============================ In Python, a comment is ignored by the Python Interpreter as it reads your program. We will use comments a lot as we get better at writing code. Comments start with a sharp character (``#``) and extend to the end of the line. To make Python ignore the ``import`` line, insert a sharp at the beginning of that line and run your program again. .. code-block:: text python firstprogram.py My name is Roie Black Traceback (most recent call last): File "firstprogram.py", line 6, in sqrt_x = sqrt(x) NameError: name 'sqrt' is not defined Any time you see messages like this, you have a problem you need to fix before you go on. Let's try another common error. Let's mistype something. Remove the sharp we just added and change the code that calls the sqrt code so it looks like this: .. code-block:: python sqrt_x = Sqrt(x) Wow, this is just a single character that is wrong. Wonder if Python will object! .. code-block:: text python firstprogram.py My name is Roie Black Traceback (most recent call last): File "firstprogram.py", line 6, in sqrt_x = Sqrt(x) NameError: name 'Sqrt' is not defined Guess so!. Let's try one more: .. code-block:: python sqrt_x sqrt(x) Seems we forgot an equal sign. .. code-block:: text python3 firstprogram.py File "firstprogram.py", line 6 sqrt_x Sqrt(x) ^ SyntaxError: invalid syntax Here Python knows a symbol (the equal sign) is missing. It tells you what line the problem is on, and even points to the place where it figured out something was wrong. In this case, the ``syntax`` is not right, so the program cannot run. We get no output except for the error message In all these cases, you need to stop and read what you typed closely. The more you look at your own code the more you end up seeing what you THINK is there and not what is actually there. I trained myself to scan my code backwards looking at every character and making sure it belonged in the code. Believe me, it helps! .. note:: When I started teaching programming, I found it almost funny that students would bring me code that did not work and I could spot the problem in seconds. When I started pointing to the place where something was wrong, their eyes would get big, and they would rip the code off my desk and storm out of the office mad at themselves for not seeing the problem. Why this was so was easy for me to spot was easy to understand. They were too close to the code and stopped seeing what was really there (or not there!) Add a few more lines of code **************************** As long as we are just playing with Python, let's try a few more simple ``statements``. In the editor, add this code: .. code-block:: python for x in range(0,10): print "The square root of",x,"is",sqrt(x) Be careful when you type this in. The editor should automatically indent the line after the colon. We want that line to be indented four spaces more than the line above. Python is very picky about this, and tab characters are not the same as spaces. (Which is why I set up the editor to expand tabs into spaces). You can always move the cursor with the arrow keys to make sure you have spaces in the code. Run this and make sure it works. You should see these new lines: .. code-block:: text The square root of 0 is 0.0 The square root of 1 is 1.0 The square root of 2 is 1.4142135623730951 The square root of 3 is 1.7320508075688772 The square root of 4 is 2.0 The square root of 5 is 2.23606797749979 The square root of 6 is 2.449489742783178 The square root of 7 is 2.6457513110645907 The square root of 8 is 2.8284271247461903 The square root of 9 is 3.0 .. warning:: You might have needed to fix a few things in the code before this will run. We messed up the code and you need to un-mess it before adding the new lines. Hmmm, why did it stop at nine? Well, that new statement is called a loop, and in Python the ``range`` is just a set of numbers beginning with the first value and ending one short of the last value. (You need to ask Guido why). Notice anything weird? ====================== We used the name "x" once again. Formally, "x" is called a variable. In Python that variable can hold exactly one value. However, we can change that value whenever we want. We are changing it each time we process the loop. The statement begins by setting "x" to 0, then it processed the line indented below. It then goes back up to the first line and advances "x" to 1, then processes the line below again. It keeps doing the sequence over and over until the new value of "x" is equal to the final value in the range (10). It does not process the line this time, but falls through to whatever comes next. The output is not as pretty as we might like, but we will not worry about that for now. Let's try another statement *************************** Now add this code: .. code-block:: python x = "Tuesday" if x == "Tuesday": print("No class today") else: print("Whoops, I might need to go to class" Run this and see if you need to go to class! Notice the two equal signs together. We used a single equal sign in setting a variable to some value (formally, that statement is called an ``assignment statement``). One equal sign does make these two things equal, but what really happens if that the value on the right of the equal sign is placed in the container named "x" in this case. The two equal signs together ask if the two things have the exact same value. In this case, whatever is stored in "x" is compared to the value on the right side, in this case a string of characters. In this example, we put a string in the container and we are comparing it to exactly the same string. The result should be "true", so the first line should be displayed. The second line is ignored (skipped) since it should only be processed if the question results in a "false" value. Now change the first line to this: .. code-block:: python x = 5 Run the code gain and see what you get. Does this make sense? Remember, we are asking if the two things are exactly equal Formally, this is a ``decision`` statement that lets you ask a question about what is going on, and do one of two things. In this case, we are comparing "x" to some other value. If the two values are the same we do the first indented line, otherwise we do the second. Once again, watch the indenting carefully! In Python you can do more than one thing as long as all those things are indented the same amount. Does it seem strange to set "x" to very different things as we work through the code? In some languages, like C++ which most of you will learn next, this is not only strange, but illegal. In those languages, you tell the system exactly what kind of container you want, and you cannot change it afterwards. This lets the system check for silliness. In Python some of that silliness is actually handy (line printing out a bunch of stars): Add this: .. code-block:: python print("*"*50) This gives us this: .. code-block:: text ************************************************** C++ would be having a cow about now! That covers the basic statement types ************************************* Believe it or not, you just played with three basic kinds of statements that are fundamental to writing code in most languages: * The ``sequence`` - one statement after the another * The ``loop`` - do something a number of times * The ``decision`` - do one thing if a question results in "true", do something else if not. We can all go home now, right? Unfortunately, not quite! There are many more things to learn, and practice will make you much better at doing the important stuff, like solving problems! Back to the square root problem ******************************* In the earlier lab, we wanted to get the computer to calculate the square root of a number. I asked you to think about this and see if you could come up with a way to do this with just a calculator (four function only, no square root key allowed). Let's try to put a program together to do that job: First, we will be trying to figure out the answer by guessing an answer, checking it, then refining the guess in the hopes that we get a closer answer. That seems to say we will need one of those loop statements as part of the solution. Let's get started with a simple guess: .. code-block:: python x = 5 # this is the number we want the sqrt of guess = x / 2 # I am starting off with this guess Now, the scheme I am going to use is very old. I learned it in one of my first courses in college where we used computers to solve problems. It goes all the way back to Isaac Newton, who figured out a bunch of things like this. His scheme (oddly enough, called ``Newton's Method`` says to start with a guess, them improve that guess by calculating the average of that original guess and that guess divided by the number whose square root you are after. Here is how we express that: .. code-block:: python x = 5 # this is the number we want the sqrt of guess = x / 2 # I am starting off with this guess for guess_number in range(0,10): # try to improve it 10 times difference = x - guess * guess # how wrong are we? print (x, guess, difference) # show what we have now guess = (guess + x/guess)/2 # generate a new guess! Look at that last line. We are replacing the current value stored in the container named ``guess`` with a new value. That value if calculated by working out the ``expression`` on the right side of the equal symbol. We can use parentheses to make sure the calculation will be done the way we want. Also, notice that all three lines below the ```for`` statement are indented an equal amount. The ``loop`` will process all three lines in order each time we run through it. That is how loops work! You can do as much work as you like! Here is the output: .. code-block:: text 5 2.5 -1.25 5 2.25 -1.25 5 2.236111111111111 -0.0625 5 2.2360679779158037 -0.00019290123456805475 5 2.23606797749979 -1.8604708884595311e-09 5 2.23606797749979 -8.881784197001252e-16 5 2.23606797749979 -8.881784197001252e-16 5 2.23606797749979 -8.881784197001252e-16 5 2.23606797749979 -8.881784197001252e-16 5 2.23606797749979 -8.881784197001252e-16 It looks like we got as good an answer as we can get in about 5 attempts, not bad! Of course, I do not expect you to come up with something like this. Newton worked pretty hard to understand math well enough to even come up with this all those years ago. The point is to show you a simple scheme that can come up with the answer using a computer and a bit of code. Cool! Wrapping this experiment up *************************** Obviously, there is much work to do before you will be able to write code like this (or more complex code) on your own. That will come. This is just to get you started. The more code you write, or copy, and run, the more you will learn. By the way, take working code and make it wrong on purpose, just to see what kinds of error messages you will see. You also need to learn how to read those messages and figure out how to correct things. One last point ============== I preach a programming concept called ``Baby Steps``. Never, NEVER, write more than a few lines of code before you try to run that code. Using Python as we showed in this example make this simple. Just hit the ``Save`` icon in the editor after you get things set up, switch to the command prompt window, and run the program. .. note:: You might try pressing the up arrow key at the command line to speed this up. The ``command prompt`` window maintains a record of the commands you entered. You can use the up and down arrow keys to look through those entries until you find the one you want. Then press enter. You can even use the left and right arrows to move into the command and edit it! Boy, are programmers lazy! .. vim:set spell filetype=rst: