Attribute Error when using Turtles in Python - python

I am trying to build snake from turtles but am running into an attribute error when using the .xcor(), .ycor(), .pos() functions from the turtle class. Basically anything that returns a value from the turtle class is not working in my program. Here is my code:
from turtle import Turtle, Screen
import time
import random
screen = Screen()
class Snake(Turtle) : ## create snake class and pass Turtle class into it
def __init__(self):
self.xcors = []
self.ycors = []
self.snakesegs = []
self.create_snake()
def create_snake(self):
N = 0
for segs in range(1,4):
super().__init__(shape="square")
self.color("black")
self.penup()
self.goto(N,0)
self.snakesegs.append(super().__init__)
N -= 20
xcor = super().__init__.xcor()
ycor = super().__init__.ycor()
self.xcors.append(xcor)
self.ycors.append(ycor)
and here is the traceback I am getting:
Traceback (most recent call last):
File "/Users/gcinco/Documents/Python/Jett-Black/SNAKE/snake.py", line 49, in <module>
snape = Snake()
File "/Users/gcinco/Documents/Python/Jett-Black/SNAKE/snake.py", line 13, in __init__
self.create_snake()
File "/Users/gcinco/Documents/Python/Jett-Black/SNAKE/snake.py", line 24, in create_snake
xcor = super().__init__.xcor()
AttributeError: 'function' object has no attribute 'xcor'
If anyone has any idea what is going on please help, thanks!

You are calling superclass's constructor when calling super().__init__().
if you are trying to to call super's methods, just do
xcor = super().xcor()
ycor = super().ycor()

super().__init__ is the initialization method of class Turtle. It has no xcor or ycor attribute. I think what you intend is to call the x|y cor methods on the segment you created, which is much simpler:
segment = super().__init__(shape="square")
self.xcors.append(segment.xcor())
self.ycors.append(segment.ycor())
You might have an even easier time with simply:
self.segments = [super().__init__(shape="square") for _ in range(4)]
Then loop through the segments to set the desired characteristics of each:
self.color("black")
for square in self.segments:
# draw each segment in turn

Related

How do I instantiate an instance of a class in Python?

I'm new to python and doing some practice for uni,
I'm familiar with java so I am trying to create a class in python and then create an instance of the class to be used as an object from another file in the same directory.
so here's how I'm trying to do it:
within main.py -
import player
p1 = player.Player(300, 300, 64, 64)
here's my Player class located in player.py
import main
class Player:
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 15
self.left = False
self.right = False
self.walkCount = 0
this results in:
AttributeError: module 'player' has no attribute 'Player'
After some research I have also tried:
from player import Player
p1 = Player(300, 300, 64, 64)
which results in: ImportError: cannot import name 'Player' from 'player' (C:\Users\Alex\PycharmProjects\BunkerGame\player.py)
quite simply and ignoring some other code this should create an instance of the Player class in player.py to be used within the main.py file
As you noted in the comment, you import main into player - which means you have a circular import: Python can't resolve this so raises an attribute error.
You shouldn't need to do that. There shouldn't be anything in main that is needed by player. If there is, move it to player itself or a third module.
From the error you mentioned you most likely have a module already installed called player, which Python is importing as opposed to your local file player.py. Try renaming the file player.py to something else, or going on console and doing pip uninstall player.
Notice how the error says cannot import name 'Player' from 'player', which means Python is accessing a module called player, but is unable to access the class Player.
As #Daniel Roseman pointed out, I had 'import main' within player.py which python doesn't like apparently, removing this and any related code fixed the issue!
You just should write the import just like this:
import Player
p1 = Player(300, 300, 64, 64)
You can also write something like:
import Player as p
p1 = p(300, 300, 64, 64)
You need to remove the player. You are passing a class through as an attribute by using . which is the reason for the first error and the second is that your importing main on your player page and importing player on your main page. Just get rid of import main on your player page.
The first error:
import player
p1 = player.Player(300, 300, 64, 64)
This should just be:
import player
p1 = Player(300, 300, 64, 64)
Here is an example of whats happened:
class Player:
def __init__(self, name, age):
self.name = name
self.age = age
player = Player # setting the class to variable
player.name = 'Johnny' # .name is the attribute of the Player class
print(player.name)
Output:
'Johnny'
You have done this:
player.Player.name = 'Johnny'
print(player.name)
Which returns your error:
Traceback (most recent call last): File "main.py",
line 8, in <module>
player.Player.name = 'Johnny'AttributeError: type object 'Player' has no attribute 'Player'

