Python tips colecting thread

I thought it would be helpfull to create a Tip topic, so that new and old members can look it up, and if they want share with others.

I have come across a few things that i thought why are you doing that, so here are 4 tips to use when writing python.

Tip 1:

import bge

You don’t need to import the whole bge, you can also import the parts from bge that you going to use.

from bge import logic

This saves you allot of writing because this:

cont = bge.logic.getCurrentController()

will become this:

cont = logic.getCurrentController()

So you don’t need to use bge. anymore.

Tip 2:

def main():

    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    print(own)


main()

In my opinion this is not the way you work, if you using functions then use the python->module brick aswell
so you can remove the main() at the bottom, and in the brick you put in the name-of-the-script.main to run that part of code(youre scipt needs to end as .py in order to work).

Tip 3:

def main():

    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    print(own)



(removed the main() at bottom), this script can be shorter and easier (less writing)

def main(cont):    own = cont.owner
    
    print(own)

Cont or controller is already build in the function.
This means you dont have to write it every time, you simply place cont in main().
Now we can use cont as our controller instead of writing:

 cont = bge.logic.getCurrentController()

Tip 4:
Now that you use functions, you can create more functions in the same script and use it. like 1 function prints the owner and the other one prints a line of text.

def print_owner(cont):    own = cont.owner
    
    print(own)
    
def some_text():
    
    print('some text to print into the console.')

in this case you can run 2 python->module bricks, 1 for print_ower and 1 for some_text.

Another thing you can do is send information from 1 function to an other function like this:

def print_owner(cont):
    own = cont.owner
    some_text(own)
    
def some_text(own):
    print(own)

we got print_owner who sends own to an other function some_text and that function prints the own.
This way you can let the functions work together and make your code even shorter.

Please be aware, a module is a python file… the complete file. You are talking about a module function. Functions define ( yes, that’s why it is called “def”) a sequence of operations. Functions do not “send” something from one function to another. What you did was “calling” one function by another. This calling is an operation and fits into the sequence of operations of the calling function. While calling a function you can pass parameters from the calling function to the called function and you can pass one parameter back to the caller. Be aware a function can call itself. That is known as “recursion”.

Here are my tips:
Think before you type!

Think about what you really want to achieve. Give it a name that expresses your wishes. Keeping your wish in your head has no use, because you will forget and others will not read your mind. Telling them will help you and others to get the idea what your code is supposed to do (… this is not necessary what the code is really doing ;)).

I really recommend to skip the (in my eyes) stupid idea that cryptic naming is a sign of professionalism. It is the opposite. A good programmer does not invent abbreviations. They add confusion to the code. You have a computer with a lot of utilities to help writing code. You do not to write SMS that only a handful of people can understand. Creating short code is nice … as long as it is understandable language (slang is no language).

Example:
You can find the word “controller” in an English dictionary. I’m not sure if “cont” is something that expresses what you think it is. (I know this is used a lot in this forum … does that makes it an English word?)

This does not mean that abbrevations should not be used at all. If it is easy to see what is meant (e.g. you do not need to scroll to see where a variable is set) you can use a short variable. Be aware this can quickly create ambiguous names.

E.g. s=scene, s=sensor, o=owner, o=object, l=logic, l=line

Expressing your wishes has another advantage: abstraction.

This means you call a function that does not exist at that time. Indeed you can’t run thst code at that time. This is no problem, as you are creating the code at that time anyway. But you can now stay at the same level of abstraction, while you can care the lower abstraction (higher details) at a later time. E.g.
goToNextWaypoint:

  1. findNextWaypoint
  2. turn to waypoint
  3. go straight foward
  4. continue with 2) unless you reached the waypoint

At this stage you express how you want to go to the next waypoint. You do not get lost in the details, how to find the next waypoint, how to turn or how to go… You can care this details later. Now you can focus on the higher abstraction. Later you can implement the lower abstraction details. You can even replace them with other solutions without effecting the higher levels.

