NameError when using "self" in class? - python

I have the following Python (3.2) code:
from pygame import *
class Application:
def __init__(self):
self.running = True
self.display_surface = None
self.size = self.width, self.height = 640, 480
self.old_ticks = pygame.time.get_ticks
self.new_ticks = None
pygame.init()
self.display_surface = pygame.display.set_mode(self.size, pygame.HWSURFACE | pygame.DOUBLEBUF)
def on_event(self, event):
if event.type == pygame.QUIT:
self.running = False
def on_loop(self):
pass
def on_render(self):
pass
def on_cleanup(self):
pygame.quit()
def regulate_time(self):
self.new_ticks = pygame.time.get_ticks
while (self.new_ticks < self.old_ticks + 1000):
pass
self.old_ticks = self.new_ticks
def load_images(self):
pass
while(self.running == True):
for event in pygame.event.get():
self.on_event(event)
self.regulate_time
self.on_loop()
self.on_render()
self.on_cleanup()
test = Application
I'm having a problem with the following line:
while(self.running == True):
which throws me the error : NameError: Name "self" is not defined.
I am pretty much a python newbie and was hoping to use this time to get started on learning python and pygame which I could then use for my college project (two birds with one stone) and I cannot figure out why this error is being thrown at me.

Well, the while(self.running == True) is not in any method (def) so there is no such variable called self in scope (which is what the NameError says)...
...perhaps there is some missing indentation? Although the previous pass makes it look like more than this is missing: maybe def run(self):?
Remember, self is just the conventional (and proper) name given to the first parameter for a method by which the "current instance" is implicitly passed.
Happy coding.

Related

Python set class variable after calling

I'm making a game using the pygame module and I have a player class:
class Player(pygame.sprite.Sprite):
def __init__(self, name, position, axsis, movment, idle, walk = None, jump = None):
pygame.sprite.Sprite.__init__(self)
self.name = name
self.idle = idle
self.walk = walk
self.jump = jump
self.image = self.idle[0]
self.movment = movment
self.left, self.right = axsis
self.pos = vec(position[0],position[1])
I am adding my characters using json data type and trying to add animations after calling the class but i can't do it
Sample code
class Game():
def __init__(self,json_file):
self.player_attribute = json_file
def character(self):
self.npc = []
for i in self.player_attribute:
self.npc.append(Player(i['name'],
i['position'],
i['axsis'],
i['movment']))
self.animation()
return self.npc
def add_animation(self):
for i in self.npc:
i.idle = "images\ghost.png"
def main_loop()
self.character
when i try this i get an error
self.image = self.idle[0]
TypeError: init() missing 1 required positional argument: 'idle'
how can i add the variables of the class after calling the class
It is not clear what the 'idle' parameter is supposed to represent in your code. However, the reason for the exception is that you are not passing any argument for 'idle' when constructing the Player object. You need something like:
self.npc.append(Player(i['name'],
i['position'],
i['axsis'],
i['movment'],
i['idle']))
You can either do that or alternatively you can pass a default argument to the Player constructor so that, when initializing you do not need to explicitly pass idle:
class Player(pygame.sprite.Sprite):
def __init__(self, name, position, axsis, movment, idle=[1], walk = None, jump = None):
You can modify its content at a later time, however I suggest you are careful what you instantiate that object attribute as, because it might come bite you back later (type error or value error).
If it were me, I would move this out of init, or not build the object until all values and their types are known (see Builder Design Pattern).
Hope this helped :) Cheers!

Object has no attribute - Python OOP

This is my code that I can't get to work. It is saying that my object doesn't have a score attribute when I try to get the player1 and player2 score with player1.score. I checked for indenting errors and couldn't find any. I am not sure why the score is missing as I have given it self. I brought in the class object with player1 = Player(PLAYER1, 1, DEFAULT_SETS) with the PLAYER1 and the DEFAULT_SETS being variables I setup in a settings file. The error is at the #points part of the code in the Game class.
class Game:
#Init function to start the game variables
def __init__(self):
pg.init()
self.screen = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption(TITLE)
self.clock = pg.time.Clock()
pg.key.set_repeat(500,100)
#self.screen_scenario = WELCOME
self.load_data()
self.Game_Deuce = False
self.Game_Tiebreaker = False
#self.Game_Winner = False
self.sets = DEFAULT_SETS
self.serve = random.choice([1,2])
#Function to start a new game
def new(self):
self.paused = False
self.screen.fill(DARKGREEN)
player1 = Player(PLAYER1, 1, DEFAULT_SETS)
player2 = Player(PLAYER2, 0, DEFAULT_SETS)
#Function to run the scoreboard
def run(self):
self.playing = True
#pg.mixer.music.play(loops=-1)
#pg.mixer.music.set_volume(BG_MUSIC_VOLUME)
while self.playing:
self.dt = self.clock.tick(FPS) / 1000
self.events()
if not self.paused:
self.update()
self.draw()
#Points
self.draw_text(str(POINTS[player1.score]), self.points_font, 180, YELLOW, POINTS_BOX_X_2, POINTS_BOX_Y_2)
self.draw_text(str(POINTS[player2.score]), self.points_font, 180, YELLOW, POINTS_BOX_X_1, POINTS_BOX_Y_1)
This is in a seperate file but has been imported correctly :
class Player:
def __init__(self, name, serving, sets):
self.name = name
sets = sets
self.score = int(0)
self.games = int(0)
self.sets = int(0)
self.advantage = False
if serving == 1:
self.serving = True
#mathtick
"Make sure to restart the python process to check for re-import errors. If you are running this as a script it shouldn't be the issues"
and
#Matthias
"In the function new you set player1 = Player(PLAYER1, 1, DEFAULT_SETS). player1 is local to that function, so you can't use it in the function run"
I added self to the variables that Matthias pointed out and restarted Python and that fixed it
And UPDATE/HINTS:
If you really want to "cheat" importlib.reload is your frenemy. I generally put this in my IPython onstart.py :
from importlib import reload
And then in IPython I live in this human-dev-loop:
In [29]: import my.lib as m
In [30]: # edit code
In [31]: reload(m)
Keep in mind this does not reload all modules. If you have other files you need reload them too in the right order. Use up arrows in IPython REPL. There are autoreload libraries but I don't trust them to always get things right and you will go mad. Remember reload is a dodgy dev hack, not everything always works. Use it if to cheat, but restart if things get weird. Survive and repeat.

