Using import random, using random.choice throws AttributeError - python

So, I'm getting a really weird error. For some reason python is not importing random as the module, and seems to me to be importing it as a function (as seen here). Why is it doing this? Using import random and random.choice() works fine in other modules. Why not here?
update: Turns out I was defining random again in logic.py. I had forgot I did this since I wasn't using it anymore. Commented it out and it works fine.
Traceback:
Traceback (most recent call last):
File "H:\workspace37\RockPaperScissors\irps\driver.py", line 20, in <module>
print "%r" % dtree.root.get_value(history)
File "H:\workspace37\RockPaperScissors\irps\datastructures.py", line 69, in get_value
return self.operation(self.left.get_value(history), self.right.get_value(history))
File "H:\workspace37\RockPaperScissors\irps\datastructures.py", line 69, in get_value
return self.operation(self.left.get_value(history), self.right.get_value(history))
File "H:\workspace37\RockPaperScissors\irps\logic.py", line 53, in either
return random.choice((a, b))
AttributeError: 'function' object has no attribute 'choice'
I've tried to include the relevant bits of code.
logic.py:
import random
#from random import choice # works if I change random.choice(...) to just choice(...)
ROCK = 'R'
PAPER = 'P'
SCISSORS = 'S'
RPS_TUPLE = (ROCK, PAPER, SCISSORS)
RPS_SET = set((ROCK, PAPER, SCISSORS))
PLAYER = 0
OPPONENT = 1
PLAYERS = (PLAYER, OPPONENT)
def assert_in_set(a, b):
assert a in RPS_SET
assert b in RPS_SET
def neither(a, b):
assert_in_set(a, b)
diff = RPS_SET.difference((a, b))
print "diff = ", diff
return random.choice(tuple(diff))
def either(a, b):
assert_in_set(a, b)
return random.choice((a, b)) #line 53
#EDITED TO INCLUDE THESE LINES FURTHER DOWN
def random(a, b):
return random.choice(RPS_TUPLE)
ALL_OPERATORS = (neither, either)
datastructures.py
from collections import deque
from logic import RPS_TUPLE, ALL_OPERATORS, PLAYERS
import random
import sys
class OperationNode(TreeNode):
def __init__(self, parent, left, right, operation):
super(OperationNode, self).__init__(parent, left, right)
self.operation = operation
def get_value(self, history):
return self.operation(self.left.get_value(history), self.right.get_value(history)) # line 69
class TerminalNode(TreeNode):
def __init__(self, parent, player, position):
super(TerminalNode, self).__init__(parent, None, None)
self.player = player
self.position = position
def get_value(self, history):
# history is a deque of tuples
return history[self.position][self.player]

Did you define random function in logic.py?
That could be a cause of a problem.
>>> def random():
... pass
...
>>> random.choice
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'choice'

Related

'>=' not supported between instances of 'method' and 'int'

Here is the method causing the error:
class Kilpailu():
def __init__(self, nimi, pituuskm, osallistujat):
self.nimi = nimi
self.pituuskm = pituuskm
self.osallistujat = osallistujat
def kilpailu_ohi(self):
for i in self.osallistujat:
if (i.getKuljettuMatka>=self.pituuskm):
return True
else:
return False
edit: here is also where getKuljettuMatka is defined
class Auto:
def __init__(self, rekisteritunnus, huippunopeus):
self.rekisteritunnus = rekisteritunnus
self.huippunopeus=huippunopeus
self.nopeus=0
self.KuljettuMatka=0
def getKuljettuMatka(self):
return int(self.KuljettuMatka)
I am trying to call the method that just returns a boolean value and print whether the value is true or false.
class main():
autot = []
for i in range(10):
auto = Auto("ABC-" + str(i + 1), random.randint(100, 200))
autot.append(auto)
k = Kilpailu("Suuri romuralli", 8000, autot)
tunnit = 0
print(k.kilpailu_ohi()) #Should return true/false, instead throws an error
and here is the actual console output for the error
Traceback (most recent call last):
File "/root/PycharmProjects/ohjelmisto1/Harjoitustehtävät/Assosisaatio/autoKilpailu.py", line 51, in <module>
class main():
File "/root/PycharmProjects/ohjelmisto1/Harjoitustehtävät/Assosisaatio/autoKilpailu.py", line 59, in main
print(k.kilpailu_ohi())
File "/root/PycharmProjects/ohjelmisto1/Harjoitustehtävät/Assosisaatio/autoKilpailu.py", line 45, in kilpailu_ohi
if (i.getKuljettuMatka>=self.pituuskm):
TypeError: '>=' not supported between instances of 'method' and 'int'
I have tried changing stuff in the method like variable names in case i was accidentally overwriting something but it didnt work either
def getKuljettuMatka(self): defines .getKuljettuMatka on instances of Auto as a method (that happens to return an integer). You can call the method with i.getKuljettuMatka() (note the parentheses), but what you're doing is comparing the method itself to self.pituuskm, which is an integer, and that doesn't work.
Instead:
def kilpailu_ohi(self):
for i in self.osallistujat:
if (i.getKuljettuMatka() >= self.pituuskm):
return True
else:
return False
By the way, I think the code is a bit roundabout in other ways, but this is you main issue right now.

