What is a Turtle Object? - python

The book i'm reading is called Think Python 2. The author keeps on mentioning objects but i still do not understand what they actually are.... The code reads as follows
import turtle
bob = turtle.Turtle()
print(bob)
turtle.mainloop()
"The turtle module (with a lowercase ’t’) provides a function called Turtle (with an uppercase ’T’) that creates a Turtle object."
So what this means is that the module defined the function Turtle, and when it was defined it created a function object 'Turtle'?
"which we assign to a variable named bob. Printing bob displays something like
turtle.Turtle object at 0xb7bfbf4c
This means that bob refers to an object with type Turtle as defined in module turtle."
I can't understand what is he doing atm... Is he assigning the return value of Turtle()function to a variable called Bob?
And why is bob's type Turtle? Isn't it type function? As when you define a function it creates a function object in this case "Turtle" of type "Function"...
I'm kinda messed up. What am i missing?

# Import the turtle module
import turtle
# Create a variable named bob, assign it a Turtle object which comes from the turtle module
bob = turtle.Turtle()
# Print out the variable bob
print(bob)
# Call a method named mainloop from the turtle package
turtle.mainloop()
Read here for more about what a module is.

An object is sort of like a blueprint for a code-like thing. When the author of the book does
bob = turtle.Turtle()
They are "instantiating" (or creating) a specific version of the Turtle object, which you will refer to as bob. Bob has certain methods you can call on it, which all turtle objects have, but when you do something like.
bob.forward(100)
It will move your specific turtle forward by 100 units.

Related

Some turtle functions not working on new turtle

So i have created a new turtle by doing bassel = turtle.Turtle(), however, some functions such as tracer() and onkeypress() just don't work, I get an error saying 'Turtle' object has no attribute 'tracer' or 'Turtle' object has no attribute 'onkeypress'...
But as soon as I replace bassel by turtle it works
So for instance, bassel.onkeypress() doesn't work ('Turtle' object has no attribute 'onkeypress')
But if I put turtle.onkeypress(), it works perfectly.
Here's some part of the code
bassel = turtle.Turtle()
bassel.tracer(0)
bassel.hideturtle()
Right. Those functions are not attributes of a SPECIFIC turtle object, they are services offered by the turtle module. Just use turtle.tracer and turtle.onkeypress.

How does dot operator relate to Namespaces?

As i was going through python basics and introduction one thing that really confuses me is namespaces. I cant seem to understand how they work.
For instance in Cs50 course they brush over the concept but i wanted to get clearer understanding of it if possible because it seems very important to grasp. For example this code:
import cs50
x = get_int("x: ")
y = get_int("y: ")
print(x + y)
Causes this error:
python calculator.py
Traceback (most recent call last):
File "/workspaces/20377622/calculator.py", line 3, in
x = get_int("x: ")
NameError: name 'get_int' is not defined
What is wonder is why when cs50.get_int() is written instead interpreter doesn't throw an error? Is it because cs50 library is seen as its own namespace structure and . goes into that structure to get_int location? What does . operator do exactly here in terms of namespaces ?
You import cs50, so you have a name "cs50", you can use
cs50.get_int()
but namespaces has no name get_int.
You can use from cs50 import get_int to import name "get_int"
To answer this question, let's talk about modules.
In Python, "module" is used to refer to two things. First, a piece of code, usually a .py file. Second, the object that is created for the namespace of that code when it is run.
When you do import foo, a couple of things happen.
Python checks if foo has already been imported. If so, it skips to the last step.
Python looks up where it can find foo, for example if there is a foo.py in the right place.
Python creates a fresh namespace object and stores a reference to it in sys.modules['foo']
Python runs the code that it found, using that namespace object as its "global" namespace.
Python goes back to the importing module, and adds a global variable foo in the namespace of importing module that points to sys.modules['foo'].
You can then access any global variable bar that was created in the foo.py module by using foo.bar.
You could also use from cs50 import get_int which works like this:
import cs50
get_int = cs50.get_int
... except that the name cs50 is not assigned to.
If you're asking why it works that way: this way different modules can define the same name for classes, functions or constants, and they won't conflict with each other.
Now, if you know you're only using get_int from cs50, and you don't have any other get_int either in your main module or that you imported, the from ... import syntax is very useful to not have to write cs50.get_int every time you want to use it.

Passing variables between two files both ways in python

