Object has no attribute - Python OOP - python

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.

Related

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)

Python - Functions & Execution order

I want to use the bot_create function with a button but I keep getting (on line 20) the problem "bots not defined" so I moved the function down below the button but got the problem "bot_create not defined".
I didn't get this problem using C++ and I'm new to Python. How should I arrange the functions?
import tkinter as tk
import numpy as np
import multiprocessing as mp
bots_max = 1000 # Maximum number of bots
bot = []
bot_count = 0
# Menu functions
def save_field():
pass
# Field functions
def field_clear():
pass
# Bots functions
def bots_create():
bot[bot_count] = bots
bot_count += 1
main = tk.Tk()
field_sides = 600
ctrls_width = 200
main.geometry("800x600")
main.resizable(0, 0)
main.title("Swarm Simulator v1.0")
# Controls menu on left side
button1 = tk.Button(main, text = "Button 1").pack(side = "left", command = bots_create())
class environment:
def __init__():
pass
class wall:
def __init__():
pass
# Bots
class bots:
alive = True
def __init__():
alive = True
# Field where bots live
field = tk.Canvas(main, width = field_sides, height = field_sides, bg = "white").pack(side = "right")
for particle in bots:
print("|")
main.mainloop()
Here's a version of your code that fixes all the syntactic problems, and so compiles (what I really mean is that my IDE now thinks its ok). It also runs, but I don't know if it does what you intended. See my comments in the code:
import tkinter as tk
import numpy as np
import multiprocessing as mp
# moved your class defs up to fix problems with accessing them before they are defined
class environment:
def __init__(self): # need a self param here
pass
class wall:
def __init__(self): # need a self param here
pass
# Bots
class bots:
alive = True
def __init__(self): # need a self param here
alive = True
bots_max = 1000 # Maximum number of bots
bot = []
# bot_count = 0 # this no longer does anything. use `len(bot)` to get the number of objects in the 'bot' list
# Menu functions
def save_field():
pass
# Field functions
def field_clear():
pass
# Bots functions
def bots_create():
# bot[bot_count] = bots # this will crash as it is referring to a non-existent location in the list
# also, your use of "bots" here makes no sense
# bot_count += 1 # this makes 'bot_count' a local variable, which is not what you want
bot.append(bots()) # not sure this is what you want, but this creates a new 'bots' object and adds it to the 'bot' list
main = tk.Tk()
field_sides = 600
ctrls_width = 200
main.geometry("800x600")
main.resizable(0, 0)
main.title("Swarm Simulator v1.0")
# Controls menu on left side
button1 = tk.Button(main, text = "Button 1").pack(side = "left", command = bots_create())
# Field where bots live
field = tk.Canvas(main, width = field_sides, height = field_sides, bg = "white").pack(side = "right")
for particle in bot: # maybe you want to iterate over the 'bot' list instead of the 'bots' type?
print("|")
main.mainloop()
As #khelwood says, it seems that you should swap the use of the names bot and bots per the way you are using them

Pyglet Player.seek() function not working?

I am trying to build a simple media tool in Pyglet, which requires a seek feature. Files are loaded, paused, and then told to seek to a specific time; however, the file does not seek when Player.seek() is called. Below is the test code I am using:
import os
import pyglet
from os.path import abspath, isfile
def loadsong(filename):
# check for file
print("Attempting to load "+filename)
filename = abspath(filename)
if not ( isfile(filename) ):
raise Exception(filename+" not found.")
# create a player for this file
song = pyglet.media.load(filename)
source = song.play()
source.eos_action = source.EOS_LOOP
source.pause()
return source
music = loadsong("test.mp3")
music.seek(57)
music.play()
pyglet.app.run()
What am I doing wrong here? I am using Python 3.5.2, Pyglet 1.2 alpha 1, and AVBin 11 alpha 4.
First of all, the error you're getting is quite important.
But I'll assume it's a Segmentation fault (core dumped) on the row:
music.seek(12)
Another quick note, fix your indentation! You're using 3 spaces and whether you are a space guy or a tab guy - 3 spaces is just odd -
The reason for you getting a segmentation fault when trying to seek is most likely because of AVbin, it's an old (and dead afaik) project.
I hacked together something more similar to a music player and here's an example on how you can use Seek with wav files:
import pyglet
from pyglet.gl import *
from os.path import abspath, isfile
pyglet.options['audio'] = ('pulseaudio', 'alsa', 'openal', 'silent')
pyglet.have_avbin=False
key = pyglet.window.key
def loadsong(filename):
# check for file
filename = abspath(filename)
# create a player for this file
player = pyglet.media.Player()
player.queue(pyglet.media.load(filename, streaming=False))
#player.play()
#song.eos_action = song.EOS_LOOP
#song.pause()
return player
class main(pyglet.window.Window):
def __init__ (self):
super(main, self).__init__(300, 300, fullscreen = False)
self.alive = 1
self.player = loadsong('./test.wav')
def on_draw(self):
self.render()
def on_close(self):
self.alive = 0
def on_key_press(self, symbol, modifiers):
if symbol == key.ESCAPE: # [ESC]
self.alive = 0
elif symbol == key.SPACE:
if self.player.playing:
self.player.pause()
else:
self.player.play()
elif symbol == key.RIGHT:
print('Skipping to:',self.player.time+2)
self.player.source.seek(self.player.time+2)
elif symbol == key.LEFT:
print('Rewinding to:',self.player.time-2)
self.player.source.seek(self.player.time-2)
def render(self):
self.clear()
#source = pyglet.text.Label(str(self.player.source.info.title.decode('UTF-8')), x=20, y=300-30)
volume = pyglet.text.Label(str(self.player.volume*100)+'% volume', x=20, y=40)
p_time = pyglet.text.Label(str(self.player.time), x=20, y=20)
#source.draw()
volume.draw()
p_time.draw()
self.flip()
def run(self):
while self.alive == 1:
self.render()
# -----------> This is key <----------
# This is what replaces pyglet.app.run()
# but is required for the GUI to not freeze
#
event = self.dispatch_events()
x = main()
x.run()
A few important notes:
pyglet.have_avbin=False
This will turn off AVbin completely, there is probably a way to turn it off for individual sources.. But since I rarely play around with it I honestly have no idea of how to.. So off it goes :)
Secondly:
streaming=False
On the media.load() call is quite important, otherwise you might get weird artifacts in your sound and or no sound at all. I got instance to a super high pitched scratching noise that almost made me deaf without that flag.
Other than that, the code is quite straight forward.
self.player.source.seek(<time>)
Is called on the player object that is a instance of pyglet.media.Player(). And it works brilliantly.
Another work-around would be to manually install AVbin 7 which appears to be working better, but I'm reluctant to install it on this machine just for testing purposes.. But the overall info i've gathered over the years is that that old library works better with Mp3 files.
Please ensure Player.playing is True before invoking Player.seek().
In the end of loadsong() function, you invoked the pause() that will set the Player.playing to False.
you could try:
music.play()
music.seek(57)
instead of:
music.seek(57)
music.play()
The following example uses pyglet 1.5.6, the seek() function works on my macbook pro, but negative on my windows 10:
import pyglet
from pyglet.window import key
source = pyglet.media.load(VIDEO_FILE_PATH)
fmt = source.video_format
player = pyglet.media.Player()
player.queue(source)
player.play()
window = pyglet.window.Window(width=fmt.width, height=fmt.height)
#window.event
def on_draw():
player.get_texture().blit(0, 0)
#window.event
def on_key_press(symbol, modifiers):
if symbol == key.LEFT:
player.seek(player.time - 3.5)
elif symbol == key.RIGHT:
player.seek(player.time + 3.5)
elif symbol == key.SPACE:
if player.playing:
player.pause()
else:
player.play()
pyglet.app.run()