Inheritance in classes does not work in Python 2.7

I am trying to improve my understanding of OOP in Python 2.7 (uses in my University courses). My goal is to print the outcome by using a child class. However, I keep getting the below error and do not know how to fix it and why it pops up.
Can anybody tell me how to fix this code and what I am doing wrong?
Error:
Traceback (most recent call last):
File "*******"", line 36, in <module>
print_grades = CreateReport(ReadFile)
TypeError: __init__() takes exactly 1 argument (2 given)
Code:
# Constants
input_file = 'grades1.in.txt'
class ReadFile():
def __init__(self):
self.text_file =''
def read_file(self, file):
self.text_file = open(file)
def data_to_list(self):
self.list_grades = []
for x in self.text_file:
output = x.strip("\n").split("\n")
temp_list = []
for y in output:
temp_list.append(y)
self.list_grades.append(temp_list)
return self.list_grades
class CreateReport(ReadFile):
def __init__(self):
# ReadFile.__init__(self)
pass
def print_list(self):
data = ReadFile.data_to_list()
print data
# start_program(input_file)
print_grades = CreateReport(ReadFile)
print_grades.print_list()

subclass string.Formatter

Following a remark here: How to define a new string formatter, I tried subclassing string.Formatter. Here is what I've done. Unfortunately I seem to have broken it in the process
import string
from math import floor, log10
class CustFormatter(string.Formatter):
"Defines special formatting"
def __init__(self):
super(CustFormatter, self).__init__()
def powerise10(self, x):
if x == 0: return 0, 0
Neg = x < 0
if Neg: x = -x
a = 1.0 * x / 10**(floor(log10(x)))
b = int(floor(log10(x)))
if Neg: a = -a
return a, b
def eng(self, x):
a, b = self.powerise10(x)
if -3 < b < 3: return "%.4g" % x
a = a * 10**(b%3)
b = b - b%3
return "%.4g*10^%s" % (a, b)
def format_field(self, value, format_string):
# handle an invalid format
if format_string == "i":
return self.eng(value)
else:
return super(CustFormatter,self).format_field(value, format_string)
fmt = CustFormatter()
print('{}'.format(0.055412))
print(fmt.format("{0:i} ", 55654654231654))
print(fmt.format("{} ", 0.00254641))
As if as in the last line, I don't refer to the variables by position, I get a KeyError. It is obviously expecting a key which is optional in the original class but I don't understand why and I am not sure what I've done wrong.
str.format does auto numbering, while string.Formatter does not.
Modifying __init__ and overriding get_value will do the trick.
def __init__(self):
super(CustFormatter, self).__init__()
self.last_number = 0
def get_value(self, key, args, kwargs):
if key == '':
key = self.last_number
self.last_number += 1
return super(CustFormatter, self).get_value(key, args, kwargs)
BTW, above code does not strictly mimic str.format behavior. str.format complains if we mix auto numbering with manual number, but above does not.
>>> '{} {1}'.format(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: cannot switch from automatic field numbering to manual field specification
>>> '{0} {}'.format(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: cannot switch from manual field specification to automatic field numbering
Good news: you have not done anything wrong.
Bad news: that's how string.Formatter behaves, it does not support {}-like positional format. So, the last call will fail even without any subclassing. Good news: that's can be fixed by overriding the parse method:
import string
class CF(string.Formatter):
def parse(self, s):
position = 0
for lit, name, spec, conv in super(CF, self).parse(s):
if not name:
name = str(position)
position += 1
yield lit, name, spec, conv
Bad news... Ah, no, that's basically it:
>>> CF().format('{} {}!', 'Hello', 'world')
'Hello world!'

Python of generating distinct binary tree

I am new programmer in Python. Here is my code, and it gives me error. I really have no idea how to fix it.
Binary Tree class:
class BinaryTree:
def __init__(self, data):
self.data=data
self.right=None
self.left=None
def inOrderTraversal(self, root):
if root == None:
pass
else:
self.inOrderTraversal(root.left)
print root.data,
self.inOrderTraversal(root.right)
def printOrder(self):
self.inOrderTraversal(self)
Generate distinct all distinct trees
def generateAllDistinctTrees(array,start,end):
returnResultList=[]
if start>end or start<0 or end>=len(array):
return returnResultList.append(None)
if start==end:
treeNode = BinaryTree(array[start])
return returnResultList.append(treeNode)
for i in range(-1,end-start):
leftResult = generateAllDistinctTrees(array,start+1,start+1+i)
rightResult = generateAllDistinctTrees(array,start+2+i,end)
for left in leftResult:
for right in rightResult:
treeTemp = BinaryTree(array[start])
treeTemp.left = left
treeTemp.right = right
returnResultList.append(treeTemp)
return returnResultList
I've also tried in this way by using appending
def generateAllDistinctTrees(array,start,end):
returnResultList=[]
if start>end or start<0 or end>=len(array):
return returnResultList.append(None)
if start==end:
treeNode = BinaryTree(array[start])
return returnResultList.append(treeNode)
for i in range(-1,end-start):
leftResult=list()
rightResult=list()
leftResult.append(generateAllDistinctTrees(array,start+1,start+1+i))
rightResult.append(generateAllDistinctTrees(array,start+2+i,end))
for left in leftResult[0]:
for right in rightResult[0]:
treeTemp = BinaryTree(array[start])
treeTemp.left = left
treeTemp.right = right
returnResultList.append(treeTemp)
return returnResultList
Main function
if __name__ == '__main__':
preOrderData=[]
scan = raw_input("Enter Number:")
for i in range(0,int(scan)):
preOrderData=preOrderData + [i+1]
results = []
results.append(generateAllDistinctTrees(preOrderData,0,len(preOrderData)-1))
for eachObject in results[0]:
eachObject.printOrder()
I've used the Java version of this code. And it works good without any error. But in python, it will give me following errors:
For the first version if generateAllDistinctTrees:
Traceback (most recent call last):
File "<stdin>", line 7, in <module>
File "<stdin>", line 10, in generateAllDistinctTrees
File "<stdin>", line 11, in generateAllDistinctTrees
TypeError: 'NoneType' object is not iterable
For the second version of generateAllDistinctTrees: (using appending one)
Traceback (most recent call last):
File "<stdin>", line 7, in <module>
File "<stdin>", line 9, in generateAllDistinctTrees
NameError: global name 'leftResult' is not defined
Thanks in advance!!!
I attached my screen shot here!!
class BinaryTree:
left, right, data = None, None, 0
This is wrong. It will create variables that belong to the class, not to the instances (meaning that there won't be several copies for several trees).
The correct way is to just assign variables in the constructor, using self.variable = value.
I see an indentation problem where a "pass" is at the same level as a "def" that should contain it. In general your indentation is not very consistent, you should always use 4 spaces, the returns should be inside the functions.
Fix those easy mistakes so it's easier to look at the logical ones.

Working with classes - resolve a NameError: global name

I am working with class object in order to improve my skills in programming.
I have three files *.py. Sorry for the basic example but help me to understand where my error is:
/my_work_directory
/core.py *# Contains the code to actually do calculations.*
/main.py *# Starts the application*
/Myclass.py *# Contains the code of class*
in Myclass.py
class Point(object):
__slots__= ("x","y","z","data","_intensity",\
"_return_number","_classification")
def __init__(self,x,y,z):
self.x = float(x)
self.y = float(y)
self.z = float(z)
self.data = [self.x,self.y,self.z]
def point_below_threshold(self,threshold):
"""Check if the z value of a Point is below (True, False otherwise) a
low Threshold"""
return check_below_threshold(self.z,threshold)
in core.py
def check_below_threshold(value,threshold):
below = False
if value - threshold < 0:
below = not below
return below
def check_above_threshold(value,threshold):
above = False
if value - threshold > 0:
above = not above
return above
when I set main.py
import os
os.chdir("~~my_work_directory~~") # where `core.py` and `Myclass.py` are located
from core import *
from Myclass import *
mypoint = Point(1,2,3)
mypoint.point_below_threshold(5)
I get:
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "Myclass.py", line 75, in point_below_threshold
return check_below_threshold(self.z,threshold)
NameError: global name 'check_below_threshold' is not defined
Functions in other modules are not automatically visible in your Myclass module. You need to explicitly import them:
from core import check_below_threshold
or import the core module and use that as a namespace:
import core
# ...
return core.check_below_threshold(self.z,threshold)
You have a missing import.
You have to import your functions where you use them.
That means, you have to import check_below_threshhold in the core.py too, because it gets used there.

Categories