Okay, so I know this may seem stupid but I am currently making a game using multiple files, one main one that receives all variables from other files and uses them in ways. I'm using the:
from SPRITES import *
to get these variable over, however now I need a variable that can only be defined in MAIN in SPRITES (as the platform the player is standing on is located in main, and this needs to change the controls defined in sprites), however if I just do a
from MAIN import *
this seems to break the connection completely. Help please
EDIT: Okay, currently my file is probs too large to post all code on here but I'll try to post whats relevent on here (first time here). This is the start to the main 'titleMAIN' file
import pygame as pg
import random
from titleSETTING import *
from titleSPRITE import *
cont = ("green")
class Game:
def __init__(self):
# initialize game window, etc
pg.init()
and so on
calling upon the Player class in the SPRITES file from the Game class - I need to be able to use the 'cont' variable in the Player class:
def new(self):
# start a new game
cont = ("green")
...
self.player = Player(self)
self.all_sprites.add(self.player)
And here is where I tried to call upon the MAIN file from the SPRITES file:
from titleSETTING import *
...
class Player(pg.sprite.Sprite):
def __init__(self, game):
Sorry that I was vague, first time here and kinda a novice at coding, no matter how much I enjoy it. BTW by files I mean different python (.py) files in the same folder - using IDLE as an IDE, which sucks but it's what I got
EDIT 2: Thanks for the responses - I realize that it's probably better to just try to make this all one file instead of two, so to not over complicate the code, so I'll work with that mindset now
The main reason this wasn't working for you is that circular imports are problematic. If some file A imports some other file B, then you do not want B to import A (even indirectly, via some other files).
So to make it work, I split main into two.
As an aside, using global variables (and import *) tends to make programs harder to read. Instead of a bunch of globals, consider perhaps a single global that has the values you need as fields. Instead of import *, consider explicit imports (just import sprites, and then sprites.foo).
main.py:
from sprites import *
from config import *
print "Hello from main. main_value is: ", main_value
print "sprite value is: ", sprite_value
do_sprite()
sprites.py:
from config import *
sprite_value=10
def do_sprite():
print "main value is: ", main_value
config.py:
main_value=5
While technically possible (using some obscure Python features), what you're trying to achieve is neither easy, nor actually a good idea.
Note that the fact that you did from moduleX import *, doesn't make the variables defined in moduleX magically available in main (or where-ever you put the import statement). What it does, it creates new variables with the same names in your current module and make them point to the same objects as those in moduleX at the moment when the import is executed. Let's say there's A in some module named X and it was initialized to "foo". You did import * from X and now print(A) will show foo. If you now call a function from X and it changes A to bar, it won't affect what you have in main - that is still the object foo. Likewise, if you do a="baz" in main, functions from X that refer to A will still see X's copy of that variable.
If you need some data to be available to more than one module, it may be best to arrange for all that shared data to be stored in some common object and have an easily-accessible reference to that object in all the modules that need the shared data. Here are possible choices for this object, pick what suits your taste:
it can be a module that's just meant to keep common variables, let's say it is called data or common (have an empty file data.py). Import it everywhere you need to and set variables as data.A = "something" or use them as needed, e.g. print (data.A).
it can be an instance of a class that you define yourself,
e.g.:
class data_class(object):
# set initial values
var1 = 10
A = "foo"
Now, create an instance of it with data = data_class() and pass it to every module that needs it. E.g., define it in one module and import it from everywhere else.
you can also use a Python dictionary (and, like with the class instance, have a reference to it in all modules). You will then refer to your common data items as data["A"], etc.

How to change class object parameters from another module (python)

So I've searched around and couldn't find an answer. I'm looking to change parameters from an object created in my main file, in a module. For example, I'm testing this with a simple piece of code here:
-this is my main file, from which i create the objects and define some properties
import class_test_2
class dog():
name=''
spots=0
def add_spots(self):
self.spots+=1
def main():
fido=dog()
fido.name='Fido'
print('Fido\'s spots: ',fido.spots)
fido.add_spots()
print('Fido\'s spots: ',fido.spots)
class_test_2.class_test()
print('Fido\'s spots: ',fido.spots)
if __name__=='__main__':
main()
-this is the module, from which I want to use functions to change the attributes in the main file
from class_test_1 import dog
def class_test():
fido.add_spots()
-So my question is how can I do this/why doesn't this piece of code above work?
Running the main function on its own shows fido's spots increasing by 1 each time its printed. Running the code calling the module however gives a NameError so my module isn't recognising the class exists even though I've managed to import it. Thanks in advance for any help.
Your variable "fido" is only defined within your "main" function. You must provide your "class_test" function with the variable.
For example:
class_test_2.class_test(fido)
Then your class_test function gets an argument. You can choose the name freely. I used the_dog in the example:
def class_test(the_dog):
the_dog.add_spots()
In this case the_dog points to the same instance of your dog class as fido.

having multiples clasess in a module in a package in Python?

I'm having trouble understanding packages in Python. In particular, is it possible to have multiple classes in a module in a package in Python. For example:
Kitchen/ Top-level package
__init__.py Initialize the package kitchen
Fridge.py module Fridge.py
Food This is a class in module Fridge
Temperature This is another class in module Fridge
Recipe.py
BeefStake This is a class in module Recipe.py
In the __init__.py, the code will be:
from Fridge import Food, Temperature
from Recipe import BeefStake
__all__ = ['Fridge', 'Recipe']
Then I would create an instance of the Temperature class by
from Kitchen import *
f = Food()
T = Temperature()
I tried this, and only making f = Food() works. The other one showed up an error, something like NameError: name 'Temperature' is not defined
If anyone knows if it is possible to have 2 classes like this in a module in a package in Python. If so, what could be the problem in this approach?
The code you showed us won't work for either Food or Temperature. You explicitly put this in Kitchen:
__all__ = ['Fridge', 'Recipe']
This means that, even though you've imported Food and Temperature into Kitchen, you don't re-export them. So, f = Food() will raise a NameError.
If you change this to, say:
__all__ = ['Food', 'Temperature']
Now everything works fine.
My guess is that in your real code, you made one of two mistakes:
Forgot to include Temperature in __all__, just as you did with both Food and Temperature here, or
Had a typo somewhere, e.g., t = temperature() with a lowercase t.
Normally I'd suspect that the first is more likely… but given that you're inconsistent with capitalization, and misspelled BeefSteak, I'd check the second here.
yes,you can have more than 1 class in a module in python

Categories