Saturday, May 26, 2012

Lesson 8 - Tuples and String Formatting

All right, last time we wrote our own functions, and now we're going to build on that using a few useful constructs of Python.

Tuples


What is a tuple?  A tuple is kind of like a list (see Lesson 4) except that it is immutable (like a string is immutable).  Tuples don't change once you create them; they will always contain the same objects/primitives in the same order.  (The objects themselves can be modified though, and I'll show you what I mean in a little bit).

Let's go back to our trusty old command line interpreter.  If you don't remember how to open it, just open a command prompt/terminal and type python.



Ok, we're ready.  To form a tuple, use parentheses like this

t = (1, 2, 3)
print t



Now you can access each item in the tuple just like a list (remember that both tuples and lists are zero index based, meaning that the "first" element is number 0).

print t[0]
print t[1]
print t[2]


Now, unlike a list, you cannot add, remove, or change the contents of a tuple.  Try this

t[1] = 42



See?  It won't let you.

So you may be wondering what the purpose of tuples are.  Simply put, tuples are just a way to pass around a sequence object (like a list) without worrying about the elements or size changing.


A Tuple of One

Incidentally, if you want to create a tuple with one item in it, you have to put a comma inside the parentheses.

t = (1,)
print t



Otherwise it treats the parentheses like they are part of a math equation, and you will only get the one element.

t = (1)
print t




Tuples in Functions

One of the most practical applications of a tuple is in regard to functions.  In the last lesson, I hinted that a function could return more than one value (which is rather unique to Python) and this is how it does it.

Open a new file and add this function


def valueAndDigits(strNum):
  return int(strNum), len(strNum)




Python treats that return as a tuple.  Now for the cool part.  You see, in Python you can do cool assignment statements like this

a, b = valueAndDigits("147")



Cool, huh?  With this statement, Python assigns the first item of the tuple to a and the second to b.  In order for this to work, you have to be exact—you can't have too many or two few variables or you'll get an error.  Just to see it work, let's print them out

print a
print b



Now run it and see what happens.


Exactly what we expected.  (Granted this isn't the most useful function, but it's only for demonstration purposes).

To see that the return value is indeed a tuple, you can do this


c = valueAndDigits("2048")
print c




And run it



And there you have it.

And now for something completely different . . .


String Formatting

This is perhaps one  of the most useful things in Python (and certain other languages).  Up until now, whenever we wanted to combine strings, we had to concatenate them.  It works, but it's not very pretty and if you have a really big string you want to create, it can get confusing.

To use string formatting, you create a string with markers inside it.  Each marker begins with a % sign and end in a letter which indicates the type of information you want to show.  Strings are %s and integers are %d (I think the d stands for 'decimal' because you could also do %x to show the integer in hexadecimal format).  After that string, you place another % sign and then a tuple with the different variables and values you want to display.  The whole thing looks something like this

"%s is a gr%d language!" % ("Python", 8)

which when run gives you

"Python is a gr8 language!"


Now let's try it.  Open up a new file and type this


name = raw_input("Please type your name: ")
greeting = "Hello, %s.  Welcome to Python!" % (name)
print greeting




Now run it, type a name, and see what happens.



We created a string without having to use any concatenation.

Certain markers have different options that go with it.  For instance, pretty much all markers let you specify a number for the number of spaces you want to fill.   To demonstrate, lets start a new file.  Well first create a function to display a name and number with a certain number of spaces, which will create our table.


def printNameAndNumber(name, num):
  print "%20s %10d" % (name, num)


Now we'll need some names.


printNameAndNumber("Sally", 27828)
printNameAndNumber("Bob", 58732)
printNameAndNumber("Joe", 91237)
printNameAndNumber("Octavian", 11263)
printNameAndNumber("Olivia", 82373)




Now run it.


There you go.

Now the most useful I have saved for last.  For integers (and floats) you can tell the string formatter to put a certain number of leading zeros onto a number.  To do this, simply put a zero before the number in a %d marker.  To demonstrate, let's change our function to this


def printNameAndNumber(name, num):
  print "%20s %010d" % (name, num)


Now run it and see what happens.



See? The 0 before the 10 made all the difference.


Putting It All Together

Now let's revisit the function we created last time—the one that turned an integer into a dollars-and-cents string—and let's use tuples and string formatting this time.

Start a new file, and lets start by creating a function that takes our integer, and returns the dollars and cents.

def dollarsAndCents(amount):
  return amount / 100, amount % 100

There we go.  Now for a function that takes an amount and creates a string, but this time we'll use string formatting.  We'll also use the function we just wrote.

def dollarString(amount):
  dollars, cents = dollarsAndCents(amount)
  return "%d.%02d" % (dollars, cents)

But wait!  We're using the variable amount in two places.  Won't that mess things up?  Actually no.  Remember what we said last time about scope?  Each function variable has its own variable scope, so we can reuse names that can't be accessed by this function.  In this case, amount cannot be accessed by dollarString() because it exists within the function scope of a different function.  If, however, amount had been declared outside the functions in the global scope, then we would have two variables called amount.  We still would be okay inside the function unless we used the global keyword which tells Python that we want to use the variable amount from the global scope, but even that is only because we declared amount as a local variable (in the parameters), and it hides (or shadows) the global variable.   If this is confusing, maybe this will help.  (I'll try to post a more detailed explanation of scope later.)

Ok, now that we have our functions, lets have more fun with tuples.  This time, we'll put them inside a list of items with prices.


items = [
  ("Milk",   359),
  ("Bread",  142),
  ("Cheese", 520),
  ("Coffee", 510),
  ("Bacon",  466)
]

Ok now we'll iterate through them and print them out in columns


for item in items:
  print "%10s $%5s" % (item[0], dollarString(item[1]))



Don't worry if that looks a little complicated.  Just think about it in pieces.  We have the string for the formatting

"%10s $%5s"


that will give us two strings—the first to fill up 10 characters and the second to fill up 5 characters.  (And we'll have the dollar sign lined up on the left to look all pretty.)

Then we have the % that tells Python to do the string formatting.  Then we have our tuple.

(item[0], dollarString(item[1]))

The first item is just pulled right out of the current item in the list, and the second parameter is taking the second item and putting it into our function.  If we didn't have functions, this would look a lot more complicated.

So after all that, you should have something like this.



Now for the moment of truth!  Run that code!



Beautiful!  It worked.  You're well on your way into the world of programming!


Review

Here's what we did today.
  • A tuple is an immutable sequence
  • You create a tuple by placing objects and primitives inside parentheses with commas
  • You cannot change the items in a tuple, but you can modify the actual objects inside (provided they too are not immutable)
  • You can use tuples to return more than one value from a function
  • You can use tuples to assign objects and primitives to multiple variables at the same time
  • You can use string formatting to quickly construct a string from various pieces of data
  • String formatting markers start with a % sign and end with a letter for the time of data you want to place there (eg s for string and d for integer)
  • Numbers between the % and the designated letter determine how many spaces the data will fill and what character will fill the extra space
That's all for now!  Happy programming!








1 comment:

  1. "I very much enjoyed this article.Nice article thanks for given this information. i hope it useful to many pepole.php jobs in hyderabad.
    "

    ReplyDelete