Understanding variable scopes in python: An Exercise Program - python

This is an exercise that I wanted to try because I thought it was interesting. The exercise is unnecessarily complex for what it is doing, but it is trying to act as practice for understanding class, function and variable behavior in more complex python programs.
import os
class grabFile:
fileObject = None
def __init__(self, filename):
self.fileObject = open(filename, "r")
def getFile():
return self.fileObject
class counter:
fileC = None
lineCount = 0
def __init__(self, fileObject):
self.fileC = fileObject
def lineCounter(self):
while True:
self.fileC.readline()
print(x)
return lineCount
def Main():
fileGrabber = grabFile("test.txt")
fileObj = fileGrabber.getFile
countObj = counter(fileObj)
lineCount = countObj.lineCounter()
print(lineCount)
Main()
However, when I run this, I get the following error:
Traceback (most recent call last):
File "/home/may/Desktop/Tree/Programming/MiscProjects/TextAnalyzer.py", line 32, in <module>
Main()
File "/home/may/Desktop/Tree/Programming/MiscProjects/TextAnalyzer.py", line 29, in Main
lineCount = countObj.lineCounter()
File "/home/may/Desktop/Tree/Programming/MiscProjects/TextAnalyzer.py", line 19, in lineCounter
self.fileC.readline()
AttributeError: 'function' object has no attribute 'readline'
[Finished in 0.2s with exit code 1]
Can anyone help me understand this program fully? And also, although this is not the correct place to ask, offer any critique on styling or formatting of the program? Especially one the use of "self".
Thank you!

I think you meant to call the method:
fileObj = fileGrabber.getFile()
And you need to change to instance method:
def getFile(self):
return self.fileObject
And your line counter method needs some work:
def lineCounter(self):
self.lineCount = len(self.fileC.readlines())
return self.lineCount

Related

How would i fix this error in creating a genesis block

Traceback (most recent call last):
File "C:\Users\RAC\crypto\...\blockchain.py", line 178, in <module>
blockchain = Blockchain()
^^^^^^^^^^^^
File "C:\Users\RAC\crypto\...\blockchain.py", line 49, in __init__
self.chain = [self.create_genesis_block(0)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Blockchain.create_genesis_block() takes 1 positional argument but 2 were given
with code looking like this
class Blockchain:
def __init__(self):
self.chain = [self.create_genesis_block(0)]
self.difficulty = 4
self.nodes = dict()
self.replicated_nodes = dict()
self.coin_ledger = dict()
def create_genesis_block(self):
return Block("Genesis Block", "0", coin)
ive tried adding other arguments but as i am new to this, i havent been able to figure it out myself properly
def create_genesis_block(self): doesn't take a parameter, maybe you meant:
def create_genesis_block(self, block_num):
return Block("Genesis Block", block_num, coin)
or
#staticmethod
def create_genesis_block(block_num):
return Block("Genesis Block", block_num, coin)
when you use the self constructor, you need to initialize the class, try
instanse = Blockchain()
instanse.create_genesis_block()

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()

Python Class and Attribute Error

Please look at the code below and the Attribute error I get. Thanks for your help.
This is the error I get.
Traceback (most recent call last):
File "ClassError.py", line 45, in <module>
if __name__ == '__main__':Main()
File "ClassError.py", line 43, in Main
printTest(i)
File "ClassError.py", line 38, in printTest
print f.FirstName
AttributeError: 'str' object has no attribute 'FirstName'
CODE
class CompKeyData():
def __init__(self,
FirstName,\
MiddleName,\
LastName):
self.FirstName = FirstName
self.MiddleName = MiddleName
self.LastName = LastName
def __repr__(self):
return repr((self.FirstName,\
self.MiddleName,\
self.LastName))
def __iter__(self):
return iter((self.FirstName,\
self.MiddleName,\
self.LastName))
def ckDataClassList(dataList):
dataObjects = []
for FirstName,\
MiddleName,\
LastName in dataList:
dataObjects.append(CompKeyData(
FirstName,\
MiddleName,\
LastName))
return dataObjects
ckData = [['John', 'Ralph', 'DuMont'], ['Jack', 'Lowry', 'Matern']]
ckClassData = ckDataClassList(ckData)
def printTest(classData):
for f in classData:
print f.FirstName
return None
def Main():
for i in ckClassData:
printTest(i)
if __name__ == '__main__':Main()
When you do
for i in ckClassData:
Each i is a CompKeyData instance. You then do:
printTest(i)
Which calls:
for f in classData:
where classData is the i you passed in.
This iterates through the individual CompKeyData instance, which (due to your implementation of __iter__) assigns FirstName, MiddleName and LastName in turn to f- each of these is a string, and doesn't have FirstName.
Instead, printTest should be:
printTest(classData):
print classData.FirstName
You don't need to explicitly return None, this happens automatically if you don't explicitly return anything else.
Also, it is worth reading PEP-0008; following this will make your code more readable.
You need to change your printTest function to the following:
def printTest(classData):
print classData.FirstName
classData is not a list of CompKeyData instances, but rather a single CompKeyData instance.
PEP8 is also certainly worth a look for python style.

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.

Python Issue - Map and Classes - Beginner

I'm attempting to use Map to reference a class function, but am having difficulty with formatting/ordering. I have heard that using map is sort of obsolete so I am definitely open to alternative solutions (for loops?) Thanks in advance.
lognames = [ "C:\Users\makker1\Desktop\logs\loga.txt",
"C:\Users\makker1\Desktop\logs\logb.txt",
"C:\Users\makker1\Desktop\logs\logc.txt" ]
class LogFile:
def __init__(self,filepath):
self.logfile = open(filepath, "r")
self.head = None
def __str__(self):
return "x=" + str(self.x) + "y="+str(self.y)
def readline (self):
if self.head != None:
self.head = self.logfile.readline()
def previewline (self):
if self.head == None:
self.head = self.logfile.readline()
def close (self):
self.logfile.close()
logs = map(LogFile(self,filepath).__init__(), lognames)
heads = map(lambda log: None, logs)
>>>
Traceback (most recent call last):
File "C:\Users\makker1\Desktop\mergesort-final.py", line 30, in <module>
logs = map(LogFile(self,filepath).__init__, lognames)
NameError: name 'self' is not defined
>>>
If any more info is needed, please let me know. I realize that there are tons of posts about this very problem and have sorted through many of them with no avail.
Here is a list comprehension answer. I like this better than map().
logs = [LogFile(fname) for fname in lognames]
You don't have to call __init__ explicitly. Try:
logs = map(LogFile, lognames)
Sometimes it helps to think of a class as being callable. You can think of a class as something like the following:
def LogFile(filepath):
class _LogFile:
def __init__(self, path):
...
return _LogFile(filepath)
Basically, a class can be thought of as something that you call to create an object instance. This isn't really true, but in many cases it will appear to be.

Categories