I am trying to teach myself Python and have created a file which runs through various questions sets spread out across classes. At the end of this file I want to summarise all of my raw inputs.
Unfortunately, I am struggling to access these values from a separate class. I have broken my coding down into a test example to demonstrate the structure of my program:
class QuestionSet(object):
next_set = 'first_set'
class ClaimEngine(QuestionSet):
def current_set(self):
last_set = "blank"
while_count = int(0)
quizset = Sets.subsets
ParentSet = QuestionSet()
while ParentSet.next_set != last_set and int(while_count)<50:
quizset[ParentSet.next_set].questioning()
while_count = while_count+1
class FirstSet(QuestionSet):
def questioning(self):
value1 = raw_input("Val1")
QuestionSet.next_set = "second_set"
class SecondSet(QuestionSet):
def questioning(self):
value2 = raw_input("Val2")
QuestionSet.next_set = "summary"
class Summary(QuestionSet):
print "test"
## I need to print a summary of my inputs here ##
## e.g. Print "The answer to value1 was:%r" %value1##
class Sets(object):
subsets = {
'first_set': FirstSet(),
'second_set': SecondSet(),
'summary': Summary()
}
I have tried defining within the Summary each class e.g. 1stSet = FirstSet() and then FirstSet.value1 etc but to no avail.
If anyone has any suggestions on how to retrieve these values that would be great as I have written a massive program full of questions and have fallen at the last hurdle!
Thank you.
The values you have in each function of the classes are not created as class members. For your application you need to create member variables which store the values within the class.
For example:
class FirstSet(QuestionSet):
def questioning(self):
self.value1 = raw_input("Val1")
QuestionSet.next_set = "second_set"
Now value1 is a member variable you can access it.
In the case of the example you have above it would probably be something like the line below to access the value1 from 'first_set'
subsets['first_set'].value1
If you're not familiar with this try
this tutorial
Related
New to OOP and python, I am struggling enormously to grasp what good classes actually are for. I tried to ask help from a lecturer who said "oh, then you should read about general methods to classes". Been putting in a days work but get no where.
I get it that a class allow you to collect an instance structure and methods to it, like this:
class Items:
def __init__(self, item_id, item_name):
self.item_id = item_id
self.item_name = item_name
def show_list(self):
print(self.item_id, self.item_name)
idA = Items("idA", "A")
idA.show_list()
But what is even the point of a class if there were not MANY instances you would classify? If I have a method within the class, I must hard code the actual instance to call the class for. What if you want a user to search and select an instance, to then do operations to (e.g. print, compute or whatever)??
I thought of doing it like this:
class Items:
def __init__(self, item_id, item_name):
self.item_id = item_id
self.item_name = item_name
def show_list(self):
print(self.item_id, self.item_name)
idA = Items("idA", "A")
idB = Items("idB", "B")
select_item = input("enter item id")
select_item.show_list()
Replacing hard coded variable with input variable doesn't work, probably logically. I then played with the idea of doing it like this:
class Items:
def __init__(self, item_id, item_name):
self.item_id = item_id
self.item_name = item_name
iL = [Items('idA', 'A'), Items('idB', 'B')]
selected_item = input("enter item id")
for selected_item in iL:
print(f'{selected_item.item_id} {selected_item.item_name}')
Now all are called thanks to making it a list instead of separate instances, but how do I actually apply code to filter and only use one instance in the list (dynamically, based on input)?
I would love the one who brought me sense to classes. You guys who work interactively with large data sets must do something what I today believe exist in another dimension.
See examples above^^
It seems you want to find all the instances of a certain element within a class.
This is as simple as:
print([x for x in iL if x.item_id == selected_item])
Now, you may ask why you can't just store the elements of iL as tuples instead of classes. The answer is, you can, but
("idA", "A")
is much less descriptive than:
item_id = "idA"
item_name = "A"
Any code you write with classes, you should in theory be able to write without classes. Classes are for the benefit of the coder, not the end-user of the program. They serve to make the program more readable, which I'm sure you'll find is a desirable property.
Your point here is to lookup for Items instances based on their item_id attribute.
That's a thing to create instances of a class.
It's a completely different thing to search for items objects stored in memory - that is not directly linked to the concept of OOP, classes and instances.
You could use dictionary to store references of your objects and then lookup in your dictionary.
class Items:
def __init__(self, item_id, item_name):
self.item_id = item_id
self.item_name = item_name
def show_list(self):
print(self.item_id, self.item_name)
idA = Items("idA", "A")
idB = Items("idB", "B")
lookup_dict = {"idA": idA, "idB": idB}
select_item = input("enter item id")
found_item = lookup_dict.get(select_item)
if found_item:
found_item.show_list()
else:
print(f"item {select_item} not found")
Apologies if I explain something wrong or use the wrong wording, my programmer vocabulary isn't the best. If anyone understands my problem and has better ways of explaining it feel free to do so. I have a problem similar to a problem here. I want to remove items from a list that occur in another list. But one list will have strings that reference the variable "name" within class objects.
class sword:
name = 'swordName'
class bow:
name = 'bowName'
class axe:
name = 'axeName'
inventory = [sword, bow, sword, axe]
select = ['bowName', 'swordName']
I want to be able to create a list "selectedItems" with the class objects out of inventory based off of the strings in "select" that are equal to the "name" of the class objects. It also needs to work if "inventory" and "select" both have duplicates in them.
Output:
>> inventory = [bow, axe]
>> selectedItems = [bow, sword]
One other thing I would like the program to ignore if there are more "name"s in select than there are corresponding class objects in "inventory", and to ignore if a string in "select" has no corresponding class objects.
For example, if "inventory" is [sword, axe] and "select" is ['bowName', 'non-existent', 'axeName'], the result is that "inventory" is [sword] and "selectedItems" is [axe].
A simple way of explaining this is that select will take from inventory, but if select can't take from inventory nothing happens.
You may make base class with magic methods __eq__ and __hash__ which can allow you to manage comparing your objects as you want:
class BaseItem:
name = None
def __init__(self):
self.__name = self.name
def __eq__(self, other):
return self.__name == other
def __hash__(self):
return id(self.__name)
def __repr__(self):
return f"'{self.__name}'"
class Sword(BaseItem):
name = "swordName"
class Bow(BaseItem):
name = "bowName"
class Axe(BaseItem):
name = "axeName"
inventory = [Sword(), Bow()]
select = ["swordName", "bowName", "axeName", "swordName", "bowName"]
# casting lists into sets and getting difference between them
result = set(inventory) - set(select)
print(result) # output {'swordName', 'bowName'}
eq - actually is unused here but i added that you can compare your objects with strings, lists etc:
Sword() in ["swordName"] # true
Sword() in ["bowName"] # false
Sword() == "swordName" # true
Sword() == "bowName" # false
hash - need to comparing two objects, actually it use for getting difference between two sets
repr - it is not really required method, it needs just for pretty displaying of objects
selectedItems = list()
# make a new list of the names of the objects in the inventory
# inventory and inventory names have the same index for the same item
inventory_names = [x.name for x in inventory]
for s in select:
if s in inventory_names:
index = inventory_names.index(s)
inventory_names.pop(index)
selectedItems.append(inventory.pop(index))
I have been researching for ages and cannot find this specific question being asked (so perhaps I am missing something simple!) but I have had trouble separating classes into different .py files.
Scenario:
Main class imports a Settings class file and a Work class file..Settings class populates a list with objects instantiated from an Object class file...
Work class wants to cycle through that list and change values within each of those objects. <-- here is where I come unstuck.
I have tried it by making the values class variables rather than instance. Still I have to import the settings class in the work class in order to write the code to access the value to change. But it wont change the instance of that class within the main class where all these classes are called!
I read an article on Properties. The examples they gave were still examples of different classes within the same file.
Any advice as to what I should be looking at would be greatly appreciated!
This is what I was doing to test it out:
Main File where all will be run from:
import Set_Test
import Test_Code
sting = Set_Test.Settings()
tc = Test_Code.Testy()
ID = sting._settingsID
print(f'Settings ID is: {ID}')
tc.changeVal()
ID = sting._settingsID
print(f'Settings ID is: {ID}')
Set_Test.py:
class Settings:
def __init__(self):
self._settingsID = 1
#property
def settingsID(self):
return self._settingsID
#settingsID.setter
def settingsID(self, value):
self.settingsID = value
Test_Code.py:
import Set_Test
class Testy:
def changeVal(self):
Set_Test.Settings.settingsID = 8
Thanks to stovfl who provided the answer in comments. I managed to decipher what stovfl meant eventually :D
I think!
Well the below code works for anyone who wants to know:
Main:
import Set_Test
import Test_Code
sting = Set_Test.Settings()
tc = Test_Code.Testy()
ID = sting._settingsID
print(f'Settings ID is: {ID}')
tc.changeVal(sting)
ID = sting._settingsID
print(f'Settings ID is: {ID}')
Set_Test.py:
class Settings:
def __init__(self):
self._settingsID = 1
#property
def settingsID(self):
return self._settingsID
#settingsID.setter
def settingsID(self, value):
self._settingsID = value
Test_Code.py
import Set_Test
sting = Set_Test.Settings()
class Testy():
def changeVal(self, sting):
print(sting.settingsID)
sting.settingsID = 8
print(sting.settingsID)
I am trying to change my code to a more object oriented format. In doing so I am lost on how to 'visualize' what is happening with multiprocessing and how to solve it. On the one hand, the class should track changes to local variables across functions, but on the other I believe multiprocessing creates a copy of the code which the original instance would not have access to. I need to figure out a way to manipulate classes, within a class, using multiprocessing, and have the parent class retain all manipulated values in the nested classes.
A simple version (OLD CODE):
function runMultProc():
...
dictReports = {}
listReports = ['reportName1.txt', 'reportName2.txt']
tasks = []
pool = multiprocessing.Pool()
for report in listReports:
if report not in dictReports:
dictReports[today][report] = {}
tasks.append(pool.apply_async(worker, args=([report, dictReports[today][report]])))
else:
continue
for task in tasks:
report, currentReportDict = task.get()
dictReports[report] = currentFileDict
function worker(report, currentReportDict):
<Manipulate_reports_dict>
return report, currentReportDict
NEW CODE:
class Transfer():
def __init__(self):
self.masterReportDictionary[<todays_date>] = [reportObj1, reportObj2]
def processReports(self):
self.pool = multiprocessing.Pool()
self.pool.map(processWorker, self.masterReportDictionary[<todays_date>])
self.pool.close()
self.pool.join()
def processWorker(self, report):
# **process and manipulate report, currently no return**
report.name = 'foo'
report.path = '/path/to/report'
class Report():
def init(self):
self.name = ''
self.path = ''
self.errors = {}
self.runTime = ''
self.timeProcessed = ''
self.hashes = {}
self.attempts = 0
I don't think this code does what I need it to do, which is to have it process the list of reports in parallel AND, as processWorker manipulates each report class object, store those results. As I am fairly new to this I was hoping someone could help.
The big difference between the two is that the first one build a dictionary and returned it. The second model shouldn't really be returning anything, I just need for the classes to finish being processed and they should have relevant information within them.
Thanks!
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