Okay, so I have a module I created and have imported it into my main program. I guess I'm still trying to understand classes and I'm not sure how to actually enter my data into my class. This is in Python 3. Here is the module:
class Movie:
def __init__(self, Title = '', Ratings = []):
self.Movie = Title
self.Ratings = Ratings
self.TotalRatings = 0
self.minusFive = 0
self.minusThree = 0
self.one = 0
self.three = 0
self.five = 0
self.ValidRatings = [-5,-3,1,3,5]
def __str__(self):
return '{0} has {1} total ratings with an average rating of {3}.'.format(self.title, self.totalRatings, self.AvgRating)
def __repr__(self):
return self.__str__()
def AddRating(self, rating):
for num in self.Ratings:
if num in self.ValidRatings:
self.totalRatings += 1
else:
continue
def AvgRating(self):
return sum (self.totalRatings)/len(self.totalRatings)
Below is the beginning of my main program:
import Movie
def ReadFile(FileName):
F = open(FileName)
return F.readlines()
File = ReadFile('Ratings.txt')
File2 = open('Prog5Titles.txt').read() #open movie titles file
movie1 = Movie("The Avengers", [5,5,5]) #this is just a sample to help me understand
When I run this, I am getting the error message: 'module' object is not callable. Can anyone help me understand how to correctly input my data into this?
The problem is that you have a file Movie.py that contains a class named, by coincidence, Movie. If you just import Movie, then the python name Movie refers to the contents of the file Movie.py and to refer to the class tucked away in there, you need to write:
movie1 = Movie.Movie("The Avengers", [5,5,5])
Alternatively, you can do your import like this:
from Movie import Movie
and now the python name Movie refers to something different — the "thing" (in this case, a class) named Movie inside the file Movie.py.
This would be a little clearer if you named the file containing class Movie with a name different from the class defined inside the file. Maybe movie_stuff.py or something. Consider that you'll have additional classes in the project (Actor, Studio) and those classes will probably be defined in the same file as class Movie.
Related
In my inventoryRead how can I properly define an Items object. Also, how do I run this method
Traceback (most recent call last):
File "C:/Users/jburk/OneDrive/Desktop/Deft Project/quickMart.py", line 7, in <module>
class Items:
File "C:/Users/jburk/OneDrive/Desktop/Deft Project/quickMart.py", line 34, in Items
inventoryRead('self')
File "C:/Users/jburk/OneDrive/Desktop/Deft Project/quickMart.py", line 24, in inventoryRead
item1 = Items()
NameError: name 'Items' is not defined
code
class Items:
# Constructor to initilize an item object
# An item has name, quantity, price, member price, and taxing status
def __init__(self, name, quantity, price, memPrice, taxStatus):
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
def inventoryRead(self):
txt = ""
count = 0
f = open("inventory.txt", "r")
inList = []
item1 = Items()
print(item1)
for line in f.readlines():
item1.name = line[0:line.find(":")]
print(item1)
print(item1.name)
inList[count] = Items()
txt = line.next()
print(txt)
inventoryRead('self')
#arr = f.readlines()
#print(arr[0])
I think it would be smarter if you had an Item and a separate ItemMangager or Items class. I'm going to call it Items from now on.
Items would contain some store every Item in (for example) a list and Items loads them from the file, but also saves them to same.
You try to create an instance of the class you are currently in, the main way you would edit this file is through the self prefix you used before to modify this instances attributes.
The example I provide is done using a .txt file for storage to keep to your way of doing it, although it would probably be smarter to use an actual database module like sqlite, you should have a look into that.
#!/usr/bin/env python3
#Item holds one record of sth
class Item():
def __init__(self,name, quantity, price, memPrice, taxStatus):
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
class Item_Manager:
def __init__(self):
self.items=[]
self.data_file_path="records.txt"
def load_data(self):
with open(self.data_file_path,"r") as f:
contents= f.read()
for i in contents.split("\n"): #splits every line into a new string
data=i.split(" ") #asuming every line has the attributes space-separated
item=Item(data[0],data[1],data[2],data[3],data[4])
self.items.append(item) #saving the new created Item instance in the mangagers items list
def save_data(self): #overwriting
with open(self.data_file_path,"w") as f:
for i in self.items: #i = item instance
f.write("{} {} {} {} {}".format(i.name,i.quantity,i.price,i.memPrice,i.taxStatus))
def create_item(self):
name=input("Name: ")
quantity= input("Quantity: ")
price=input("Price: ")
memPrice= input("MemPrice: ")
taxStat = input("Tax Status: ")
item=Item(name, quantity, price, memPrice, taxStat)
self.items.append(item)
def display_data(self):
for i in self.items:
print(i.name,i.quantity,i.price,i.memPrice,i.taxStatus)
Hope this helps, if you have any further questions, just comment under this.
There are two main issues here:
Your code is obviously faulty, see below, and
You have made some strange design choices.
Code Error:
Your error comes from line: inventoryRead('self')
This is wrong because:
you do not write self into a class method call. It is passed by itself.
Your method call is outside of context. It is not part of another method in the class, while it obiously isn't an attribute.
Sort off "working" version of your code would be:
class Items:
''' Constructor to initilize an item object
An item has name, quantity, price, member price, and taxing status'''
def __init__(self, name=None, quantity=0, price=0, memPrice=0, taxStatus=None): # fill the default values or you will have an error in inventory function
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
def inventoryRead(self):
txt = ""
count = 0
f = open("inventory.txt", "r")
inList = []
item1 = Items() # <-- works like this only if you have defaults in your __init__ definition
print(item1)
for line in f.readlines():
item1.name = line[0:line.find(":")]
print(item1)
print(item1.name)
inList[count] = Items()
txt = line.next()
print(txt)
items = Items()
items.inventoryRead()
This would work now but it surelly isn't what you want...
Design choice
You have an Item --> make it a class
You have an inventory? --> make it a class!
Manipulate your code from within Inventory
You should really read some examples and tutorials on python OOP, since it would seem you don't really feel comfortable with how it works.
Now for a quick working example:
#!/usr/bin/env python3
class Item:
def __init__(self,name, quantity=0, price=0, memPrice=0, taxStatus=0):
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
class Inventory:
def __init__(self):
self.items = []
def inventoryRead(self):
# your function to collect items from file
if __name__ == '__main__':
inventory = Inventory()
inventory.inventoryRead()
I am trying to run some code that allows me to either call the name Student or Programmer from the class I called Master_programmer. Here is the code I used.
class Master_programmer:
capabilities = []
student = "SoloLearn Student"
programmer = "Programmer"
def Student(self):
return 'SoloLearn Student'
def Programmer(self):
return 'Programmer'
def __init__(self, name):
self.name = name
def add_capabilities(self, capability):
self.capabilities.append(capability)
m1 = Master_programmer(programmer)
print(m1.Student, m1.Programmer)
a.add_capabilities('Stay Inspired')
b.add_capabilities('Find Clients')
b.capability
After running the above code, I get the following error
Traceback (most recent call last):
File "./Playground/file0.py", line 21, in <module>
m1 = Master_programmer(programmer)
NameError: name 'programmer' is not defined
Now, my question is, how do I get my code to deliver the expected results? e.g when I request for the Name 'programmer' to be called up, I expect it to bring up Programmer and then allow me to add capabilities to the programmer like "Find Clients". And for Student it must be "Stay Inspired".
I guess the below code and its comments will answer your question.
class Master_programmer:
STATIC_VARIABLE_ONE_FOR_EVERY_INSTANCES = 'This is Static Var'
def __init__(self, name):
self.name = name
self.capabilities = []
self.student = "SoloLearn Student"
self.programmer = "Programmer"
def get_student(self):
return self.student
def get_programmer(self):
return self.programmer
def add_capabilities(self, capability):
self.capabilities.append(capability)
# Create instance for your class and name it coder (or whatever you like)
coder = Master_programmer('Replace me with student name')
# to call coder object's variable
# you need to call it by object name just like below
print('capabilities: ', coder.capabilities)
print(coder.programmer)
print(coder.student)
coder.add_capabilities('Stay Inspired')
coder.add_capabilities('Find Clients')
print(coder.get_student())
print(coder.get_programmer())
print('capabilities: ', coder.capabilities)
print()
# you can invoke Static variables usign directly class name
# you can invoke usign instance name as well but, it is not convention
print(Master_programmer.STATIC_VARIABLE_ONE_FOR_EVERY_INSTANCES)
print()
# if you change Static member, it will get change for all of your instances
coder_2 = Master_programmer('Replace me with student name')
Master_programmer.STATIC_VARIABLE_ONE_FOR_EVERY_INSTANCES = 'changed'
print()
# print static var using both ways
print(Master_programmer.STATIC_VARIABLE_ONE_FOR_EVERY_INSTANCES)
print(coder.STATIC_VARIABLE_ONE_FOR_EVERY_INSTANCES)
print(coder_2.STATIC_VARIABLE_ONE_FOR_EVERY_INSTANCES)
m1 = Master_programmer(programmer)
print(m1.Student, m1.Programmer)
Is calling the variable programmer if you wan to refer to programmer = "Programmer" in the Master_programmer class you need to use Master_programmer.programmer instead.
Though your code will later crash if you don't initialse a and b too since you need to define them too like normal variables e.g. a = Master_programmer("EEZi") to call them and/ or work with them
Thank you all for your answers. Here is the final code that I went with and it works really well. Many Thanks to you.
class Master_programmer:
STATIC_VARIABLE_ONE_FOR_EVERY_INSTANCES = 'This is Static Var'
def __init__(self, name):
self.name = name
self.capabilities = []
self.student = "SoloLearn Student"
self.programmer = "Programmer"
def get_student(self):
return self.student
def get_programmer(self):
return self.programmer
def add_capabilities(self, capability):
self.capabilities.append(capability)
coder = Master_programmer('EEZi')
coder.add_capabilities('Stay Inspired!')
coder.add_capabilities('Find Clients')
a = coder.get_student()
b = coder.get_programmer()
capabilities = coder.capabilities
for i in range(0,1):
print(a)
print("Listen here, just", coder.capabilities[0], "\n")
print(b)
print("Hustle hard and", coder.capabilities[1])
I'm coding a game in Python 3 and I need to create an unknown number of objects with each objects properties based on the contents of a file.
To explain, I'll dump some code here:
class attack(object):
def __init__(self, name, power):
self.name = name
self.element = int(power)
import getline from linecache
Attacks = []
count = 1
while 1==1:
line=getline("Attacks.txt", count)
line = line.rstrip()
if line == "":
break
else:
linelist = line.split()
#something involving "attack(linelist[1], linelist[2])"
Attacks.append(item)
count += 1
"Attacks.txt" contains this:
0 Punch 2
1 Kick 3
2 Throw 4
3 Dropkick 6
4 Uppercut 8
When the code is done, the list "Attacks" should contain 5 attack objects, one for each line of "Attacks.txt" with the listed name and power. The name is for the user only; in the code, each object will only be called for by its place in its list.
The idea is that the end user can change "Attacks.txt" (and other similar files) to add, remove or change entries; that way, they can modify my game without digging around in the actual code.
The issue is I have no idea how to create objects on the fly like this or if I even can. I already have working code that builds a list from a file; the only problem is the object creation.
My question, simply put, is how do I do this?
I had the same problem someday:
How to call class constructor having its name in text variable? [Python]
You obviously have to define classes which names are in file. I assume that is done. And you need to have them in current module namespace globals()
from somelib import Punch, Kick, Throw, Dropkick, Uppercut
globals()[class_name](x, y)
line = getline("Attacks.txt", count)
line = line.rstrip()
linelist = line.split()
class_name = linelist[1]
value = linelist[2]
class_object = globals()[class_name]
item = class_object(value)
# or shortly in one line:
# item = globals()[linelist[1]](linelist[2])
You could create a class like so providing overloading operators to support the operations:
class Operation:
def __init__(self, *header):
self.__dict__ = dict(zip(['attack', 'power'], header))
class Attack:
def __init__(self, *headers):
self.__dict__ = {"attack{}".format(i):Operation(*a) for i, a in enumerate(headers, start=1)}
def __setitem__(self, attack_type, new_power):
self.__dict__ = {a:Operation(attack_type, new_power) if b.attack == attack_type else b for a, b in self.__dict__.items()}
def __getitem__(self, attack):
return [b.power for _, b in self.__dict__.items() if b.attack == attack]
#property
def power_listings(self):
return '\n'.join(['{} {}'.format(*[b.attack, b.power]) for _, b in self.__dict__.items()])
with open('filename.txt') as f:
f = [i.strip('\n').split() for i in f]
a = Attack(*f)
print(a.power_listings)
a['Throw'] = 6 #updating the power of any occurrence of Throw
Output:
Throw 6
Kick 3
Punch 2
Uppercut 8
Dropkick 6
Very new to Python and could do with some help. How do I go about referencing members in a class?
I have two csv files. One contains a series of parts and associated material ID. The other is a material index that contains materials ID's and some information about that material.
My intention is to create a third file that contains all of the parts, their material Id's and the information if present in the material index.
I have created a class for the material index and am trying to access objects in this class using material Ids from the part file however, this is not working and I am unsure as to why. Any help is appreciated:
class material():
def __init__(self, name, ftu, e, nu):
self.name = name
self.ftu = ftu
self.e = e
self.nu = nu
def extract_FTU_Strain(input_file_parts,input_file_FTU,output_file):
parts = {}
materials = {}
for aline in open(input_file_FTU, 'r'):
comma_split = aline.strip().split(',')
name = comma_split[1]
ftu = comma_split[8]
e = comma_split[9]
nu = comma_split[7]
try:
materials[int(comma_split[0])] = material(comma_split[1],comma_split[8],comma_split[9],comma_split[7])
#materials[comma_split[0]] = material(comma_split[1],comma_split[8],comma_split[9],comma_split[7])
except:
pass
for i in open(input_file_parts, 'r'):
semicolon_split = i.strip().split(';')
material_id = semicolon_split[3]
part = semicolon_split[0]
part_id = semicolon_split[1]
material_name = materials[material_id].name
FTU = materials[material_id].ftu
Stress = materials[material_id].e
output.write(','.join([part,part_id,material_name,material_id,FTU,Stress]) + '\n')
output = open (output_file,'w')
output.write('Part Title, Part Id, Material Id, FTU, e' + '\n')
output.close()
import sys
input_file_parts = '/parttable.csv'
input_file_FTU = '/Material_Index.csv'
output_file = '/PYTHONTESTING123.csv'
extract_FTU_Strain(input_file_parts,input_file_FTU,output_file)
Since in the comments you said your error is in materials[material_id] make material_id an integer as it was an integer when you created the object.
You created it this way
materials[int(comma_split[0])]=...
But later called it without converting material_id to an int. Do this before calling it in your for loop to write in the output.
material_id = int(material_id)
I may have misinterpreted your question, but going off the line 'How do I go about referencing members in a class?' you can reference member variables like so:
class Demonstration:
def __init__(self, a, b):
self.a = a
self.b = b
def printMembers(self):
print self.a, self.b
So inside the class you can use self.someVariable to reference member variables.
If you want to access them outside of the class:
myclass.myvariable
I'll happily edit the answer if I have't quite understood your question or if there is a specific error you are getting.
I did not understand what error you have, could you put the traceback? Anyway, you are creating a class instance at the time of assignment. For more elegant programming, you could simply do:
m = materials(name, ftu, e, nu)
This way you can access the instance variables like this:
m.name
m.ftu
...
And try, except -> pass it's very dangerous
I am having some problem accessing class instances. I am calling the class from a procedure, name of instance is defined in some variable. I want the instance name to be created of that value and then want to access it, but when i access it is giving error. Can some one please help to resolve this issue.
class myclass:
def __init__(self,object):
self.name = object
def mydef():
global a1
b = "a1"
b = myclass(b)
mydef()
print a1.name
Second Problem:
In my actual script, I have to create a large number of such instances from this function (around 100). So defining their name as global would be painful, is there a way i could access those instances outside function without having to declare them as global.
Modification:
class myclass:
def __init__(self,object,typename):
self.name = object
self.typeid = typename
def mydef():
file_han = open(file,"r")
while True:
line = file_han.readline()
if not line:
break
start = line.find('"')
end = line.find('"',start+1)
string_f = line[start+1:end]
myclass(string_f,'a11')
mydef(file)
print def.name
print def.typeid
File Contents are :
a11 "def"
a11 "ghi"
a11 "eff"
Here's how I'd do it. I don't know why you're messing around with globals, if you'd care to explain, I'll update my answer.
class Myclass(object):
def __init__(self, name):
self.name = name
def mydef():
return Myclass("a1")
a1 = mydef()
print a1.name
Gather your instances in a list:
instances = []
for x in range(1000):
instances.append(Myclass("Instance {0}".format(x)))
print instance[42].name
Note the changes:
Class names should be capitalized
Use object as the base class of your classes (since python 2.2, but no longer necessary in 3.x)
Don't shadow the built-in object with your parameter name
Just use the string "a1" directly as a parameter instead of assigning it to a variable
Return something from the function instead of passing the result by global variable
RE: Comment
You haven't said anything about the format of these files, so I'll just give an example where the file to be read contains one class name per line, and nothing else:
def mydef(filename):
ret = []
with open(filename) as f:
for line in f:
# Call `strip` on line to remove newline and surrounding whitespace
ret.append(Myclass(line.strip()))
return ret
So if you have several files and wish to add all your instances from all your files to a large list, do it like this:
instances = []
for filename in ["myfile1", "myfile2", "myfile3"]:
instances.extend(mydef(filename))
RE: OP Edit
def mydef(filename):
ret = []
with open(filename, "r") as file_han:
for line in file_han:
string_f = line.split('"')[1]
ret.append(Myclass(string_f))
return ret
i = mydef("name_of_file")
RE: Comment
Oh, you want to access them by name. Then return a dict instead:
def mydef(filename):
ret = {}
with open(filename, "r") as file_han:
for line in file_han:
string_f = line.split('"')[1]
ret[string_f] = Myclass(string_f)
return ret
i = mydef("name_of_file")
print i["ghi"].name # should print "ghi"
RE: Comment
If I understand you correctly, you want to have it both ways -- index by both line number and name. Well then why don't you return both a list and a dictionary?
def mydef(filename):
d = {}
L = []
with open(filename, "r") as file_han:
for line in file_han:
string_f = line.split('"')[1]
instance = Myclass(string_f)
d[string_f] = instance
L.append(instance)
return L, d
L, d = mydef("name_of_file")
print d["ghi"].name
print L[3]
print L.index(d["ghi"])
You could use class as repository for your instances, for example
class Named(object):
def __init__(self,name):
self.name = name
def __new__(cls,name):
instance = super(type,cls).__new__(cls,name)
setattr(cls,name,instance)
return instance
def __repr__(self):
return 'Named[%s]'%self.name
Named('hello')
Named('x123')
Named('this is not valid attribute name, but also working')
print(Named.hello,Named.x123,getattr(Named,'this is not valid attribute name, but also working'))