Sunday, July 28, 2013

Objects

     Lists gather variables and values together to use repeatedly. Functions gather code together to use repeatedly. And then there's objects. No, not the chair or couch you may be sitting on or the computer you're using, but objects which collect functions and other data together.
     Real world objects have things you can do with them, or actions. They also have certain attributes, or properties.  This same rule applies with Python as well.
     In Python, characteristics you know about an object are attributes. Things you can do with them are methods.
     Let's say we were making a ball in Python. The ball would have attributes and methods. The attributes would look like this:

ball.color
ball.size
ball.weight

     The methods would look like this:

ball.kick()
ball.throw()

     Etc.
     The attributes of the object are whatever you know, or will know about it. They're bits and pieces of information, which are numbers, strings, etc. Variables. Variables that are inside the object.
     The methods of the object are something you can call to do something. Functions. Functions that are inside an object.
     So, attributes are information, and methods are actions. Objects collect those two together. Alright, now that you hopefully understand what objects are by now, let's start making some!
     We need to make an object with these steps: first, we make the class. The class keyword tells Python IDLE you are making an object. We use the class to make an instance, or the object. You define what the object looks like, and then you put your object to use. Let's write this program in a new window!

     class Ball:

    def bounce(self):
        if self.direction == "down":
            self.direction = "up"

     Alright, here's our object. That self keyword is a big thing in making games. This is a hint that we're getting to the big stuff soon!
     So, all we have right now is a class definition for a ball with one method, bounce(). There are no attributes because they really don't belong to the class, but its instance. Hey, speaking of instances, why don't we give our object some?
     If we want an instance of our Ball, we'd do something like this:

theBall=Ball()

     We have no attributes for our ball, so let's get that taken care of.

theBall.size="small"
theBall.color="purple"
theBall.direction="down"

     Alright, we've got the attributes covered. Now, let's see our bounce() method again.
     This is how we would use it.

theBall.bounce()

     Okay, looking good. Let's put all of this in our program. We will also add in some print statements so we'll know what's happening.

class Ball:

    def bounce(self):
        if self.direction == "down":
            self.direction = "up"
         
theBall=Ball()
theBall.size="small"
theBall.color="purple"
theBall.direction="down"


print("The ball has been loaded.")
print("The ball is", theBall.size)
print("The ball is", theBall.color)
print("The ball is going", theBall.direction)
print("Let's bounce the ball.")
theBall.bounce()
print("The ball is now going", theBall.direction)

     Now let's test this. Run the program and see what happens.

>>> ================================ RESTART ================================
>>>
The ball has been loaded.
The ball is small
The ball is purple
The ball is going down
Let's bounce the ball.
The ball is now going up

     The bounce() function changed our balls direction! That's pretty cool, don't you think?
     That's about it for this article. See you later!

Friday, July 19, 2013

Global

     So, global variables are variables that can be used outside of a function. But what happens when we use them inside a function? Well, let's create a new program, and write this:

def groceries(oranges):
    orangePrice = 1.53
    print("Orange price inside function: ", orangePrice)
    orangeTotal=orangePrice * oranges
    return orangeTotal

print("Enter a price for the oranges")
orangePrice=float(input())

totalPrice = groceries(3)

print("Orange price outside function: ", orangePrice)

print("Orange total: ", totalPrice)

     Now, let's save the program and run it. Let's say, each orange costs $3, so type "3" when you run the program. So, here's what should happen.

Enter a price for the oranges
3
Orange price inside function:  1.53
Orange price outside function:  3.0
Orange total:  4.59

     Hold on a second, $3 times $3 doesn't equal $4.59! $1.59 times 3 equals $4.59! What about our oranges that cost $3 each? Well, this program here has a bug.
     No, not a real bug. There's a problem that doesn't make it run right. How did we get this bug, though? Well, orange price is $1.59 when it's being used inside the function, and is the user's input outside of the function. The user's input doesn't even exist during the function! It's a little confusing, but all we have to do to fix this is with the global function. Retry the program, instead with this code:

def groceries(oranges):
    global orangePrice
    print("Orange price inside function: ", orangePrice)
    orangeTotal=orangePrice * oranges
    return orangeTotal

print("Enter a price for the oranges")
orangePrice=float(input())

totalPrice = groceries(3)

print("Orange price outside function: ", orangePrice)

print("Orange total: ", totalPrice)

     The program should be debugged now and you should get this:

Enter a price for the oranges
3
Orange price inside function:  3.0
Orange price outside function:  3.0
Orange total:  9.0

     The program has now calculated the price correctly! You see, the user's input didn't exist in the function because it was created after the function. I know, still confusing, but that's the best explanation I can think of. But with the global keyword, the function knew there was a variable somewhere in the program it needed to use. This can be very useful when you need to use something in a function and somewhere else!

     That's just about it for this article. I challenge you to edit the program so it takes several different prices inputted by the user!

Thursday, July 11, 2013

Local

     Can the functions only have 1 argument? The answer is no. You can have as many as you want! You simply do this:

>>> def randomwords(randomword, otherRandomWord):
print(randomword)
print(otherRandomWord)
print("CHEESE")

>>> randomwords("Pickles", "Cow")
Pickles
Cow
CHEESE


     Remember to do the values in order! Otherwise they will be switched around.
     That was only 2 arguments, but that's not all you can do. You can do over 9,000 arguments (if you have the patience, not to mention time, to do that) if you want to. Although... If you want to do at least five or six arguments, you might want to think of doing a list instead of a bunch of variables.

     It's possible for a function to return things to us. It's called a result.
     In order to get results, you use the return function. Try this:

>>> def groceries(oranges):
            orangeCost=9
            orangeTotal=orangeCost * oranges
            return oranges

>>> groceries(3)
27
>>> groceries(8)
72
>>> groceries(19)
171
>>> groceries(9001)
81009

     So, our block of code used the parameter (or argument) to figure something out, then gave us what it figured. That's how the return function works. If you want to do stuff with the return value, you can simply call it inside a variable.
     orangeCost, oranges, and orangeTotal are all in the same block of code. The same line, even. Being variables, these are called local variables.
     Local variables only exist while the function is running. Try printing each variable:

>>> print(orangeCost)
Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    print(orangeCost)
NameError: name 'orangeCost' is not defined
>>> print(orangeTotal)
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    print(orangeTotal)
NameError: name 'orangeTotal' is not defined
>>> print(oranges)
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    print(oranges)
NameError: name 'oranges' is not defined

     Right. That's what a local variable is. If a variable is in the main part of a program, and not in a function, that is called a global variable.
     We will continue global variables in the next article. See you next time!

Thursday, July 4, 2013

Def and Arguments

     Hopefully you still have the list from the last article, because we're doing a bit more with it!
     Alright, we have a list of lists here named traits. What if we want an item inside an item of the list? Okay, lemme just explain what I said, if you find it a bit too confusing; We have 3 lists in a list. What if we want a single item from 1 of those lists? We know that we can get an entire list (because each list is an item in traits) like this;

>>> print(traits[0])

['Blue', 'No', 'Yes', 'No']

     But what if we want only one of those items? Well, we add a second index.

print(traits[0] [3])

No

     There you have it. That's the last thing about tables I have to talk about, so let's move on to the next thing:  def.

     Def basically skips a block of code. You use it before a variable, just like for and while loops. Write this:

>>> def randomwords():
print("Hi")
print("Pears")
print("CHEESE")


