Object not iterable when assigning to a list - python-2.7

I am coding a 2048 game via pygame. below is the relevant section of my code:
class Data():
def __init__(self):
self.data = getnull()
self.score = 0
def updatesprites(self): # EXP
spritelist = [[],[],[],[]]
for count in range(4): # for row loop
for i in range(4): # per column loop
if self.data[count][i] != 0:
spritelist[count]+= newSprite(str(self.data[count] [i])+".png") # error occurs here
spritelist[count][i].move(15 + i*115, 15 + count*115)
showSprite(spritelist[count][i])
class newSprite(pygame.sprite.Sprite):
def __init__(self,filename):
pygame.sprite.Sprite.__init__(self)
self.images=[]
self.images.append(loadImage(filename))
self.image = pygame.Surface.copy(self.images[0])
self.currentImage = 0
self.rect=self.image.get_rect()
self.rect.topleft=(0,0)
self.mask = pygame.mask.from_surface(self.image)
self.angle = 0
def addImage(self, filename):
self.images.append(loadImage(filename))
def move(self,xpos,ypos,centre=False):
if centre:
self.rect.center = [xpos,ypos]
else:
self.rect.topleft = [xpos,ypos]
----------------Main-------------------
from functions import *
from config import *
from pygame_functions import *
import pygame
screenSize(475,475) # call screen init
gameboard = newSprite("game board.png") # createboard
showSprite(gameboard)
game = Data()
game.updatesprites()
while True:
pass
when game.updatesprites() is called, "newSprite object is not iterable" error is raised in function Data.updatesprites

+ concatenates lists and strings, and adds numbers.
What you are trying to do, is to add an element to a list.
This is done as follows:
li.append(element) # adds the element to the end of the list
Or in your case:
spritelist[count].append(newSprite(str(self.data[count][i]) + ".png"))
Another solution: You could create a new type, that lets you add elements the way you were trying to:
class UglyList(list):
def __iadd__(self, other):
self.append(other)
You'd need to change another line here:
spritelist = [UglyList() for i in range(4)]

Related

How to return function results in an array?

