I am trying to implement Genetic Algorithm and I am new to python and i am trying to build a Python class Gene with the following as properties
Gene has Portid,trt,days
And a second class Chromosome with 20 Gene objects as its property
Chromosome has gene1,gene2,gene3...gene20
As shown in this diagram UML Diagram Any help please
I have tried
import random
class Gene:
def __init__(self,id):
self.id=id
self.nb_trax=random.randint(1,10)
self.nb_days=random.randint(50,100)
class Chromosome(object):
def __init__(self,object):
self.port[i] = [Gene(id) for i in range (20)]
g=Gene('China')
f=Chromosome(g)
and i get an error
f=Chromosome(g)
File "chrom.py", line 11, in __init__
self.port[i] = [Gene(id) for i in range (20)]
AttributeError: 'Chromosome' object has no attribute 'port'
Try the following code. Python 3 does not need (object) hierarchy for classes. You were also using it as a parameter that you were not using so I also deleted it from there. And the part inside the square bracke3ts [] laready creates the list so you don't need to assign it to self.port[i] but to self.port directly.
import random
class Gene:
def __init__(self, id):
self.id = id
self.nb_trax = random.randint(1, 10)
self.nb_days = random.randint(50, 100)
class Chromosome:
def __init__(self):
self.port = [Gene(id) for id in range(20)]
Related
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'm trying to use class objects in a list for the first time. But for some reason, the attributes of all class objects in the list are getting assigned the same value as the last object in the list. Here's my code:
# First I define the class
class Batsman:
def __init__(self, innings, avg, sr):
Batsman.innings = innings
Batsman.avg = avg
Batsman.sr = sr
# Then I create the list of class objects:
batsman = [
Batsman(100,45,65),
Batsman(50,40,60)
]
# Then I print the below:
print(batsman[0].innings)
Output should be 100, but it is 50 instead. Why is this?
If I use 5 instances, the attributes of all 5 get reset to whatever the last object contains. Why is this?
When using the name of the class Batsman you are refering to the class not the instance, you need to use self:
class Batsman:
def __init__(self, innings, avg, sr):
self.innings = innings
self.avg = avg
self.sr = sr
# Then I create the list of class objects:
batsman = [
Batsman(100,45,65),
Batsman(50,40,60)
]
# Then I print the below:
print(batsman[0].innings)
You can check some extra explanations and inforamtion about self in this other question
I have a file called Model.py that contains the code
class ModelCalibrator():
def __init__(self):
self.file1 = 'Mortality_Population.txt'
self.file2 = 'Deaths_1x1_adj.txt'
self.MaxAge = 101
self.MinAge = 18
self.basisAges = np.array([18, 50, 100])[np.newaxis]
self.mortalityData = PopulationData()
self.deathRateData = DeathRateData()
(self.age, self.phis) = computeBasisFunctions(ModelCalibrator)
def computeBasisFunctions(mc):
MaxAge = mc.MaxAge
MinAge = mc.MinAge
age = np.arange(MinAge, MaxAge)[np.newaxis]
basisAges = mc.basisAges
#calculations
...
return (age, phis)
In a separate test.py file I am running nosetests using the code
def testMC():
data = ModelCalibrator()
Phi = data.phis()
assert_equal(Phi[0], 1)
This keeps telling me that I have an attributeerror: type object 'ModelCalibrator' has no attributes 'MaxAge'. Can anyone tell me where I am going wrong please?
On this line, you are passing in the class instead of the object. Try replacing ModelCalibrator with self. The class is only a template for the object. self represents the current object with all of the properties set.
(self.age, self.phis) = computeBasisFunctions(self)
Alternatively, if you want these to be accessible without an object, you could set MaxAge and MinAge as class variables by moving them outside of the __init__ function, but inside the class as shown here.
Edited:
I want to generate N-number of agents. Each agent will have a name, so I create a random name from names and assigned it to class Agent.
After I run the model, I want to get the list of my agents name.
This is from mesa:
import names
from mesa import Agent, Model
from mesa.time import RandomActivation
class Agent(Agent):
def __init__(self, name):
self.name= names.get_full_name()
self.wealth = 1
def step(self):
pass
class Model(Model):
def __init__(self, N):
self.num_agents = N
self.schedule = RandomActivation(self)
for i in range(N):
a = MoneyAgent(i)
self.schedule.add(a)
def step(self):
self.schedule.step()
on interactive session
gow = MoneyModel(10)
gow.step()
atr = list([a for a in MoneyAgent.name])
print(atr)
I got this error:
File "C:\src__init__.py", line 7, in
atr = list([a for a in MoneyAgent.name])
AttributeError: type object 'MoneyAgent' has no attribute 'name'
How to fix it?
Here's my interpretation of your problem: You're creating a MoneyModel object which contains a collection of MoneyAgent objects stored in a collection-like object referred to as MoneyModel.schedule, and you want a list of the names of each MoneyAgent object within your MoneyModel.schedule collection.
Assuming MoneyModel.schedule behaves as an iterable object, the following should work:
atr = [agent.name for agent in gow.schedule]
I'm intending to create a data distributor class as a mutable class:
class DataDistributor(object):
def __init__(self):
self.target_trackid = -1
def next_sen(self):
self.target_trackid += 1
return self.target_trackid
So that I can globally keep a pointer on my data.
I have another class:
class Env(object):
def __init__(self, distributor):
self.distributor = distributor
self.target_trackid = 0 # init
def reset(self):
self.target_trackid = self.distributor.next_sen()
So that when I create many Env instances, each Env instance will get a different data point.
So I use this to create my instances:
ddist = DataDistributor()
env = Env(ddist)
envs = [pickle.loads(pickle.dumps(env)) for _ in range(12)]
envs[0].reset()
envs[1].reset()
envs[2].reset()
print envs[0].target_trackid
print envs[1].target_trackid
print envs[2].target_trackid
And the results are all the same: a bunch of 0s.
I'm not exactly sure how Python is handling this :( and if there is a viable solution to achieve what I want to achieve!
How about creating a class variable for keeping track of the objects created? Your simple class structure will be like:
class Env(object):
my_counter = 0 # Your class variable
def __init__(self, param1, param2):
# some initialization
Env.my_counter += 1 # increament everytime object is created
# some logic
Sample run:
>>> e1 = Env('p11', 'p12') # creation of first object
>>> Env.my_counter
1 # value of counter set as 1
>>> e1 = Env('p21', '22') # creation of second object
>>> Env.my_counter
2 # value of counter set as 2
Passing object of different class just for tracking the created object of some other class, it is definitely not the right approach.
pickle.load will create different objects which means the datadistributor variable in each env object will refere