Don't understand why this TypeError occurs when attempting to call inherited method

First, I am using python 3.6.
I am trying import and use my own .py file in my project. I import my LinkedList.py file and create a Mylist class, which extends the imported file's class.
When I try the construct an instance of the Mylist class, which involves creating an instance of my inheritedLinkedList derived class, I get the following error:
Traceback (most recent call last):
File "*/PycharmProjects/Veri Yapilari/lists.py", line 65, in <module>
test = Mylist()
File "*/PycharmProjects/Veri Yapilari/lists.py", line 38, in __init__
self.linkedlist = inheritedLinkedList()
File "*/PycharmProjects/Veri Yapilari/lists.py", line 8, in __init__
super.__init__()
TypeError: descriptor '__init__' of 'super' object needs an argument
Here's the section of the code where the problem occurs:
test = Mylist()
test.insertFirstM(incomingDataM=4) # <- Causes a TypeError.
Below is the main script in its entirety:
import LinkedList as myLinkedList
class inheritedLinkedList(myLinkedList.DoublyLinkedList):
def __init__(self):
super.__init__()
def raplaceElements(self, dataToBeChanged, incomingData):
position = self.find(dataToBeChanged)
position.data = incomingData
def swapElements(self, swap1, swap2):
position1 = self.find(swap1)
prev1 = position1.previous
next1 = position1.next
position2 = self.find(swap2)
prev2 = position2.previous
next2 = position2.next
prev1.next = position1
position1.previous = prev1
position1.next = next1
next1.previous = position1
prev2.next = position2
position2.previous = prev2
position2.next = next2
next2.previous = position2
def insertBefore(self, incomingData, previousNode=None):
self.insert(incomingData, self.find(previousNode).previous.data)
class Mylist:
def __init__(self):
# self.linkedlist = inheritedLinkedList;
self.linkedlist = inheritedLinkedList() # Per martineau's suggestion.
def replaceElements(self, dataToBeChanged, incomingData):
self.linkedlist.raplaceElements(dataToBeChanged, incomingData)
def swapElements(self, swap1, swap2):
self.linkedlist.swapElements(swap1, swap2)
def insertFirstM(self, incomingDataM):
self.linkedlist.insertFirst(incomingDataM)
def insertLast(self, incomingData):
self.linkedlist.insert(incomingData)
def insertAfter(self, incomingData, incomingNode):
self.linkedlist.insert(incomingData, incomingNode)
def insertBefore(self, incomingData, incomingNode):
self.linkedlist.insert(incomingData, incomingNode)
def remove(self, incomingData):
self.linkedlist.remove(incomingData)
def listprint(self):
self.linkedlist.listprint()
test = Mylist()
test.insertFirstM(4)
The code for the imported LinkedList module (LinkedList.py) can be obtained—if needed—by downloading it from my github repository.
As I said in a comment, you're not using the super built-in correctly. Try do things this way instead (so it's like the example in the linked documentation):
class inheritedLinkedList(myLinkedList.DoublyLinkedList):
def __init__(self):
super().__init__() # Change line to this.
Actually, since the derived class' __init__() is currently doing nothing but that, it's not even necessary because that's what would occur automatically if the subclass didn't define its own. In other words, the following would accomplish the same thing:
class inheritedLinkedList(myLinkedList.DoublyLinkedList):
# ** NOT REALLY NEEDED AT ALL **
# def __init__(self):
# super().__init__()
P.S. You also ought to change the very end of the LinkedList.py script so the last few lines that are there don't execute when it's imported as a module by lists.py:
...
nextNode.previous = previousNode
dataToBeDeleted.next = dataToBeDeleted.previous = None
if __name__ == '__main__': # Should add this, too.
list1 = SinglyLinkedList()
list2 = DoublyLinkedList()
list2.insertFirst(6)