I know this sounds strange and like lot of overhead. But it is worth.
I hope this helps a bit.

nice little trix.

target.worldPosition-own.worldPosition == Vector to target ==own.getVectorToTarget(target)[1]


Diff = target.worldPosition-own.worldPosition
Diff.magnitude = Distance between objects

Rot=own.worldOrientation.to_euler()

Rot.x += an offset

own.worldOrientation=Rot

is better then own.applyRotation because own.applyRotation does not update the orientation matrix until after the script is done as far as I can tell.

last tip, the steering actuators facing math is kinda wonkey, instead use

LinV = own.localLinearVelcocity.copy()
LinV.z*=0
offset = own.worldOrientation*LinV
own.alignAxisToVect(offset,axis,time)

Attachments

NavSeeker.blend (501 KB)

Please be aware, a module is a python file… the complete file. You are talking about a module function. Functions define ( yes, that’s why it is called “def”) a sequence of operations. Functions do not “send” something from one function to another. What you did was “calling” one function by another. This calling is an operation and fits into the sequence of operations of the calling function. While calling a function you can pass parameters from the calling function to the called function and you can pass one parameter back to the caller. Be aware a function can call itself. That is known as “recursion”.

Yes, that’s true their called functions, but you can also see it as a module (a container for some code) you can even call it containers.
But lets keep it at functions (only used module because you gonna use the module option of the python brick, so the name makes a link already) but i have corrected that and now it’s called functions.

Also you say you can send 1 parameter. Anyway you can ofcourse send more then 1.

def coding():    appels = 1
    beer = 2 
    cake = 4


    result(appels, beer, cake)


def result(appels, beer, cake):
    print(appels, beer, cake)

this will print 1 2 4

you can also make a list type to have one parameter ( i call them variables) to contain more information (variables) like this:

def coding():    info = 1,2,4


    result(info)

in this case you send the same amount(3) into one variable info, and there are a few ways to read it in an other funtion like:

def result(info):    
    appels, beer, cake = info
    
    print(appels)

or you can tell the list type what information to get out of info by doing

def result(info):    
    print(info)    #prints (1,2,4)
    print(info[0]) #prints 1
    print(info[1]) #prints 2
    print(info[2]) #prints 4

To return information you can call the function from a variable and that variable gets the returned information like

def coding():    info = 2, 3, 4


    appel = result(info) #create variable appel, and call funtion result and send info to it.
    
    print(appel) #prints the returned information, 2 in this case


def result(info):
    
    appels, beer, cake = info
    
    return appels #here we return appels to the coding function

A game object’s properties can any python object type – not just the types it provides you in the editor (int, float, string, bool, etc).
A property can hold a reference to a list, dictionary, tuple, class, or another GameObject.


from bge import logic

class Apple:
    def __init__(self, color):
        self.color = color
    def main(self):
        print(self.color)

own = logic.getCurrentController().owner

if 'fruit' not in own:
    own['fruit'] = Apple('red')
else:
    own['fruit'].main()

if G_key_pressed():    #a phony method to check for keypress G
    own['fruit'].color = "green"

This will look for the property ‘fruit’ (which isn’t defined in the editor), and creates it when it doesn’t find it – defining it as a reference to an instance of the Apple class. If it doesn’t not find it (double-negative intended), it calls fruit’s .main() method, which will start printing out rows of ‘red’ into the console. If the user presses the G key at any time, it will start spitting out ‘green’.

This seems to be the most common, straight-forward, and least ‘magical’ way to associate game objects (cubes, cameras, lamps) with python objects (namely classes).

this depend from the context
typically inside a loop are absolutely good.

enemies = [i for i in scene.objects if “enemy” in i]

“enemies” is used later, need of more readibility (differently from “i”)
extraverbosity also make the code hard to read

plus, not ever one know what is this “stuff”
ie, not ever simple give name right (and a name wrong is also worse than “stuff”)