Saturday, February 4, 2012

Lesson 4 - Floats and Lists

Floats


In Lesson 3, we learned about text editors and how to run Python script files.  (If you haven't done the setup, you may want to go back to Lesson 3 because you'll need to have all that done eventually.)  For this lesson, we'll use the command line interpreter until the end when we'll write a program.

So now, open a console window.  (If you don't remember how, look here.)

Let's cover floats really quick.  A float (or floating point number) is a number that contains a decimal portion.  In other words, a float is whatever isn't an integer (more or less).  To make a float, simply put a decimal point after the whole part of the number.  Like so:

print 12.4


Nothing to it, right?  Here's the tricky part.  What if you are dividing numbers?  Try this

print 3 / 2


Surprised?  Why did we get 1 as the answer?  That's because we were dividing with integers; when you divide with integers, you get an integer answer.  If you want the remainder, you can to use the modulus symbol (which is the % sign).

print 42 % 5


Great, but how do we get a floating point answer?  We have to use floats to start with; at least one of the operands (the numbers involved in the math operation) has to be a float.  How do we make the integer 3 a float?  Remember, this isn't like math class; this is programming.  We can simply do something like this:

print 3.0 / 2.0



Wait!  Aren't 3.0 and 3 the same number?  Well, yes and no.  They are the same number, but Python treats them very differently.  The decimal point is just your way of telling Python that you want this number to be a float and not an integer.

Now then, question: for representing currency (eg $1.40) in a program, should you use integers or floats?  Answer: you probably actually want to use integers.  Why?  You always know that there are two decimal places, so you just multiply everything by 100.  So $1.40 becomes 140.

The reason you would want to do this is because of something called round-off error.  See, in a computer,  floating point numbers are represented in a very special way, and sometimes weird things can happen (like this).  That being said, you'll probably be better off with integers in that situation.


Lists


Here's where things get interesting.  A list is just what it sounds like; you create lists of things like strings, numbers, and floats (and a lot of other things we'll get to later).  These items are sometimes called elements.  Unlike some languages, Python makes lists (often called arrays) really easy to make.  You create a list by using square-brackets [].  You can create an empty list like this:

myList = []

It stores this list with this variable.  An empty list isn't much good to us (at least not right now).  So let's create a list that has something in it.

myList = [1, 2, 3]

Now we have a list that contains the integers 1, 2, and 3.  Each entry is separated by a comma.  Now we can print that list.


print myList 



Ok great, but what good is it?  Well, we can access different items in that list by using square-brackets after the variable name like this:

print myList[2]



Tada!  The number 3!  But wait!  Isn't 3 the third item in the list?  Well sort of.  Lists are what's called zero-based, meaning that the "first" element is element 0.  Try it and see what I mean

print myList[0]



See?  That may seem a little weird at first, but it makes things WAY easier in the future, and once you start using lists this way, it becomes second nature to you.

You can also assign to a location in the list, provided the list already has something assigned to that position.  We can say

myList[1] = 17

but we cannot say

myList[5] = 17



See that error?  All that means is that we tried to assign outside the bounds of the list.

To get the length of list, you use the function len().

print len(myList)



Len takes one parameter, and returns an integer of its length.  The length of the list is 3 (because there are three elements in it).  Thus the last element of a list is always len(list) - 1.  It just takes some getting used to.

Incidentally, you can use len() with strings too.  The len() function counts every character (letter, number, or symbol) in the string (including spaces).

print len("Python is cool")



Only certain objects have a length.  What's an object?  Glad you asked.


Objects and Methods

An object is just a name for a group of information—like the information in a string or a list.  Most objects have cool things called methods.  A method is like a function, except you call it by placing a period(.) after the variable name.  The you put the method name, and last comes the parameters.  For example, a list has a method called append() which lets you add an item to the end.

myList = [1, 2, 3]
myList.append(4)
print myList