Tkinter error - Tuple index out of range

This program is supposed to put a sprite on the canvas for the user to control using the left and right arrow keys, but I keep getting a Tuple index out of range error, and I do not have any tuples in my program. I know that I properly imported the picture, so its probably something to do with the key pressing event.
#4/22/15
#Test game, user controlled sprite
import random
from Tkinter import *
import Tkinter
from PIL import Image, ImageTk
root = Tk()
root.geometry('700x600')
canvas = Canvas(root,width=700,height=600,bg='white')
canvas.place(x=0,y=0)
class Character_sprite(object):
'''Creates the users sprite and handles the events'''
def __init__(self):
self.im = Image.open('grey_mario_mushroom_sprite.png')
self.tkimage = ImageTk.PhotoImage(self.im)
self.char_sprite = canvas.create_image(image=self.tkimage)
def moveLeft(event):
'''Handles the left arrow key press event, moves char_sprite to the left'''
canvas.move(self.char_sprite,-20,0)
canvas.update()
def moveRight(event):
'''Handles the right arrow key press event, moves the char_sprite to the right'''
canvas.move(self.char_sprite,20,0)
canvas.update()
root.bind('<Left>', Character_sprite.moveLeft)
root.bind('<Right>', Character_sprite.moveRight)
Character_sprite()
root.mainloop()
This is the error:
Traceback (most recent call last):
File "C:\Users\Calvin\Documents\Python Programs\Test_game_example.py", line 57, in <module>
Character_sprite()
File "C:\Users\Calvin\Documents\Python Programs\Test_game_example.py", line 36, in __init__
self.char_sprite = canvas.create_image(image=self.tkimage)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2310, in create_image
return self._create('image', args, kw)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2294, in _create
cnf = args[-1]
IndexError: tuple index out of range
Please help!
The problem is that create_image requires a position. Like this:
self.char_sprite = canvas.create_image((0, 0), image=self.tkimage)
If Tkinter had been defined in a more friendly way, you'd get a friendlier error message:
>>> def create_image(position, **options):
... pass
>>> create_image(image=0)
TypeError: create_image() takes exactly 1 argument (0 given)
Unfortunately, Tkinter is often a bit complicated under the covers, so it's defined more like this:
>>> def create_image(*args, **options):
... position = args[-1]
... pass
So, you get a less useful error message. The *args ends up as an empty tuple, so that position = args[-1] raises an IndexError. And of course the variable isn't even called position, but cnf, which doesn't help you understand the problem.
But it's the same problem. You forgot to pass the position argument.

Syntax Error; Python game spits out super method and imports