I have one function where I am calculating the CPU usage of a test case. The function works, but I would like to append the result of the subtraction in a list for the further usage.
For example, first I subtract 10 and 15, which is -5. At this point the list looks like [-5]. Next I subtract 20 and 30, which is -10. Now I want the list to look like [-5, -10]. My current code is (python 2.7):
import psutil
class CPU():
def __init__(self):
self.cpu_start()
def cpu_start(self):
global a
a= psutil.cpu_percent(interval=1, percpu=False)
print a
def cpu_end(self):
global b
b = psutil.cpu_percent(interval=1, percpu=False)
print b
def diff(self):
c= a-b
list = []
list.append(c)
print list
def main():
CPU()
if __name__ == '__main__':
main()
Just make the diff function return a-b, and append that to an array:
import psutil
class CPU:
def __init__(self):
self.cpu_start()
self.list = []
self.a = 0
self.b = 0
self.c = 0
def cpu_start(self):
self.a = psutil.cpu_percent(interval=1, percpu=False)
return self.a
def cpu_end(self):
self.b = psutil.cpu_percent(interval=1, percpu=False)
return self.b
def diff(self):
self.c = self.cpu_start() - self.cpu_start()
return self.c
def main():
cpu = CPU()
results = []
while True:
results.append(cpu.diff())
print results
if __name__ == '__main__':
main()
Remember that when you're using a class function, you need to create an object of that class, such as cpu = CPU() - I'm creating an object called cpu of class CPU, initialised with nothing. Then the __init__ function will create a and b(created as self.a and self.b, because they're local) and store them locally in that class. The diff() function, takes no arguments, but returns the difference of a and b which are stored locally in that class. Then I create a list called results with no elements. I run cpu.diff(), which gets the difference from cpu_start() and cpu_end(), and append the result to the results array. This is run in a loop, constantly appending to the array and printing it.
Hope this helps.

Why doesn't my find function compare the nodes correctly?

I'm working on a concordance dictionary that reads a data file and records every unique word and the word's line number in a AVL tree. The problem is that my find method is not finding the Entry's within the tree so it adds every word instead of every unique word.
I'm also having trouble making my program keep a list of the line numbers within each entry. I'm using an entry class to keep the key(word) and the list of line numbers. Thank you for any help.
I'm writing in Python 2.7 and have included all my program so far.
My Main Program:
import string #NEW
from time import clock
import sys #for BST recursion limit
from dictionary import Entry
sys.setrecursionlimit(3000)#for BST
from avl import AVL
def main():
"""Calls on necessary functions to fill the dictionary, and process the keys"""
start = clock() #times runtime
stopWordDict = AVL()#Empty Dictionary
stopWordDict = fillStopWordDict(stopWordDict)
keyList = []
wordConcordanceDict = AVL()#Empty Dictionary
wordConcordanceDict = fillWordDict(stopWordDict,wordConcordanceDict, keyList)
print str(wordConcordanceDict) #wordconcorddict made here.
keyList.sort()
print keyList
writeWordConDict(wordConcordanceDict, keyList)
end = clock() #gets runtime
runTime = end - start
print("Done. Runtime was:",runTime,"seconds.")
def fillStopWordDict(stopWordDict):
"""fills chain dict with all of the stop words"""
fileNew=open('stop_words.txt', "r")
for word in fileNew:
word=word.lower().strip() #strip will strip \n from word
if stopWordDict.find(word) == None:
stopWordDict.add(word)
fileNew.close()
return stopWordDict
def fillWordDict(stopWordDict,wordConcordanceDict, keyList):
"""opens hw5data.txt and calls on processLine function"""
lineCounter = 1
fileNew=open('hw5data.txt', "r")
for line in fileNew:
processLine(lineCounter, line, stopWordDict,wordConcordanceDict, keyList)
lineCounter+=1 #changes to next line of file
fileNew.close()
return wordConcordanceDict
def processLine(lineCounter, line, stopWordDict,wordConcordanceDict, keyList):
"""process each line into the wordConcordanceDict"""
line=line.split() #splits line into list of words
for word in line:
word=word.lower().strip(string.punctuation)#strips punctuation
if stopWordDict.find(word) == None:
wordEntry = Entry(word, None)
if wordConcordanceDict.find(wordEntry) == None:
lineList = wordEntry.value
lineList.append(lineCounter)
wordEntry.value = lineList
wordConcordanceDict.add(wordEntry)
keyList.append(word)
else:
wordEntry = wordConcordance.find(wordEntry)
lineList = wordEntry.value
lineList.append(lineCounter)
wordEntry.value = lineList
wordConcordanceDict.add(wordEntry)
return wordConcordanceDict
def writeWordConDict(wordConcordanceDict, keyList):
"""takes in wordConcordanceDict and list of its keys. Then prints the key value pairs to the screen"""
fileNew=open("ProgProj5Concordance.txt", 'w')
# listOfWords = wordConcordanceDict.inorder()
for key in keyList:
wordEntry = wordConcordanceDict.find(key) #makes the values into a string
lineList = wordEntry.value
line=str(key + ":" + lineList + "\n")
fileNew.write(line)
fileNew.close()
main()
MY ENTRY CLASS:
"""
File: bst.py
BST class for binary search trees.
"""
from queue import LinkedQueue
from binarytree import BinaryTree
class BST(object):
def __init__(self):
self._tree = BinaryTree.THE_EMPTY_TREE
self._size = 0
def isEmpty(self):
return len(self) == 0
def __len__(self):
return self._size
def __str__(self):
return str(self._tree)
def __iter__(self):
return iter(self.inorder())
def find(self, target):
"""Returns data if target is found or None otherwise."""
def findHelper(tree):
if tree.isEmpty():
return None
elif target == tree.getRoot():
return tree.getRoot()
elif target < tree.getRoot():
return findHelper(tree.getLeft())
else:
return findHelper(tree.getRight())
return findHelper(self._tree)
def add(self, newItem):
"""Adds newItem to the tree."""
# Helper function to search for item's position
def addHelper(tree):
currentItem = tree.getRoot()
left = tree.getLeft()
right = tree.getRight()
# New item is less, go left until spot is found
if newItem < currentItem:
if left.isEmpty():
tree.setLeft(BinaryTree(newItem))
else:
addHelper(left)
# New item is greater or equal,
# go right until spot is found
elif right.isEmpty():
tree.setRight(BinaryTree(newItem))
else:
addHelper(right)
# End of addHelper
# Tree is empty, so new item goes at the root
if self.isEmpty():
self._tree = BinaryTree(newItem)
# Otherwise, search for the item's spot
else:
addHelper(self._tree)
self._size += 1
def inorder(self):
"""Returns a list containing the results of
an inorder traversal."""
lyst = []
self._tree.inorder(lyst)
return lyst
def preorder(self):
"""Returns a list containing the results of
a preorder traversal."""
# Exercise
pass
def postorder(self):
"""Returns a list containing the results of
a postorder traversal."""
# Exercise
pass
def levelorder(self):
"""Returns a list containing the results of
a levelorder traversal."""
# Exercise
pass
def remove(self, item):
# Exercise
pass
def main():
tree = BST()
print "Adding D B A C F E G"
tree.add("D")
tree.add("B")
tree.add("A")
tree.add("C")
tree.add("F")
tree.add("E")
tree.add("G")
print tree.find("A")
print tree.find("Z")
print "\nString:\n" + str(tree)
print "Iterator (inorder traversal): "
iterator = iter(tree)
while True:
try:
print iterator.next(),
except Exception, e:
print e
break
# Use a for loop instead
print "\nfor loop (inorder traversal): "
for item in tree:
print item,
if __name__ == "__main__":
main()
AND FINALLY THE BINARY TREE AVL CLASS:
from binarytree import *
class BinaryTreeAVL(BinaryTree):
def __init__(self, item, balance = 'EQ'):
BinaryTree.__init__(self, item)
self._balance = balance
def getBalance(self):
return self._balance
def setBalance(self, newBalance):
self._balance = newBalance
def __str__(self):
"""Returns a string representation of the tree
rotated 90 degrees to the left."""
def strHelper(tree, level):
result = ""
if not tree.isEmpty():
result += strHelper(tree.getRight(), level + 1)
result += "| " * level
result += str(tree.getRoot())+ " : " + tree.getBalance() + "\n"
result += strHelper(tree.getLeft(), level + 1)
return result
return strHelper(self, 0)

Creating a Class Attribute dependent on Another Attribute

I am currently working on a small RPG in Pygame to get used to object oriented coding.
When looking into how to auto-update a property I came across the following:
class P:
def __init__(self,x):
self.x = x
#property
def x(self):
return self.__x
#x.setter
def x(self, x):
if x < 0:
self.__x = 0
elif x > 1000:
self.__x = 1000
else:
self.__x = x
I tried applying it to my code but I get the following error:
File "weapons.py", line 13, in __init__
self.name = '{} {}'.format(ammo, self.raw_name)
TypeError: name() takes exactly 3 arguments (2 given)
I understand what the error is but I don't get how to solve it since I need both the raw_name and the ammo attributes to auto-update my Arrow instance's name.
My class is as such:
class Projectile(Item):
def __init__(self, name, value, image, x, y, speed, dmg, dmg_modif, ammo):
super(Projectile, self).__init__(name, value, image, x, y)
self.dest = (self.rect[0],self.rect[1])
self.speed = speed
self.dmg_modif = dmg_modif
self.dmg = dmg
self.orientation = 0
self.ammo = ammo
#property
def name(self):
return self.___name
#name.setter
def name(self, raw_name, ammo):
if '{} {}'.format(raw_name,ammo) != self.___name:
self.___name = '{} {}'.format(raw_name,ammo)
The child class which returns the error is:
class Arrow(Projectile):
def __init__(self, ammo): #name, value, image, x, y, dmg
self.raw_name = 'Arrows'
self.name = '{} {}'.format(ammo, self.raw_name)
self.value = 5
self.image = variables.quiver_img
self.speed = 4
self.dmg = 2
self.dmg_modif = 1
super(Arrow, self).__init__(self.name, self.value, self.image, 200, 150, self.speed, self.dmg, self.dmg_modif, ammo)
And the parent classes are, Item and MySprite:
class Item(MySprite):
def __init__(self, name, value, image, x, y):
# Call the parent class (Sprite) constructor
super(Item, self).__init__(image, x, y)
self.name = name
self.value = value
self.inv_pos = -1
and
class MySprite(pygame.sprite.Sprite):
def __init__(self,image,x,y):
# Call the parent class (Sprite) constructor
super(MySprite, self).__init__()
self.image = image
self.rect = self.image.get_rect().move(x, y) #initial placement
self.top_cp = (self.rect[0]+self.rect[2]/2,self.rect[1])
self.bot_cp = (self.top_cp[0],self.rect[1]+self.rect[3])
self.left_cp = (self.rect[0],self.rect[1]+self.rect[3]/2)
self.right_cp = (self.left_cp[0]+self.rect[2],self.left_cp[1])
self.center = self.rect.center
self.pos = self.rect.topleft
self.blit_order = 1
self.level = variables.current_level #Level(1)#level to which sprite belongs
Any help would be welcome !
Please provide a minimal example next time.
Your code looks a little complicated. OK, the first problem is that you can't pass multiple arguments to a setter. You can either pass a tuple or just use a traditional setter method def set_name(self, name, ammo):.
Another problem is that you use the ___name attribute before it has been set, for example in the second line of the Arrows __init__ method.
Private attributes should have one underscore not three (that's just a convention to warn other programmers). If you have two or more underscores than the name gets mangled.
Also, it looks to me like you change the name in the setter only if the new name is equal to the old name (kinda pointless ;)). What do you actually want to do there? Maybe you don't need properties at all.
Here's a fixed (minimal) version of your code:
import pygame
class MySprite(pygame.sprite.Sprite):
def __init__(self):
super(MySprite, self).__init__()
class Item(MySprite):
def __init__(self, name):
super(Item, self).__init__()
self.name = name
class Projectile(Item):
def __init__(self, name):
super(Projectile, self).__init__(name)
#property
def name(self):
return self._name
#name.setter
def name(self, name):
self._name = name + ' foo'
class Arrow(Projectile):
def __init__(self):
super(Arrow, self).__init__(name='Arrows')
arrow = Arrow()
print(arrow.name)
arrow.name = 'New name'
print(arrow.name)
So I eventually managed to solve my problem:
class Projectile(object):
def __init__(self, raw_name, ammo):
self.raw_name = raw_name
self.name = self.raw_name
self.ammo = ammo
#property
def ammo(self):
return self._ammo
#ammo.setter
def ammo(self, ammo):
self.name = str(ammo) + self.raw_name
self._ammo = ammo
class Arrow(Projectile):
def __init__(self):
self.raw_name = ' Arrows'
self.name = self.raw_name
super(Arrow, self).__init__(self.raw_name, ammo
= 10)
arrow = Arrow()
print arrow.ammo
print arrow.name
arrow.ammo = 15
print arrow.ammo
print arrow.name
gives:
>>>10
>>>10 Arrows
>>>15
>>>15 Arrows

Generate a bunch of tkinter checkbuttons and read the status of all those radio buttons at once

I have a tkinter class which reads some data into a couple of lists. From this now i have created a dictionary for creating checkbuttons.
I'm trying to create those checkbuttons in a new window() with a button to submit and read the stutus of those. I want this data to process.
def get_data(self):
self.flags = ["one","two","three", "four"]
self.tests = ["Jack","Queen","King","Ace"]
self.value = [11,12,13,1]
self.dict1 = {k:v for k,v in enumerate(self.flags,1)}
def get_status(self):
self.selectWindow = Toplevel(root)
self.selectWindow.title("Select Test Cases")
Submit_btn = Button(selectWindow, text="Submit", command=read_status )
for testcase in self.dict1:
self.dict1[testcase] = Variable()
l = Checkbutton(self.selectWindow,text=self.dict1[testcase], variable=self.dict1[testcase])
l.pack()
def read_status(self):
pass
From here I'm not able go ahead and read the status of checkbuttons and get those are checked. I need this data for further processing on tests(not actual lists given here I have few more). How to solve? Please let me know.
Checkbutton has a built in command function that can solve this problem. Every time you press a button that function is called, and you can print out the values of the buttons (0,1)
def get_data(self):
self.flags = ["one","two","three", "four"]
self.tests = ["Jack","Queen","King","Ace"]
self.value = [11,12,13,1]
self.dict1 = {k:v for k,v in enumerate(self.flags,1)}
def get_status(self):
self.selectWindow = Toplevel(self)
self.selectWindow.title("Select Test Cases")
self.get_data()
Submit_btn = Button(self.selectWindow, text="Submit", command=read_status ) # This button should be packed
Submit_btn.pack()
for testcase in self.dict1:
self.dict1[testcase] = Variable()
l = Checkbutton(self.selectWindow,text=self.dict1[testcase], variable=self.dict1[testcase], command=self.read_status) # Note the command
l.pack()
self.selectWindow.mainloop()
# Here comes the interesting part
def read_status(self):
for i,j in self.dict1.iteritems():
print j.get()
You forgot to use self and pack method:
Submit_btn = Button(self.selectWindow, text="Submit", command=self.read_status )
Submit_btn.pack()
Checkbutton's states are (0, 1) so use IntVar() to inspect the state:
...
self.dict1[testcase] = IntVar()
...
Then use IntVar get method:
def read_status(self):
for v in self.dict1:
print self.dict1[v].get()

Python AttributeError instance has no attribute, When I add a new method.

I am Trying to call a another method within my class, for some reason I am getting the AttributeError: portfinder instance has no attribute 'generatePortNumber' See my code below:
when I tried to call the generatePortNumber I'm getting the same error. I have never come across this issue.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sqlite3 as lite
import sys
import random
class portfinder:
"""docstring for ClassName"""
def __init__(self):
self.portsToCheck = ['agentport','BatchProcessingAgentPort','databaseport','indexserviceport','monitorport','servicefacadeport','webdriverport']
self.dataBasePort = (u'60025',)
self.portInUse = False
self.x = 0
def generatePortNumber(self):
self.newPortNumber = random.randrange(8000, 9000)
print self.newPortNumber
return self.newPortNumber
def findUsedPortsinDB(self):
con = lite.connect('D:\play\Opes\db.sqlite3')
with con:
cur = con.cursor()
sqlStatement = "Select " + self.portsToCheck[2] +' From Jobs_jobs'
print sqlStatement
cur.execute(sqlStatement)
rows = cur.fetchall()
for row in rows:
print row
if row == self.dataBasePort:
self.portInUse = "true"
self.generatePortNumber()
if __name__ == "__main__":
m = portfinder()
m.findUsedPortsinDB()
Found what was wrong I had a extra indentation in my method