Voila!  You've called your first method.  Now remember that methods are particular to a specific object type (actually it's called a class, but more on that in another lesson).  Strings, for example, do not have an append() method.  Where can you find a list of the methods for a given object?  Check the Python documentation.  (Here's the ones for lists.)

There are many useful methods for each kind of object.  Be sure to check them out; they can really save you a lot of extra programming.

Integers and floats, however, are not objects.  They are called primitives.  They have no methods, and they are not stored by reference; they are stored by value.  Actually, that leads me into my next topic.


Reference


This may be hard to understand, but don't panic.   Variables are not objects; they point to objects.  This is commonly referred to as storing an object by reference.  In other words, when you say

myList = [1, 2, 3]

Python creates a list containing the integers 1, 2, and 3 in memory (you may have heard of RAM (Random-Access Memory); that's what this is; it's where your program stores its information), and then sets the variable myList to point to that list.  What does this mean for you?  Well, let's do this:

otherList = myList

What did we just do?  You may think we just told Python to make another list containing 1, 2, and 3 and assign it to otherList, but that's not actually what happened.  To demonstrate my point, let's append the number 4 to myList and then print otherList.

myList.append(4)
print otherList



Whoa!  Did appending to myList change otherList?  Not exactly.  Both myList and otherList point to the same object.  You can think about it like this:



The list is sitting off in memory somewhere, and both variables point to it.  So when you use the variable myList for a method call, what you're really saying is "take the object myList points to and perform this method."  Even though you have two variables, there's only one list object involved.

I know that sounds crazy, but it's how it works, and its really cool that it works that way because you can do some pretty cool stuff.  Now what if for some reason you wanted to copy a list, you have to use the function called list().

myList = [1, 2, 3]
otherList = list(myList)
myList.append(4)
print myList
print otherList



There we go.  Now we have two lists in memory.  When we used the list() function, Python made a copy of the list.  (Note: if that list contained objects, the objects are not copied only their references are, but I won't go into that now).



Immutable

Now then what about strings?  Strings are objects; therefore they get pointed to (and not copied like numbers).  So can strings change like lists do?  Well, the truth is that there are no methods of strings that can cause strings to change.  So how do you use them?

Let's take for example the string method called upper().  It takes no parameters, and it's used to create a string with all uppercase letters.  (There's also a method called lower() which creates a string with all lowercase letters.)  Let's try called this method.

string = "This is a string."
string.upper()
print string



Huh?  Nothing happend?  Why didn't the string change?  That's because strings are immutable; they don't change.  This is good because you don't want to be changing strings around in one place and have things messed up in another.  So if upper() can't do anything to the string itself, what does it do?

Answer: It creates a new string and returns it.  A method (or function) can return something that you can store in a variable--either a primitive or a reference to an object.  Like the len() function we used above, it returns an integer of the length of the list or string, and we can assign it to a variable or print it or whatever we want.

Incidentally, that's why the string "THIS IS A STRING." appeared after you called upper().  In the command line interpreter, typing an object or primitive on a line causes the console to output a representation of that object or primitive.  (If you type in 2 + 2, even without a print statement, you'll still see 4).  So that string is not the value of the string variable but rather what was returned by upper().

To use upper() properly, you have to do something like this.

uppercaseString = string.upper()
print uppercaseString



See?  It works, but what if we wanted to have the string variable point to an uppercase version of itself?  Remember how assignment works?  It's not like math class, so we actually can do something like this:

string = string.upper()
print string 



No problem!  Python runs the method upper() on string object pointed to by the variable string, creating that new string object, and then it assigns a reference to that string object back to the variable string.  Make sense?


Let's Write a Program


Here we go!  Now we're going to write a program that uses everything we've learned so far.

We're going to create a list of words and then make each of them uppercase.

First things first.  Create a new folder in the "python" folder we created in Lesson 3.  Call this new folder "Lesson 4"; this is where you will save the new ".py" file we will create.

Speaking of which, open up your text editor.  (I'll be using TextWrangler on my Mac.)



Save this file in the "Lesson 4" folder we just made.  (A name like "lesson4.py" should do.)  Now we can start writing our code.

First let's do a really quick floating point example.  First, let's create a variable with the value for pi(π).



pi = 3.14159265



Now we can use the variable pi so we don't have to type it in every time.  Now let's do something like this:


print "A circle with diameter 7 inches has a circumference of"
print 7 * pi


Great!  But what if we want to add the unit "inches" after our answer, and put it on the same line?  We can't concatenate a number with a string, so we'll have to convert the number to a string first.  Replace the line

print 7 * pi

with this one:

print str(7 * pi) + " inches"

Yes, str() works on floats too.  That line will multiply 7 by pi and convert it to a string before concatenating " inches" on the end.  Notice that I put a space before the words "inches" so that we would get some separation between the number and the unit.

Now let's do the same thing, but for the area of a circle now.


print "A circle with radius 2.4 has an area of"
print str(2.4 * 2.4 * pi) + " square inches"


There, now that will calculate the area of a circle of radius 2.4 inches.

Now let's do some lists stuff, but first let's use the handy trick we learned from this blog entry.

print "-" * 80

That will print a line of "-" characters to give us some separation in our code.  Now let's create a list of strings.  Type this all on one line:

wordList = ["python", "programming", "two words", "This is a sentence."]

Notice how the commas go outside the quotation marks.  (If you are an English teacher, you're probably cringing right about now, but don't worry: it's not English; it's Python!)

Now let's do some cool by-reference stuff:

otherList = wordList

Now we're going to do a lot of things in one line.  We're going to get the item at index 0, convert it to uppercase, and then reassign it to position 0.

otherList[0] = otherList[0].upper()


Yes, we can do all that in one line.  We'd be in trouble if the object at 0 wasn't a string, but we already know it is, so it's ok.  Now let's do the same thing with all the other strings:


otherList[1] = otherList[1].upper()
otherList[2] = otherList[2].upper()
otherList[3] = otherList[3].upper()


Right now, you may be thinking that that's a lot of copy-and-pasting.  Surely there's a better way to do it!  Well, there is, and I think I'll cover that in the next lesson.  For now, let's just do it this way.

Now let's print the strings using the variable wordList.  We assigned the list at wordList to otherList, so it should have passed by reference, meaning that there is only one list involved here.  So if we type


print wordList[0]
print wordList[1]
print wordList[2]
print wordList[3]


we'll get the uppercase versions of the strings, even though we changed and assigned them using the variable otherList.

Now then, your full program should look like this:




pi = 3.14159265
print "A circle with diameter 7 inches has a circumference of"
print str(7 * pi) + " inches"
print "A circle with radius 2.4 has an area of"
print str(2.4 * 2.4 * pi) + " square inches"


print "-" * 80


wordList = ["python", "programming", "two words", "This is a sentence."]
otherList = wordList


otherList[0] = otherList[0].upper()
otherList[1] = otherList[1].upper()
otherList[2] = otherList[2].upper()
otherList[3] = otherList[3].upper()


print wordList[0]
print wordList[1]
print wordList[2]
print wordList[3]


Now for the moment of truth!  Open up a console window and navigate to the Lesson 4 folder we created by using the "cd" command.  (Consult Lesson 3 if you don't remember how.)  Now let's run it.  Type

python lesson4.py

and hit return (or Enter).



Voila!  Our program ran!  Take a look at the output (the stuff that printed to the console).  Is it what you expected?  First, we ran our calculations:


A circle with diameter 7 inches has a circumference of
21.99114855 inches
A circle with radius 2.4 has an area of
18.095573664 square inches


These answers are approximately correct.  We could get better approximations with a more precise definition of pi.


Then comes our line


--------------------------------------------------------------------------------

And finally, the uppercase strings from our print statements


PYTHON
PROGRAMMING
TWO WORDS
THIS IS A SENTENCE.


Pretty cool, huh?  We're well on our way to learning how to make the computer do work for us.  Right now we're just covering concepts, but it won't be too much longer before we can right a program that will do something useful.

Review


That's it for now!  I know it's a lot to take in, but we'll be reviewing all this stuff along the way.  (Trust me; that object-reference thing is going to be in almost every lesson from here on out.)  Anyway, here's what we learned in this lesson:
  • Floats are numbers with decimals.  Python treats floats differently from integers.
  • To get a float result when performing a mathematical operation, at least one of the operands must be a float.
  • When you divide with integers, the result is an integer.  You can get the remainder of an integer division by using the modulus (%) operation.
  • Lists are ordered collections of elements.
  • Lists are zero-based, meaning that its "first" element is at index 0.
  • You access elements of a list by using square-brackets [].
  • The len() function can be used to get the length of strings and lists.
  • An object is something like a string or a list.  It usually has methods which sometimes perform operations on the object and/or return an object or primitive.
  • Objects are also stored by reference, meaning that two or more variables can point to the same object.
  • Primitives are like integers and floats.  They have no methods, and they are stored by value.
  • Strings are immutable objects; they don't change.  String methods that would be used to modify a string instead return a new string.
That's it!  See you next time!






No comments:

Post a Comment