# Python (civ4 scripting language) tutorial thread

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

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

#make sure every menu entry is unique otherwise it
#will show the index of the first entry it appears in
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'] = \

#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\
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'] = \
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

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. ### croxisChat room op

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

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. ### MSTKDeity

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

6. ### JurimaxDuke 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. ### JurimaxDuke 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

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

Greetz Jurimax

8. ### Blackbird_SR-71Spying from 85,000 ft

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

9. ### LicentiaPrince

Joined:
Mar 12, 2002
Messages:
328
Location:
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-71Spying 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. ### LicentiaPrince

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

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.

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!!!

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)

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

>>> 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()

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,

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. ### bgart5Chieftain

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.

Joined:
May 25, 2004
Messages:
1,177
Location:
Centreville

18. ### KuningasDeity

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

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 ShaferCivilization 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.