variables, control structures and functions
Alright! Let's do some programming. This is going to be kind of a long post, but it will (hopefully) include all of the basic concepts that you'll need to grasp in order to write a computer program. I'd suggest coming back to it a couple of times if you don't have the stamina to power through. I wanted to get it all out at once, though — I always find it frustrating to be given piece after tiny, useless pieces, patiently waiting until things start making sense.
Let's get on with it...
So what is a program? We could get fancy about defining it, but there's no need: put simply, it's a set of steps for a machine to perform on some data until it finishes. The data could come from anywhere — a sensor, a file, from pre-set values within the program itself, wherever; and the "finished" criteria might change — the user selecting "quit", the program finishing a calculation or reaching the end of a file, whatever. For now, the specifics are unimportant.
Variables
A program manipulates data through the use of variables. You probably remember variables from algebra. They're pretty much the same thing here, with one important exception: variables in an equation all happen at once, so to speak. It may take you a moment to figure out what x equals, but it doesn't change as you figure it out. A variable in a program does change over time, as the program executes. It's important to realize that — tracing through the various stages of a variable's existence is the crux of debugging a program.
So what does a variable look like in Python? Like any word that isn't reserved for use as part of Python itself. You don't have to do anything special to declare variables before you use them. Just assign something to one and it'll become available.
SomeVariable = 0
A few notes: variable names are case sensitive. SomeVariable is different from SOMEVARIABLE. They can contain both letters and numbers, but must start with a letter.
Variable Types
So what can we put in a variable?
- Scalars
- Numbers! Computers love numbers. For our purposes, let's worry about integers (ints) and decimals (floating point numbers — floats). Pretty straightforward. Technically speaking, a single keyboard character (a char — like 'a' or '$') is also a scalar, but you don't really need to worry about that in Python. I mention it just so that I can use the term without guilt.
- Strings
- Strings get their names because they're sets of characters strung together. They're text, in other words, and can be of any length. They're signified by quotes (either single or double — either works, but they must match) and can include multiple lines. How? By the use of delimited characters, which are signified by a preceding backslash. \n means "new line", for example. \t means "tab". \' means "single quote" and \" means "double quote" — useful for when you need to include a quote symbol inside a string that is defined by quotes itself. Example time!
x = "hey!\nthis prints out a \"string\""outputs
print xhey!
Strings are also arrays. So what the hell is an array?
this prints out a "string" - Arrays
- An array is a special kind of variable containing multiple values that can be reached by number. Think of it like the pages of a book: you could keep all of those pages separate, but it'd be a pain to manipulate them. It's much easier to say "page 200 of Harry Potter". Or, in programming-ese, HarryPotter[199]. Why 199? because arrays are zero-indexed — this means that the first entry is HarryPotter[0], not HarryPotter[1].
Virtually every programming language refers to these kinds of structures as arrays, but Python doesn't. In Python, simple arrays are called lists. Be forewarned: I'll probably slip into calling them arrays. For one thing, I'm more used to the term. For another, there are a couple of other array-like structures in Python — the list is just a specific type of array. I'll collectively refer to lists, strings, dictionaries, tuples and other indexed data types as arrays.
You can define a list like this:
MyListOfPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]Python's insistence on terminological weirdness is made up for by its array-slicing features, which are, frankly, totally awesome. The syntax is ArrayName[Start:End]. For the above array
MyListOfPrimes[2:5]Would return an array equal to
[5, 7, 11]Go ahead — count up the positions in the array (remember to start with zero!). Something will seem amiss. It's easy to see why it starts with 5 — that's clearly at the third spot — position 2. But why does the value end with 11 rather than 13? 13 is the value in position 5 of the array. The reason is that the End in ArrayName[Start:End] isn't inclusive.
Other things to note: you can leave Start or End out entirely, and Python will assume you mean the beginning or end of the array, respectively. You can also use negative values for either — when you do, it refers to the distance from the end of the array rather than from the beginning. It's all a little confusing at first. Don't worry about mastering it — you'll probably need to futz around with things when you start using arrays. I just want you to be familiar with the notation.
As mentioned, strings are really just a special class of arrays. You can use the exact same slicing syntax with them as you could with the list above:
MyString = "Michael Chiarello is totally undeserving of my vitriol"
print MyString[0:21] + MyString[24] + MyString[20:23] + MyString[-2:]Notice the plus signs — we can add strings. More on that in a second.
Functions
Here's another part of programming where math terminology creeps in. A function is a way to make a particular operation reusable (this is more useful than it will probably seem from my examples). They can be sent zero or more values, but they only return one variable (there are ways to make variables contain multiple values, one of which you already know). They look like this:
def AddParameters (x,y):
ValueToReturn = x + y
return ValueToReturn
print AddParameters(3,2) # this will print out '5'
print AddParameters(0,6) # this will print out a '6'
Pretty simple, right? Two things to note: first, the hash (#) mark signifies a comment. This isn't a function-specific thing, it's just something I haven't gotten around to mentioning yet. When Python sees a hash mark (that's not in a string), it ignores everything else until the end of the line. In most other languages you can accomplish the same thing with two forward slashes (//). Unlike other languages, Python has no easy way to comment out multiple lines of text at once (boo!). You'll need to include a # on every line you want commented out.
The other, more important thing to note is the indentation in the above example. How does Python know where the function ends and the program begins? Okay, the "return" is kind of a clue. But the indentation is the real story. Most other languages define where blocks of code start and stop by using braces ({}). Not Python. It decides this by indentation. Consider:
def AddParameters (x,y):
ValueToReturn = x + y
return ValueToReturn
print "test"
print AddParameters(3,2)
This will only print '6' — the function stops executing when it hits the 'return' statement.
def AddParameters (x,y):
ValueToReturn = x + y
return ValueToReturn
print "test"
print AddParameters(3,2)
Whereas this will print 'test' on one line, then '6' on the next. That's because the statement that prints 'test' is no longer part of the function, by virtue of its lack of indentation.
You can indent by any amount, but make it consistent! You'll eventually have to nest layers of indentation within one another, so it'd be best to make sure they're all the same amount. Also, although they work perfectly well, it's considered gauche to use tabs, for a variety of reasons — use spaces instead. Most decent text editors can be told to insert a particular number of spaces whenever you hit tab instead of inserting the literal tab character. So while it may be an annoyance in PythonIDE or ActivePython, when you do more serious programming in a text editor, it's not nearly as irritating to use spaces.
Operators
An extra bonus section! Exciting, I know. But necessary. We've already used the plus sign without explaining it. What it does is, hopefully, pretty obvious. The same can be said for minus (-), divide (/) and multiply (*). Less obvious are exponent (** — 2**3 is equal to 23 is equal to 8) and modulo (% — 11%3 is equal to 2). All of these are operators. Like articles in English, they're hard for dopes like myself to define, but are vital.
The previously mentioned operators are arithmetic operators, and, as I mentioned, should be fairly self-explanatory. The only complication is that operations performed exclusively on integers will only result in integers. So
print 5 / 2
Outputs '2'. The solution is simple: convert part of the operation to a floating point number:
print 5 / (2 * 1.0)
This results in '2.5'.
There are some non-arithmetic operators, as well. For one thing, there's the assignment operator, which we've already seen (=). It assigns the current value of the value on its right to the variable on its left.
x = 1
One = x
x = x + 1
Two = x
x = x + 1
Three = x
print One + " " + Two + " " + Three
Prints out '1 2 3'.
Don't confuse the assignment operator with the equivalence operator! The latter is a logical operator, and is composed of two equal signs (==). Accidentally switching them will cause errors. Here's an example of the equivalence operator:
x = 1
print (x==2) # prints 'False' because x is not equal to 2
Other logical operators include 'greater than' (>); 'less than' (<); 'less than or equal to' (<=); 'greater than or equal to' (>=); 'not equal to' (!=); and 'not' (not — for example, "print (not(x==2))" added to the last example would print 'True').
Control Structures
We're finally ready to begin controlling program flow. We'll do this with three control structures: if, while and for. All of them allow you to treat data in dynamic ways. But first, let's figure out how to get some data. To do that, we'll use the raw_input() function, which is built into Python. It's simple:
OurValue = raw_input('Please enter a value')
This will present the user with a prompt saying "Please enter a value". They'll enter something, and it'll be stored as a string in the variable OurValue. Remember: this will be a string, even if the entered data is numeric. If I want to turn a "9" into 9, I need to cast it like so:
SomeValue = int(SomeValue)
Okay. All set. Let's check out the if statement:
SomeValue = raw_input('Please enter an animal: ')
if (SomeValue=='dog'):
print 'woof'
Frequently you'll find yourself wanting to do one thing if a condition is true, and another if it's false. This is what the else clause of the if statement is for:
SomeValue = raw_input('Please enter an animal that barks: ')
if (SomeValue=='dog'):
print 'woof'
else:
print 'that is not a dog'
Note the indentation — an if or else clause can execute any number of lines of code; the bounds of what it will execute is determined by indentation, just like in the function explanation above.
Sometimes it's useful to chain together a number of if statements. Rather than producing a heavily-indented mess, you can use the elif statement (short for else if):
SomeValue = raw_input('Please enter an animal: ')
if (SomeValue=='dog'):
print 'woof'
elif (SomeValue=='cat'):
print 'meow'
else:
print 'I don\'t know what kind of sound that makes'
Next up: while. This structure executes a block of code while a condition is true. This is a good way to cause infinite loops — blocks of code that repeat without ever exiting. Be careful of them; you may have to ctrl-alt-del out of ActivePython (or Force Quit PythonIDE) if you accidentally cause one.
On the other hand, you can write some awesomely crappy games with it. We'll need to add one more piece: importing the "random" module. It's built into Python; you'll just need to add some language saying to import it. Simple enough:
#import the random module
import random
# produce a value between 1 and 10
ValueToGuess = random.randint(1,10)
#ensure that the initial state of CurrentGuess
#is not equal to ValueToGuess
CurrentGuess = ValueToGuess + 1
while(CurrentGuess!=ValueToGuess):
CurrentGuess = int(raw_input("Guess: "))
if(CurrentGuess<ValueToGuess):
print "Too Low"
elif (CurrentGuess>ValueToGuess):
print "Too High"
print "Right! The value is " + ValueToGuess
There's one last control structure to cover: for. This one works differently in Python than in other languages. The classic formulation is some variation of for variable = start to end (do something), where start and end are integers (syntax varies wildly, but this is the basic idea). In Python, the formulation is for variable in list:. For example:
SampleList = [1, 2, 3]
for Entry in SampleList:
print Entry
This will output
1
2
3
Sometimes you won't want to iterate across a list — you just want to do something a set number of times. For that, you can use the range() function, which will return a list with the correct number of entries, containing values corresponding to the index of each position in the list. Check it:
for i in range(10):
#note the trailing comma;
#this prevents a new line from being printed
print str(i) + ',', # str() converts an int to a string
# output a newline to get the previous line to display
print ''
This will output "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ".
It takes some practice to easily understand the pattern in which an algorithm will execute — this is called the program's flow. When your program starts doing something unexpected, you'll need to mentally step through the program, trying to keep track of what's happening. It can also be useful to comment out parts of your program, or to insert print statements to ensure that variables are carrying the values you expect. Debugging is frustrating; it's mostly a matter of practice.
Alright — that's pretty much it! There are some more minor details that we could go over, but we've covered the basic concepts. I realize that number-guessing games are boring, but it's important to understand how to control the logic of a program before you start trying to do cool things with it. In the next (much shorter) installment, we'll handle reading and writing from files, and briefly introduce you to regular expressions. Then it's time to start interacting with the networked world.
But first, a little practice wouldn't hurt.
Homework
We can manipulate variables. We can play around with arrays. We can control program flow. Let's put these things together with a practice exercise. Try writing a program to find all of the words that can be created with your phone number, based on the letters associated with each number on the phone keypad — ala 1-900-EZ-BABES.
Let's assume seven digits, and decide that 1 and 0 will equal a blank space. We're also not going to try to match our results against a list of real words. Instead, we're just trying to list every possible combination of applicable letters.
I'll give you some hints to get started. Depending on your specific solution, these may or may not be applicable:
- Think about what operation(s) you'll have to do over and over. Use functions for such instances.
- Remember that numbers and strings are different. '9' is different from 9. You can convert to an int with int(); you can convert to a string with str().
- Some digits have four letters associated with them; most have three. Whatever you're doing automatically, you'll have to vary how much of it you do, based on the number.
- If you find yourself wanting to print a value without a line break appearing at the end of the line, put a comma at the end of the line:
print 'something',Outputs 'something somethingelse'
print 'somethingelse'
There are a bunch of ways to solve this problem; I've implemented one of them below. Highlight the text to reveal the solution. The top part is a function — you might try just revealing that, first, if you're having a hard time figuring out where to get started.
def FindLetters(number):
if (number == '2'):
return ['A','B','C']
elif (number == '3'):
return ['D','E','F']
elif (number == '4'):
return ['G','H','I']
elif (number == '5'):
return ['J','K','L']
elif (number == '6'):
return ['M','N','O']
elif (number == '7'):
return ['P','Q','R','S']
elif (number == '8'):
return ['T','U','V']
elif (number == '9'):
return ['W','X','Y','Z']
else:
return [' ']
number = raw_input('Enter Your Phone Number: ')
for FirstDigit in FindLetters(number[0]):
for SecondDigit in FindLetters(number[1]):
for ThirdDigit in FindLetters(number[2]):
for FourthDigit in FindLetters(number[3]):
for FifthDigit in FindLetters(number[4]):
for SixthDigit in FindLetters(number[5]):
for SeventhDigit in FindLetters(number[6]):
print FirstDigit + SecondDigit + ThirdDigit + FourthDigit + FifthDigit + SixthDigit + SeventhDigit
I should also probably note that this solution is written so that it'll be easy to follow; no self-respecting programmer would actually do it this way. I'll post a "real" solution in a separate entry.

Comments
"Array" is the name of a particular standard module in python, used for, well, I'm not sure—I think people who do numerical processing or interfacing with C use it. The pythonic term for what you're calling an "array" is "sequence".
Also, re slices, there are actually three possible arguments: start, stop, and step. So if you want every other element of a sequence s, you can access it with s[::2] (or s[1::2] if you want every other element starting with the first).
As with the start and stop values, the step can be negative; however, in that case things can get pretty confusing. The only really useful thing you can get out of that is that you can get a reversed copy of a sequence s (note, you won't reverse the sequence itself, just get a copy of it) with the expression s[::-1].
Finally, although tom said he'll refer to dictionaries (which haven't yet been introduced) as arrays, you can't slice them, because they aren't indexed but keyed. The same goes for sets, which are related.
(Also, you might want to enable <code> in comments.)
It might also be worth noting that a correct implementation will yield (depending on the numbers) somewhere between a thousand and a million lines of output if you print your answers, so you might want to be prepared to stop execution if you actually test your solution out.
Also, this is wrong:
It will output "something somethingelse". Commas in print statements insert spaces. This is true whether or not they occur at the end of the line! Eg, will print "something something else 1" (with a new line at the end). If you want to print two things together with no space between, or some custom formatting, you have to mess around with format codes, which I'm sure will be introduced at some point in the future.i am thinking this is not going to be as spectacularly easy for me as i imagined.
Thanks for the notes, Ben. I've corrected those mistakes (and a few others). I'm sure there are more in there.
And Catherine: don't get discouraged. Just take it one section at a time, and ask questions if things don't make sense. This is a lot of text, but it's really just explaining a few simple concepts. Once you get used to them, they're easy as pie.
I'm refreshing like mad but see no updates to the print-comma thing (which also occurs in one of the for loop examples, printing a list of numbers).
d'oh. I fixed them, hit save, but my MT authentication had expired. Had to log in again. Should be better now.
So, "for" in Python is kind of like "map" in Scheme/Lisp?
I think I am going to have to tie my pinkie finger down to keep from hitting the semicolon at the end of each line.
Actually, "map" in python is kind of like "map" in Scheme/Lisp.
Also, the semicolon isn't, technically, an error (at the level of syntax at the end of a line. You can put multiple statements on the same physical line with a semicolon:
will print "hello world". But it's certainly stylistically wrong.One good thing to know is that the control variable(s) in a for-loop get their values according to basically the same rules as assignment in general works. So, just as all of these are valid assignments:
, so too are all of these valid for-loop beginnings:With the last one, lst[0] will be equal to 9 at the end of the loop (assuming it hasn't been modified within the loop). (enumerate() accepts a sequence, and returns a list of (index, value) pairs.)It's amazing how similar different languages are, particularly from a structural standpoint (variables, functions, operators, etc). The only thing that really differs is syntax. I'm a VB/ASP/Javascript/occasional C# programmer, and I'm pretty confident that I could pick up Python with relative ease.
maybe my interpreter is crappy but I think the last line of that number guessing game should be
print "Right! The value is " + str(ValueToGuess)
Post A Comment