Python (civ4 scripting language) tutorial thread

Discussion in 'Civ4 - Modding Tutorials & Reference' started by Gingerbread Man, Aug 16, 2004.

  1. Gingerbread Man

    Gingerbread Man Dark Magus

    Joined:
    Jun 9, 2002
    Messages:
    2,078
    Location:
    Ooorstrailier!
    I made a text adventure game! However, I did read ahead a little - I put dictionaries inside dictionaries, which I never said you could do, and I did a bit of error handling. Here is the source code, and attached is the file it is stored in:
    Code:
    #THE BOX
    #Python program by Steven Thurlow
    #Property of the Civfanatics.com forums
    
    #The menu function
    #make sure every menu entry is unique otherwise it
    #will show the index of the first entry it appears in
    def menu(list, question):
        for entry in list:
            print list.index(entry) + 1,
            print ") " + entry
        return input(question) - 1
    
    #The input processing function
    def command(input):
        output = []
        print ""
        text = raw_input(input + " ") + " "
        space = 0
        letter = 0
        count = 0
        while count < len(text):
            if text[count] == " ":
                output.append(text[space:count])
                space = count + 1
            count = count + 1
        end = output[0]
        del output[0]
        output.append(end)
        return output
    
    #Define default actions
    actions = ['touch','listen','look','smell','taste','use','take','goto', 'leave', 'exit']
    
    #Define the objects in the room
    objects = {}
    
    #The space's touch
    objects['touch'] = \
    "In the confined space you find YOURSELF. You feel a cold \n\
    metal ROOF, a rickety FLOOR, a FRONT section, a BACK\n\
    section, and two SIDES."
    
    #The space's listen
    objects['listen'] = \
    "You hear a rumble towards the front of your confines, but it sounds\n\
    distant, so you cannot learn much from it."
    
    #The space's look
    objects['look'] = \
    "you can see absolutely nothing - it is pitch black. You need a \n\
    source of light"
    
    #The space's smell
    objects['smell'] = \
    "You can smell nothing but YOURSELF."
    
    #The space's taste
    objects['taste'] = \
    "A myriad of disgusting flavours are found throughout your confines."
    
    #Quit the game
    objects['exit'] = \
    "You quit the game while still stuck in the confines you found yourself in."
    
    #yourself
    objects['yourself'] = {}
    objects['yourself']['touch'] = \
    "You are (quite obviously) a man. You are also slightly obese."
    objects['yourself']['listen'] = \
    "Normal bodily functions are still occuring."
    objects['yourself']['look'] = \
    "You cannot see yourself."
    objects['yourself']['smell'] = \
    "You reek of ALCOHOL"
    objects['yourself']['taste'] = \
    "You taste like ALCOHOL, with a smidge of jam, with a creamy texture.\n\
    You want more."
    
        #alcohol
    objects['yourself']['alcohol'] = {}
    objects['yourself']['alcohol']['touch'] = \
    "Your shirt appears to be soaked in the alcohol"
    objects['yourself']['alcohol']['listen'] = \
    "Sounds like alcohol, as usual"
    objects['yourself']['alcohol']['look'] = \
    "Remember? You cant see yet!"
    objects['yourself']['alcohol']['smell'] = \
    "The sweet aromas of a 1997 vintage, dry sparkling wine, probably \n\
    grown organically in the Barossa Valley, reminds you of many fine \n\
    days ago."
    objects['yourself']['alcohol']['taste'] = \
    "It wets your dry mouth with the flavours that it's smell suggests."
    
    #roof
    objects['roof'] = {}
    objects['roof']['touch'] = \
    "The roof is of cold metal, with a spot of RUST."
    objects['roof']['listen'] = \
    "The roof seems to be rattling"
    objects['roof']['look'] = \
    "You cannot see the roof."
    objects['roof']['smell'] = \
    "The roof smells a bit damp."
    objects['roof']['taste'] = \
    "Now why would you that?"
    objects['roof']['rust'] = {}
    objects['roof']['rust']['touch'] = \
    "The rust pokes through and water trickles from the hole you made.\n\
    Have a nice drink."
    objects['roof']['rust']['listen'] = \
    "Your ear gets damp rust all over it."
    objects['roof']['rust']['look'] = \
    "You cannot see the roof. You need a soure of light."
    objects['roof']['rust']['smell'] = \
    "The rust smells damp."
    objects['roof']['rust']['taste'] = \
    "Mmmm, precious, filthy, water!"
    
    #floor
    objects['floor'] = {}
    objects['floor']['touch'] = \
    "The floor is covered in CARPET. Not much else makes sense at the\n\
    moment"
    objects['floor']['listen'] = \
    "The floor has a rumble to it."
    objects['floor']['look'] = \
    "It is pitch black. You cannot see the floor."
    objects['floor']['smell'] = \
    "The floor smells of your own odour."
    objects['floor']['taste'] = \
    "That was stupid. Why did you do that?"
        #carpet
    objects['floor']['carpet'] = {}
    objects['floor']['carpet']['touch'] = \
    "The carpet is of synthetic material. It is very worn, and could be\n\
    peeled back if you were able to manouvre inside the space you are in."
    objects['floor']['carpet']['listen'] = \
    "The carpet prickles your ears as you try to listen to it."
    objects['floor']['carpet']['look'] = \
    "If you haven't realised by now, it is pitch black. You cannot see!"
    objects['floor']['carpet']['smell'] = \
    "The carpet smells musty and old."
    objects['floor']['carpet']['taste'] = \
    "You lick the carpet, and feel it pricle your tounge. ouch!"
    
    #front
    objects['front'] = {}
    objects['front']['touch'] = \
    "The front consists of two PANELS"
    objects['front']['listen'] = \
    "You can attach no sound related to the front section."
    objects['front']['look'] = \
    "Gee, you are dull. It is pitch black, and you cannot see."
    objects['front']['smell'] = \
    "You can smell something through a gap in the front section, but you\n\
    can't narrow it down."
    objects['front']['taste'] = \
    "I expected more from you. You lick the front, and taste your own\n\
    stupidity."
        #panels
    objects['front']['panels'] = {}
    objects['front']['panels']['touch'] = \
    "The panels move quite a bit, but would require a strong force to\n\
    to dislodge them."
    objects['front']['panels']['listen'] = \
    "Your futile efforts of listening to an inanimate panel prove, rather,\n\
    futile."
    objects['front']['panels']['look'] = \
    "Maybe you should open your eyes and see that it is pitch black inside\n\
    your confines."
    objects['front']['panels']['smell'] = \
    "The panels smell like the panels they are."
    objects['front']['panels']['taste'] = \
    "What is your obsession with tasting unusual objects?"
    
    #back
    objects['back'] = {}
    objects['back']['touch'] = \
    "The back is of cold metal. There are WIRES running out from each\n\
    corner"
    objects['back']['listen'] = \
    "Apart from a whir of air and the occasional thump, You do not hear\n\
    much from the back"
    objects['back']['look'] = \
    "How much of a dimwit are you? You cannot see, it is too dark."
    objects['back']['smell'] = \
    "You attach no smell with the back."
    objects['back']['taste'] = \
    "It doesn't taste very nice. A little like cold metal, you could say."
        #wires
    objects['back']['wires'] = {}
    objects['back']['wires']['touch'] = \
    "The wires in each corner seem to attach to GLOBEs of some sort,\n\
    which are built into the back wall."
    objects['back']['wires']['listen'] = \
    "It is a little hard to listen to electricity, but you still try.\n\
    and fail."
    objects['back']['wires']['look'] = \
    "You cannot see the wires."
    objects['back']['wires']['smell'] = \
    "You can smell the plastic insullation on the wires."
    objects['back']['wires']['taste'] = \
    "Your tounge gets a nasty zap when you press the wires to them."
    
    #sides
    objects['sides'] = {}
    objects['sides']['touch'] = \
    "There is nothing interesting about the sides of your confines."
    objects['sides']['listen'] = \
    "You feel a low rumble."
    objects['sides']['look'] = \
    "You cannot see."
    objects['sides']['smell'] = \
    "The sides smell strongly of oil. You can't tell by the smell, what\n\
    type it is."
    objects['sides']['taste'] = \
    "The sides taste of engine oil. Your tounge feels awful now."
    
    
    #Introduction
    print \
    "Welcome to 'The Box', a text adventure game written in Python by\n\
    Steven Thurlow.\n\n\
                *    *    *    *    *\n\
    You don't know how, you don't know why, but you wake up, and find\n\
    yourself confined inside a box of some sort. The aim is to find\n\
    out where you are.\n\n\
    You can make the following commands, to any of the objects you see,\n\
    or just type them in for a generic description of the area:\n\
    touch\n\
    listen\n\
    look\n\
    smell\n\
    taste\n\n\
    You may also type exit at any time, by typing \'exit\'.\n\n\
    This game is still in development, and as such is a little difficult\n\
    to use. It understands context now, however. The context is whatever\n\
    information was posted last."
    location = objects
    loop = 1
    lastinput = []
    while loop == 1:
        noprint = 0
        location = objects
        input = command(">")
        if input [-1] not in actions:
            print "Sorry, I don't understand the command \'" + input[-1] + "\'."
            continue
        if input[0] == "exit":
            print objects['exit']
            loop = 0
            noprint = 1
            break
        newcommand = lastinput
        for word in input:
            newcommand.append(word)
        if len(input) <= 1:
            newcommand = input
        try:
            for entry in newcommand:
                location = location[entry]
        except:
            for entry in input:
                try:
                    location = location[entry]
                except:
                    print "Sorry, I don't recognise the object \'" + entry + "\'."
                    noprint = 1
                    break
        if noprint == 0:
            print location
        lastinput = input[:-1]
    
    
    WAH???? - You may say this. I'll be writing an explaination to the entire program, in the hope that you can glean some info from the program.

    box.txt is the program. To run it:
    1) go to the command prompt (a.k.a. MSDOS) of your computer
    2) Type in cd C:\Path\to\where\you\saved\the\file\
    3) Type in python box.txt

    There are many bugs with it, but nothing that will cause problems. The only real problem is that it may have problems figuring out what you are referring to. As a general guide -
    1) mess around.
    2) Type 'smell', 'taste', 'touch', 'look', or 'listen' in order to do those things to the place you have just found yourself in.
    Lets just say when you typed 'touch' it printed:
    Code:
    In the confined space you find YOURSELF. You feel a cold
    metal ROOF, a rickety FLOOR, a FRONT section, a BACK
    section, and two SIDES.
    in order to smell the sides you would type:
    > smell sides
    3) Anything in capitols, is something you can smell, taste, look at, touch or listen to.
    4) type everything in lowercase.
     

    Attached Files:

    • box.txt
      File size:
      8.5 KB
      Views:
      247
  2. Gingerbread Man

    Gingerbread Man Dark Magus

    Joined:
    Jun 9, 2002
    Messages:
    2,078
    Location:
    Ooorstrailier!
    THE EXPLAINATION:
    This is not a lesson. It could help you learn things, though.

    'def menu(list,question):' is where I define the menu function. I don't actually use it anywhere in the program - It's just a leftover from what I started with.

    'def command(input):' is much more interesting. This is the function that turns what command you type in, into the location of the text relating to that command. First, I should tell you how I have structured the text:

    I did everything as dictionaries inside dictionaries. (My technique here would probably make seasoned programmers puke, but hey, I'm learning!). It is structured a little like a tree, where you have the main area, all the game objects in the main area, and smaller objects inside other objects, etc, etc...
    Code:
              MAIN LOCATION
                   |
         |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|
       FLOOR                                  ROOF
         |                                      |
       |^^^^^^^^^^^^^^^|             |^^^^^^^^^^^^^^^^^^^^^^^^|
     CARPET     SOMETHING ELSE     RUST                      HOLE
                                                              |
                           |^^^^^^^^^^^^^^^^^^^|^^^^^^^^^^^^^^^^^^^^^|
                         WATER               WIRES                SOMETHING ELSE
    The 'command()' function turns what you type in, e.g. 'taste carpet floor' into the string ['carpet', 'floor', 'taste']. This is used to find where the info about what you typed in is.

    The mass of text after that is the descriptions of everything you can smell, look, touch, taste or listen. For example, the place where the taste of the carpet on the floor is stored is:
    objects['floor']['carpet']['taste']
    Yes, that is right, a dictionary inside a dictionary inside a dictionary! That is sorted out later.

    After all this is the Introductory text, and the main program:
    the dictionary 'location' is pretty much a narrowed down version of the dictionary 'objects' - the big one you saw above. We can mess around with the dictionary 'location' without changing the dictionary 'objects'.

    lastinput is an array of each of the words you typed in last. It tells the computer what was the last thing you were referring to in the game.

    input = command(">") puts what you type into a list, called input. (Note - the command function puts the first word you typed in, last.)

    Code:
    if input [-1] not in actions:
        print "Sorry, I don't understand the command \'" + input[-1] + "\'."
    The above code is pretty much saying, if you aren't asking to touch, taste, etc... then it doesn't know what you want to do. It then asks you to type something in again.
    Here we are introduced to two new operators (little commands for the computer) - 'continue', and 'break'. They are VERY simple - continue tells the computer to start from the top of the loop you are in again. break tells the computer to leave the loop.

    The 'if input[0] == 'exit':' line is saying that if you type in exit, the program quits.

    'newcommand = lastinput' and the next four lines are just telling the computer what is the last thing you looked at, and so what to refer to when you type something in. e.g. if there were two spots of rust - one on the roof, and the other on the back wall, which spot of rust you are talking about.

    Next learn yet another new thing - error handling. Lets just say you typed in 'smell flfloor' - a minor typo. Now, the computer is trying to find something called 'flfloor' and a smell attached to it. Normally, the program would simply quit, because it cant find an object called 'flfloor'. This is where try: and except: come in.
    What happens, is that the code after try: is executed. If something goes wrong, then it will go to the code after except: and instead of spitting the dummy, try out a new bit of code instead.
    'location = location[entry]' is simply narrowing down what you are referring to. For example, if you were smelling a thumbtack in the carpet, on the floor, it would go;
    Where am I looking? - the floor
    Where am I looking on the floor? - the carpet
    Where am I looking in the carpet? - at the thumbtack
    What am I doing to the thumbtack? - smelling it.

    This way, things can be narrowed down.

    after except: is what the program does if something goes wrong. This mostly deals with a typo. It says that it doesn't know what you are talking about, if you were to type in 'flfloor'.

    The last bit prints what you found, and then records where you are, as a reference point to the last thing you typed in.

    I can very well assume that most of you are baffled. I had to look ahead and learn some extra things in order to do this - until now, everything I had learnt, had been learnt while I was writing the lessons. Never mind - you will catch up in a jiffy!

    Next lesson, we learn classes, then file I/O. Next time I set a programming task for you guys, I'll make it a little more achieveable - I have a feeling this was WAY too hard. My program was a lot more than what you people had to do, but I still feel sorry for pushing things a little too much.

    Thanks all,
    GBM
     
  3. croxis

    croxis Chat room op

    Joined:
    Dec 17, 2001
    Messages:
    3,277
    Location:
    Portland, OR, US
    Done both the lesson and looked at the game
     
  4. Gingerbread Man

    Gingerbread Man Dark Magus

    Joined:
    Jun 9, 2002
    Messages:
    2,078
    Location:
    Ooorstrailier!
    Great to see that the lesson got to some people.

    My computer has been down all week, thanks to me hopelessly trying to get Gentoo Linux to work. This coming week I have exams, but Wednesday should be a good day for me (If I have python re-installed by then). Maybe in a week the lesson on classes will be ready.

    In the meantime, look for some constructive critisisms about the tutorial. I'll soon be putting the entire series so far (and every lesson after it), plus possibly some forums, on a new web server that I have acquired. As such, the lessons need to be of top quality.
     
  5. MSTK

    MSTK Deity

    Joined:
    Dec 30, 2003
    Messages:
    2,154
    is this thing back up?
     
  6. Jurimax

    Jurimax Duke of Flanders

    Joined:
    Jul 1, 2001
    Messages:
    636
    Location:
    Oostrozebeke, Belgium
    I'll join and catch up:

    I know: VB6, VB.NET, C, C++, TurboPascal, a bit of XML, HTML, a bit of VBA and Visual C++
    (all of these have diminshed a bit over the last few years since I learnt them)

    Greetz Jurimax
     
  7. Jurimax

    Jurimax Duke of Flanders

    Joined:
    Jul 1, 2001
    Messages:
    636
    Location:
    Oostrozebeke, Belgium
    Just finished Lesson 1
    Just finished Lesson 2 (BTW, there's a mistake in the code 23%3 should give 2 instead of 1)
    Just finished Lesson 3
    --> rest will follow later

    [will update this post until I'm up with the group]

    Greetz Jurimax
     
  8. Blackbird_SR-71

    Blackbird_SR-71 Spying from 85,000 ft

    Joined:
    May 25, 2004
    Messages:
    1,177
    Location:
    Centreville
    when will the next lesson be
     
  9. Licentia

    Licentia Prince

    Joined:
    Mar 12, 2002
    Messages:
    328
    Location:
    Chilliwack BC Canada
    Python seems alot like QuickBasic so far in that the commands are all very similar. I'm already in the process of learning it. The QuickBasic 7.1 compiler is so easy to work with, but it's an outdated language. I've never moded a game before. Don't really use mods either... Maybe i'll start if it's easy.

    Thanks for this. I hope you can keep the tutorials up. Maybe people can post other tutorials here and we can all work together to get good at this.

    Learning to program is an awesome payoff, because there is nothing you can't make your computer do. It feels really good when you finally finish a program. Try it!
     
  10. Blackbird_SR-71

    Blackbird_SR-71 Spying from 85,000 ft

    Joined:
    May 25, 2004
    Messages:
    1,177
    Location:
    Centreville
    QuickBasic i believe was a scripting langauge like Python was so i can see were their synatix appears similar. and also the other part i agree with a 100%
     
  11. Licentia

    Licentia Prince

    Joined:
    Mar 12, 2002
    Messages:
    328
    Location:
    Chilliwack BC Canada
    I don't know whether or not it was a scripting language, but obviously the Python creator programmed in Basic alot in the past.
     
  12. Gingerbread Man

    Gingerbread Man Dark Magus

    Joined:
    Jun 9, 2002
    Messages:
    2,078
    Location:
    Ooorstrailier!
    This tutorial is still alive, I have nearly finished the lesson on classes.

    There have been many delays in the last two weeks, but I've managed to almost complete it. This lesson though, I'd like somebody proficient in python to check it out, and make sure I haven't made some blaring mistakes.
     
  13. Gingerbread Man

    Gingerbread Man Dark Magus

    Joined:
    Jun 9, 2002
    Messages:
    2,078
    Location:
    Ooorstrailier!
    LESSON 8
    Let the Classes begin!

    ## One thing that you will get to know about programming, is that
    ## programmers like to be lazy. If something has been done before, why
    ## should you do it again?

    That is what functions cover in python. You've already had your code do something special. Now you want to do it again. You put that special code into a function, and re-use it for all it is worth. You can refer to a function anywhere in your code, and the computer will always know what you are talking about. Handy, eh?

    This is much unlike a variable. A variable from one function vannot be seen by another function. If there is a variable in the main program, a function cannot see it - the only thing you can do is pass the value inside the variable to a function (in the parentheses after the function name). This poses a problem - certain functions and variables are related to each other very closely, and need to interact with each other a lot. For example, imagine you have a golf club. It has information about it (i.e. variables) like the length of the shaft, the material of the grip, and the material of the head. It also has functions associated with it, like the function of swinging your golf club, or the function of breaking it in pure frustration. For those functions, you need to know the variables of the shaft length, head material, etc...

    That can easily be done with just functions. Variables affect the effect of a function. But what if a function needs to affect variables? What happens if each time you use your golf club, the shaft gets weaker, the grip on the handle wears away a little, you get that little more frustrated, and a new scratch is formed on the head of the club? A function cannot do that. What is needed is a way to group functions and variables into one place so that they can interact with each other.

    This is a problem that a thing called classes fixes. It puts functions and variables together in a way that they can see each other and work together.

    Continued next post - at 15484 characters, this is the longest lesson yet!!!
     
  14. Gingerbread Man

    Gingerbread Man Dark Magus

    Joined:
    Jun 9, 2002
    Messages:
    2,078
    Location:
    Ooorstrailier!
    CREATING & USING A CLASS
    So how do you make these so-called 'classes'? very easily, with the class operator:
    Code:
    # Defining a class
    class [u]class_name[/u]:
        <statement 1>
        <statement 2>
        <statement 3>
        <etc>
    
    Makes little sense? Thats ok, here is an example, that creates the definition of a Shape:
    Code:
    #An example of a class
    class Shape:
        def __init__(self,x,y):
            self.x = x
            self.y = y
        description = "This shape has not been described yet"
        author = "Nobody has claimed to make this shape yet"
        def area(self):
            return self.x * self.y
        def perimeter(self):
            return 2 * self.x + 2 * self.y
        def describe(self,text):
            self.description = text
        def authorName(self,text):
            self.author = text
        def scaleSize(self,scale):
            self.x = self.x * scale
    	self.y = self.y * scale
    
    What you have created is a description of a shape (That is, the variables) and what operations you can do with the shape (That is, the fuctions). This is very important - YOU HAVE NOT MADE A SHAPE, SIMPLY THE DESCRIPTION OF WHAT A SHAPE IS. The shape has a width (x), a height (y), and an area and perimeter (area(self) and perimeter(self)). No code is run when you define a class - you are simply making functions and variables.

    Shape is the name of the class. As a general convention (not a rule, but most people do it) class names start with a capital letter.

    def __init__(self,width,height): is the function that is run when the class is created. You'll see it in use when we create a shape.

    self is where everything in a class is stored. Anything created on the first level of indentation (that is, lines of code that start one TAB to the right of the first letter in 'class') are automatically put in self - functions, variables, the lot. The following things (attributes) in Shape are in the first level of indentation:
    Functions:
    1) __init__
    2) area
    3) perimeter
    4) describe
    5) authorName
    6) scaleSize

    Variables:
    1) description
    2) author

    These are automatically put in self. To access or add something to self while not in the first level, use this:
    Code:
    self.[u]Attribute_name[/u]
    
    and use it like a normal function or variable.

    When we create a function inside a class, the first parameter (The things inside the parentheses) of the function is always self. This is just another little convention, and is just saying that we are passing all the values inside self to the function, so that we can view them, use them, and change them.

    Its all well and good that you can make a class, but how do you use one? Here is an example, of what we call creating an instance of a class:

    Code:
    #Using the Shape class
    
    #First, define the class 'Shape':
    class Shape:
        def __init__(self,x,y):
            self.x = x
            self.y = y
        description = "This shape has not been described yet"
        author = "Nobody has claimed to make this shape yet"
        def area(self):
            return self.x * self.y
        def perimeter(self):
            return 2 * self.x + 2 * self.y
        def describe(self,text):
            self.description = text
        def authorName(self,text):
            self.author = text
        def scaleSize(self,scale):
            self.x = self.x * scale
            self.y = self.y * scale
    
    #creating a rectangle object, from Shape:
    rectangle = Shape(100,45)
    
    #finding the area of your rectange:
    print rectangle.area()
    
    #finding the perimeter of your rectangle:
    print rectangle.perimeter()
    
    #describing the rectangle
    rectangle.describe("A wide rectangle, more than twice\
     as wide as it is tall")
    
    #making the rectangle 50% smaller
    rectangle.scaleSize(0.5)
    
    #re-printing the new area of the rectangle
    print rectangle.area()
    
    This is all really explained in the line 'rectangle = Shape(100,45)'. What we are saying is that 'rectangle' is a 'Shape' class. The stuff in the brackets (that is, 100 and 45) is the values we are passing to the x and y respectively in the __init__ function, which is being run now that we have created a 'Shape'.

    The lines after that are all using things inside the class. I will make it clear that Classes are NOT functions - they don't actually do anything (though they may store things that do something) - they just store functions and variables in one spot.

    LINGO

    I guess it is about time I taught you the lingo of what we are doing.

    When we are creating a class for future use, we call it 'defining a class', just like with defining a function or defining a variable.

    Functions that are inside classes are called 'methods'.

    when we use a class, like in 'rectangle = Shape(100,45)' we are 'initialising' an 'instance' of the class. Initialising, because we using something that we 'defined' earlier on. Instance, because this is one instance of the class being used. There could be many instances of a class being used in our proram.

    An object is an instance of a class. for example, when we say:
    Code:
    fooey = HappyDays(123,"Step on it!")
    
    we are saying fooey is an object. It is an instance of the class HappyDays. (An object can mean many other things in programming, but I won't confuse you too much here)

    When we want to access a method or variable of an instance of a class, we write it in this way:
    Code:
    [i]object[/i].[u]method_or_variable_name[/u]
    [code]
    (an object is an instance of a class)
    for example,
    [code]
    print rectangle.area()
    
    Here are some examples examples:
    Code:
    print rectangle.x
    
    edge = rectangle.perimiter()
    
    #Printing a variable inside a Class
    print ClassName.variablename
    
    #running a function in a class
    ClassName.functionName(parameter1,parameter2,parameter3)
    
    INHERITANCE
    The other thing that classes solve is creating lots of things with slight differences. Just image you are living without classes, and make a function in python for each of your golf clubs - what they look like, what materials they are made of, etc. You would have to create a new function for each golf club, because they are all slightly different.

    Wouldn't it be easier to say "My driver is like a normal club, but with a wide, wooden head and a shaft made of hickory.", or "My 5-Iron is ... (whatever a 5-Iron looks like - I don't play golf...)"? Well, classes take care of that too, with a thing called inheritance, because a driver inherits most of the attributes of a generic golf club, but has some differences. A 5-iron is like a generic golf club, but with certain differences.

    Python does this really easily. To create a new class based on another, 'parent' class, You use this:
    Code:
    class NewClassName(ParentClassName)
        <Additions and Changes>
        <Additions and Changes>
        <More additions and changes>
    
    This is extremely useful. Let's create a square class, based on the Shape class:
    Code:
    # First, define what a shape is
    class Shape:
        def __init__(self,x,y):
            self.x = x
            self.y = y
        description = "This shape has not been described yet"
        author = "Nobody has claimed to make this shape yet"
        def area(self):
            return self.x * self.y
        def perimeter(self):
            return 2 * self.x + 2 * self.y
        def describe(self,text):
            self.description = text
        def authorName(self,text):
            self.author = text
        def scaleSize(self,scale):
            self.x = self.x * scale
            self.y = self.y * scale
    	
    # Now, define a square class, based on the Shape class
    class Square(Shape):
        def __init__(self,x):
            self.x = x
    	self.y = x
    
    As you see, I described a square really quickly. That's because I inherited everything from the shape class, and simply changed what needed to be changed.

    The way it works is everything is brought over from the parent class, in this case Shape. To replace or change a method (a.k.a function in a class) or variable, simply create a new one with the same name (like what we did with __init__). To add something new to your new class, do it as you would a normal class.

    Let's create a class based on the square class. It will be two squares side by side, like what is shown below:
    Code:
     _________
    |    |    |
    |    |    |
    |____|____|
    
    What can we gather from that? The shape will will be created with a width twice the height, and the perimeter will be changed due to the line in the middle. So let's write it:
    Code:
    class DoubleSquare(Square):
        def __init__(self,x):
            self.x = 2 * x
            self.y = x
        def perimeter(self):
            return 2 * self.x + 3 * self.y
    
    Now here's a helpful hint, that you may have forgotten from the 2nd lesson. Do you know how when you run a program in IDLE, it runs in the window titled 'Python Shell'? That's right, the same place that >>> thing is, where you can play around with code. Here's the cool bit - after you run a program, every line you type here, is as if you were running another line of code at the end of your program.

    Run the following program:
    Code:
    class Shape:
        def __init__(self,x,y):
            self.x = x
            self.y = y
        description = "This shape has not been described yet"
        author = "Nobody has claimed to make this shape yet"
        def area(self):
            return self.x * self.y
        def perimeter(self):
            return 2 * self.x + 2 * self.y
        def describe(self,text):
            self.description = text
        def authorName(self,text):
            self.author = text
        def scaleSize(self,scale):
            self.x = self.x * scale
            self.y = self.y * scale
    
    class Square(Shape):
        def __init__(self,x):
            self.x = x
    	self.y = x
    
    class DoubleSquare(Square):
        def __init__(self,x):
            self.x = 2 * x
            self.y = x
        def perimeter(self):
            return 2 * self.x + 3 * self.y
    
    Now, where you see this: >>> try typing in these things:
    Code:
    (after running the program above, type in these lines after the >>>, in the 'Python Shell' window)
    
    >>> LongRectangle = Shape(8,200)
    
    >>> print LongRectangle.area()
    
    >>> print LongRectangle.author
    
    >>> LongRectangle.authorName("Put your name here")
    
    >>> print LongRectangle.author
    
    As you see, you can play around with the last program you ran. play around with the Square and DoubleSquare classes (remember that python is case sensitive, so be careful with capital letters).

    POINTERS
    If you talk to some C programmers, you may hear them whinge about pointers. I personally find them really cool, but nonetheless, pointers are much easier in python than in C.

    What are pointers? Pointers, well, point. They are something that points to another variable or object (remember - an object can be an instance of a class being used). After running the program, run this in the 'Python Shell' window:
    Code:
    # Creating an object (instance of a class)
    >>> smallsquare = Square(3)
    
    #Testing it out
    >>> print smallsquare.area()
    
    # Creating a pointer, from 'abc' to 'smallsquare'
    >>> abc = smallsquare
    
    # Now try it out:
    >>> print abc.area()
    
    # Try changing things:
    >>> abc.authorName("Sherry Bobbins")
    
    >>> print smallsquare.author
    # You'll see the author name you just typed in, here
    >>> print abc.author
    # Again, the same thing - because abc [i]points[/i] to smallsquare
    
    Pretty cool, eh? There's probably a lot of ways you could use this, but I'll leave that up to your imagination.

    CLASSES IN DICTIONARIES
    Another cool thing you can do with classes is put them in a dictionary. This is useful for when you don't know how many instances of a class you'll need when you make the program. For example, say you want a user to be able to create as many shapes as they please, and give them all a name. The user needs to search the list of names to find a certain shape. You can't do this normally, but with a dictionary you can:
    Code:
    # Again, assume the definitions on Shape, Square and DoubleSquare have been run.
    # First, create a dictionary:
    dictionary = {}
    
    # Then, create some instances of classes in the dictionary:
    dictionary["DoubleSquare 1"] = DoubleSquare(5)
    dictionary["long rectangle"] = Shape(600,45)
    
    #You can now use them like a normal class:
    print dictionary["long rectangle"].area()
    
    dictionary["DoubleSquare 1"].authorName("The Gingerbread Man")
    print dictionary["DoubleSquare 1"].author
    
    As you see, it is pretty cool to be able to create any number of class instances. Or maybe I am just easily entertained...

    You can also put classes in lists. You can put those lists through a 'for' loop, and do all kinds of fancy stuff, but I won't touch on that now.

    And that is the lesson on classes! You won't believe how long it took me to write this in a clear-cut manner, and I am still not completely satisfied. Especially to you proffesional programmers out there, help me with the lingo - all the different things an 'object' can be, whether an attribute is any function or variable in a class, or only a variable, etc. I've probably confused some of you with the lingo in my own confusion, but remember - it is not the name that is important, but what it does (this doesn't work in a social setting, believe me... ;)).

    Thanks to all,
    Gingerbread Man
     
  15. Gingerbread Man

    Gingerbread Man Dark Magus

    Joined:
    Jun 9, 2002
    Messages:
    2,078
    Location:
    Ooorstrailier!
    I want to contact Firaxis to see if they can give me some details on how they will be implementing python and XML for civIV (for example, any modules or libraries, specific XML tags, etc.) It would be really useful if I could get on the beta testing team, but I have a feeling that will be a while off. Does anybody know who I should talk to?
     
  16. bgart5

    bgart5 Chieftain

    Joined:
    Nov 21, 2004
    Messages:
    7
    Python rules. Though I don't know a lot, I am really excited about the prospect of using it to mod.
     
  17. Blackbird_SR-71

    Blackbird_SR-71 Spying from 85,000 ft

    Joined:
    May 25, 2004
    Messages:
    1,177
    Location:
    Centreville
    did you already contact them? maybe ask old Sid ;)
     
  18. Kuningas

    Kuningas Deity

    Joined:
    Aug 15, 2003
    Messages:
    2,092
    I know some Java, Delphi, Visual basic, Visual c++ etc. But I haven't any interest left for those because I really dislike classes.

    Lessons:
    Lesson1: in progress
    Lesson2: in progress
    Lesson3: in progress
    Lesson4: in progress
    Lesson5: in progress
    Lesson6: in progress
    Lesson7: in progress
    Lesson8: in progress
    I'll update the post as I go forward.

    Original BitTorrent client were programmed with python, that language indeed is interesting :D
     
  19. Gingerbread Man

    Gingerbread Man Dark Magus

    Joined:
    Jun 9, 2002
    Messages:
    2,078
    Location:
    Ooorstrailier!
    Don't like classes? Well, python uses them pretty extensively. Maybe lesson 8 may make it easier.

    As for talking to good ol' sid - how??? I'm sure Soren from firaxis or somebody over there could halp me, but how to contact them?
     
  20. Jon Shafer

    Jon Shafer Civilization 5 Designer

    Joined:
    Jul 14, 2002
    Messages:
    2,102
    Location:
    Maryland
    Yes, classes are integral in learning how to program.

    If you don't use classes, you might as well not program in this day and age. Everything is about OOB.
     

Share This Page