TypeError: argument 1 must be pygame.Surface, not type

I'm making a submarine game in python, but when I try to run it, the interpreter gives me very strange error:
"TypeError: argument 1 must be pygame.Surface, not type."
I tried to search the web for my answer, but it seems like this isn't very usual error. I also tried to find error by myself, but everything seemed fine to me. Here 's part of the code that I think error is in:
mina = pygame.image.load('mina.png')
class mina():
def __init__(self, x , y):
self.x = x
self.y = y
self.eksplozija = False
def naris(self):
screen.blit(mina, (self.x, self.y))
igralec = podmornica(150, 300, 10)
eksploziv = mina(700, 350)
metki = []
clock = pygame.time.Clock()
def grafika():
clock.tick(60)
screen.blit(ozadje, (0,0))
igralec.naris()
#line, that doesn't work:
eksploziv.naris()
for metek in metki:
metek.naris(screen)
pygame.display.flip()
The variable mina and the class mina have the same name. The class mina shadows the variable mina. You need to rename one or the other. I recommend to rename the calss mina to Mina, since Python classes use the CapWords convention (PEP 8 -- Style Guide for Python Code):
class mina():
class Mina():
eksploziv = mina(700, 350)
eksploziv = Mina(700, 350)

Attributes just disappear when I give a method as parameter

I look for an answer but no one suits to my problem...
I tried to make a Timer which should call a given function every n-ticks, but it doesn't work and when I debugged my object, the attribute callback_function that supposed to store the function to call just disappears.
Here is the code:
import pygame
class Timer:
def __init__(self, time, callback_function, repeat=False, how_many=0,
infinite=False, *args, **kwargs):
self.now = pygame.time.get_ticks()
self.time = time
self.callback_function = callback_function
self.repeat = repeat
self.how_many = how_many
self.infinite = infinite
self.args = args
self.kwargs = kwargs
self.active = True
def update(self):
if pygame.time.get_ticks() - self.now >= self.time and self.active:
self.callback_function(self.args, self.kwargs)
if((self.how_many == 0 and not self.infinite) or
self.repeat == False):
self.active = False
return False
elif not self.infinite:
self.how_many -= 1
self.now = pygame.time.get_ticks()
return True
More code:
import pygame
from api.ActorSprite import ActorSprite
from api.Timer import Timer
class ActorTest(ActorSprite):
def __init__(self):
super().__init__(pygame.image.load("assets/mario.jpg").convert())
self.add_timer(timer = Timer(2000, self.print_test,repeat=True,how_many=2))
def draw(self, screen):
super().draw(screen)
self.update_timers()
def print_test(self, *args, **kwargs):
print("Hello World!")
There is no error message, the function print_test is just not called. But when I don't use the super class of ActorTest to manage the Timer, it works...I don't get it!
These are screenshots from my debugger:
<screenshot showing instantiation>
<screenshot showing error>
I'm not sure if this is really the cause of your problem, but instead of this:
self.callback_function = lambda *args, **kwargs: callback_function(args, kwargs)
you should simply write
self.callback_function = callback_function
Ok I'm sorry it was just a bug from my debugger, the problem wasn't there. It works well now, thank you !

python default argument syntax error

I just wrote a small text class in python for a game written using pygame and for some reason my default arguments aren't working. I tried looking at the python documentation to see if that might give me an idea what I did wrong, but I didn't fully get the language in the documentation. No one else seems to be having this issue.
Here's the code for the text class:
class Text:
def __init__(self,screen,x_location='center',y_location='center',writeable,color,size=12):
self.font = pygame.font.Font("Milleni Gem.ttf", size)
self.text = self.font.render(writeable,True,color)
self.textRect = self.text.get_rect()
if x_location == "center":
self.textRect.centerx = screen.get_rect().centerx
else:
self.textRect.x = x_location
if y_location == "center":
self.textRect.centery = screen.get_rect().centery
else:
self.textRect.y = y_location
self.update()
def update(self):
screen.blit(self.text,self.textRect)
and here's the code to call it:
from gui import *
Text(screen,75,75,currentweapon.clip)#currentweapon.clip is an integer
The error I get is this:
SyntaxError: non-default argument follows default argument
and points to the def __init__() line in the code. What does this error mean and what am I doing wrong here?
def __init__(self,screen,x_location='center',y_location='center',writeable,color,size=12):
You have defined non-default arguments after default arguments, this is not allowed. You should use:
def __init__(self,screen,writeable,color,x_location='center',y_location='center',size=12):

Categories

Resources