I made classes for what will basically become a BreakOut game, but I keep getting error messages. The nature of which always seem to surround two things; Class imports and the infamous "super" method. Usually in the form of a syntax error
I had some questions shot down in the past, so I will try to be as clear as I possibly can.
The main code for the game is as such...
import pygame
from Game import *
from Game.Scenes import *
from Game.Shared import *
class BreakOut:
def __init__(self):
self.__lives = 5
self.__score = 0
self.__level = Level(self)
self.__level.load(0)
self.__pad = Pad((0,0), 0)
self.__balls = [Ball((0,0), 0, self)]
pygame.init()
pygame.mixer.init()
pygame.display.set_caption("This is the Title of the Game")
self.__clock= pygame.time.Clock()
self.screen = pygame.display.set_mode(GameConstants.SCREEN_SIZE, pygame.DOUBLEBUF, 32)
pygame.mouse.set_visible(0)
self.__scenes = (
PlayingGameScene(self),
GameOver(self),
HighScoreScene(self),
MenuScene(self)
)
self.__currentScene = 0
self.__sounds = ()
def start(self):
while 1:
self.__clock.tick(100)
self.screen.fill((0,0,0))
currentScene = self.__scenes[self.__currentScene]
currentScene.handleEvents(pygame.event.get())
currentScene.render()
pygame.display.update()
def changeScene(self, scene):
pass
def getLevel(self):
pass
def getScore(self):
pass
def increaseScore(self, score):
pass
def getLives(self):
pass
def getBalls(self):
pass
def getPad(self):
pass
def playSound(self, soundClip):
pass
def reduceLives(self):
pass
def increaseLives(self):
pass
def reset (self):
pass
BreakOut().start()
At this stage, its only supposed to return a black screen, but instead it keeps giving me a error message with this traceback:
Traceback (most recent call last):
File "/Users/Ryan/PycharmProjects/Demo 1/Game/BreakOut.py", line 3, in <module>
from Game import *
File "/Users/Ryan/PycharmProjects/Demo 1/Game/__init__.py", line 9, in <module>
from Game.BreakOut import BreakOut
File "/Users/Ryan/PycharmProjects/Demo 1/Game/BreakOut.py", line 4, in <module>
from Game.Scenes import *
File "/Users/Ryan/PycharmProjects/Demo 1/Game/Scenes/__init__.py", line 3, in <module>
from Game.Scenes.HighScoreScene import HighScoreScene
File "/Users/Ryan/PycharmProjects/Demo 1/Game/Scenes/HighScoreScene.py", line 7
SyntaxError: invalid syntax
The bottom one connects to another class of code that looks like this:
from Game.Scenes.Scene import Scene
class HighScoreScene(Scene):
def __init__(self, game):
super(HighScoreScene, self.__init__(game)
PyCharm seems to highlight "super" and tells me "Old-style class contains call for super method" I don't know if that's important or not, but its something I've noticed consistently throughout the code.
I'm pretty sure its a simple mistake. Might be a typo, but I can't pinpoint it for the life of me. Please help!
super(HighScoreScene, self.__init__(game) # <- missing paren
It should be super(HighScoreScene, self).__init__(game)
And use object class BreakOut(object) if you want to use super.
New-style and classic classes
Your class Breakout line is not in line with the rest of your program (ahead by one space). If you backspace that line by one, everything should be fine (including #Padraic Cunningham 's answer).

Error: unbound method Dragon( ) must be called with Enemy instance as first argument (got Player instance instead)

class Character:
def __init__(self):
self.name = ""
self.health = 1
self.health_max = 1
class Player(Character):
def __init__(self):
Character.__init__(self)
self.state = 'normal'
self.health = 10
self.health_max = 10
class Monster(Character):
def Dragon(self):
self.name = "Dragon"
self.health = 20
def Goblin(self):
name = "Goblin"
health = 5
p = Player()
p.name = raw_input("Please enter your name: ")
print p.name
print p.state
print p.health
print p.health_max
m = Monster()
enemy = m.Dragon
print enemy.name
print enemy.health
Sorry, I've made this a little simpler to explain what I'm having difficulty with. I'm having a little bit of trouble with the basics of OOP, and I'm running into an issue with this snippet of code. I'm trying to create a "Dragon" here but I'm running into the following error:
Traceback (most recent call last):
File "test2.py", line 32, in
print enemy.name
AttributeError: 'function' object has no attribute 'name'
Can you tell me what I'm doing wrong here? Thanks.
You have to create an instance of a class first before you call any functions from it:
myenemy = Enemy()
myenemy.Dragon()
In your code, it looks like you created self.enemy, but later you call self.enemy = Enemy.Dragon(self). Instead of this last line, put self.enemy = self.enemy.Dragon(self).
It seems to be a recurring issue in the rest of your code as well. Commands = {'explore': Player.explore} should probably be Commands = {'explore': p.explore} (after you have created the instance p).
Since your updated code, I think you're getting functions and classes mixed up. Dragon is a function, and when you do enemy = m.Dragon, you are simply copying the function onto enemy. And thus when you do enemy.name, thinking it's a class, an error is raised, because enemy is now a function, not an instance.
You will have to create separate classes for different monsters:
class Dragon:
self.name = "Dragon"
self.health = 20
class Goblin:
name = "Goblin"
health = 5

Categories

Resources