Modifying a function from another in python

For an online course in python, I'm making a basic text-based adventure game in python.
Right now, I have a rudimentary inventory system that works through booleans for if the user has an object or not, and integers for limited items, such as ammo and whatnot.
Here is the code for the inventory system
def Inventory(self): #The inventory for the game. I don't know how to program it properly, so this is my testing ground.
#This will hold the boolean values to if the player has the items or not. Another will be used to show the user the items
street_clothes = False
pistol = False
ammo = 0
phone = False
And this is the code where I am trying to modify the inventory function above
#Eric's apartment
def Eric_Apartment(self):
print "type in grab your gun"
action = raw_input("> ")
if action == "grab":
self.Inventory(CR97) = True
# self.CR97_ammo += 15
# print CR97_ammo
# print self.CR97_ammo
exit(1)
Attempting to run this program gets me this error:
python ex43.py
File "ex43.py", line 78
self.Inventory(CR97) = True
SyntaxError: can't assign to function call
Is there something else I'm supposed to do? I'm very new to python, and this is my first project on my own.
Here is the entire code, for reference
from sys import exit #allows the program to use the exit(1) code
from random import randint #allows the program to use a random number
class Game(object):
#quotes that pop up if the person dies, and also defines the start and self variables
def __init__(self, start):
self.quips = [
"You lose!"
]
self.start = start
def Inventory(self): #The inventory for the game.
#This will hold the boolean values to if the player has the items or not.
street_clothes = False
pistol = False
ammo = 0
phone = False
#this function launches the game, and helps with the room transfer
def play(self):
next = self.start
while True:
print "\n---------"
room = getattr(self, next)
next = room( )
#if the user dies, or fails at the game, this is the function that is ran
def death(self):
print self.quips[randint(0, len(self.quips)-1)]
exit(1)
#Welcome screen to the game
def welcome_screen(self):
print " place holder"
return 'intro_screen'
#Intro screen to the game
def intro_screen(self):
print "place holder"
action = raw_input("> Press any key to continue ")
return 'Eric_Apartment'
#Eric's apartment
def Eric_Apartment(self):
print "type in grab your gun"
action = raw_input("> ")
if action == "grab":
self.Inventory(CR97) = True
# self.CR97_ammo += 15
# print CR97_ammo
# print self.CR97_ammo
exit(1)
a_game = Game("welcome_screen")
a_game.play()
That's an amazingly perverse way to go about it. Why are you using a function to store data?
Just have a player object, with an inventory array.
I'd recommend using objects to model items too. Good use for for a class hierarchy. COuld have a base Item, with Subclasses SingleItem and StackableItem, etc.
Instead of using a function, try using a class -
class Player:
def __init__(self):
self.street_clothes = False
self.pistol = False
self.ammo = 0
self.phone = False
def give_street_clothes(self):
self.street_clothes = True
# etc
But personally, instead of using each item as a boolean, I'd use a list of items:
class Player:
def __init__(self):
self.inventory = []
# add code for ammo/pistol
def has_item(self, item):
return item in self.inventory
def give_item(self, item):
self.inventory.add(item)
def remove_item(self, item):
self.inventory.remove(item)
# etc

NameError when using "self" in class?

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.

Categories

Resources