>>> randomwords()
Hi
Pears
CHEESE

     We'll get to why there are parenthesis after randomwords in a second. When we used def, it skipped the entire block of code and did nothing. Doing this allowed us to activate the block whenever we wanted, just by repeating the variable after def. Of course we didn't type the colon (:), because that's not part of the variable. It tells Python you are making a block of code.
     Alright, now why are the parenthesis there? Well, without the parenthesis, you wouldn't be able to call (or activate) the block of code, because Python doesn't understand you if you just typed "randomwords." Python wouldn't know whether it's a string or an integer or anything, so you get an error. With the parenthesis, Python knows you're calling for the block of code and activates it. Also, as always, we might put things in parenthesis.
     A good thing about the def function is that you can print it over and over as many times as you like, like a loop. However, instead of printing it several times at once, you can print it anywhere you want in the program. But, that's not what we're focusing on in this paragraph. That statement set aside... What can we put in the parenthesis? A little something I like to call (okay, everyone calls it this), arguments!
     Not arguments like two people disagreeing, computers never argue. In programming, argument means a piece of information you give to a function. If you don't want a def function to be the same every time you activate it, you put an argument in the parenthesis. Arguments are variables, so you can call them whatever you want.
     Arguments are tricky to understand unless you get an example with a program. I'll change the first print statement in randomwords to an argument named randomword. Here's my example:

>>> def randomwords(randomword):
print(randomword)
print("Pears")
print("CHEESE")


>>> randomwords("Pie")
Pie
Pears
CHEESE

     When you put a variable in the parenthesis, then somewhere in your block of code, you can change that variable to something every time you call it. Pretty neat, huh? That way you don't have to print the same thing (with something slightly changed, of course) over and over again.
     In this article, you learned about def and arguments. What programs can you make now with you knowledge? After we get through all the functions, objects, and modules, we will be moving onto making our own computer games! But for now, bye!
     Oh, I almost forgot, happy 4th of July!

Wednesday, July 3, 2013

Mutable, Immutable, and Tables

     If I haven't mentioned this already, it's impossible to change numbers and strings. Not unless a variable (or name) is assigned to them. With lists, you can change whatever's in it. Appending, deleting, sorting, reversing, all that stuff. These things are called mutable and immutable.
     Mutable means something can be changed. It is "changeable." Immutable means it can't be changed.
     Is there such a thing as an immutable list? Yes there is. It's called a tuple. Type this in Python IDLE:

tuple1=("Apples", "Bananas", "Watermelon")

     Instead of square brackets ([]), we used parenthesis (()). Once you make this list, you can't change it. Well, you could change it if you write it in a program, but that's not the point. You can't append, pop, delete, extend, insert, sort, reverse, or any of those things you can do with a normal list. This is an immutable list.



     It's useful to visualize how data is stored in a program.

     A variable has a single value.         person --> 'Bob'
     A list is like a bunch of values assigned to one variable. family --> 'Jack', 'Tim', 'Mom', 'Dad', 'Willy', 'Betty'
     Sometimes you need to make a table, a chart with rows and columns.
     traits --> Eye color   Widow's peak   Freckles   Left handed
     Jack      | Blue         | No                  | Yes        | No
     Tim       | Green       | No                  | No         | Yes
     Willy     | Blue         | Yes                  | No        | No

     Wait, what? A table? In order to do that, we make a series of lists.
     We could make a list of traits for each person, like so:

>>> jackTraits=['Blue', 'No', 'Yes', 'No']
>>> timTraits=['Green', 'No', 'No', 'Yes']
>>> willyTraits=['Blue', 'Yes', 'No', 'No']

     Or we could organize the table in columns, like this:

>>> eyeColor=['Blue', 'Green', 'Blue']
>>> widowsPeak=['No', 'No', 'Yes']
>>> freckles=['Yes', 'No', 'No']
>>> leftHanded=['No', 'Yes', 'No']

     We might want to collect this data together in a little something called a data structure.
     I'll be using the rows, just so you know. It doesn't really make a difference, except the layout will be different in the end. First, let's make another list.

traits=[jackTraits, timTraits, willyTraits]
print(traits)

[['Blue', 'No', 'Yes', 'No'], ['Green', 'No', 'No', 'Yes'], ['Blue', 'Yes', 'No', 'No']]

     That is a list of lists. Each item in the list is a list itself. Now, to display it in a table...

for allTraits in traits:
    print(allTraits)

['Blue', 'No', 'Yes', 'No']
['Green', 'No', 'No', 'Yes']
['Blue', 'Yes', 'No', 'No']

     There we go. Doesn't quite look like a table, but it helps to visualize it like one.
     This article is getting a bit too long! Keep those lists ready, because we'll continue this in the next one!