class Swimmers:
""" Creates objects for each swimmer with unique details"""
instances = []
def __init__(self, fName = "None", lName = "None", house = "None", time = "None"):
self.fName = getfName()
self.lName = getlName()
self.house = getHouse()
self.time = getTime()
self.__class__.instances.append(self)
#classmethod
def printInstances(cls):
for instance in cls.instances:
print(instance)
def test():
style, swimmerNumber = raceDetails()
for x in range(int(swimmerNumber)):
y = re.sub(".0", "", str(x))
string = "swimmer" + y
print("\n" + string + "\n")
string = Swimmers()
x -= 1
I need to create a module that takes various inputs and saves each iteration as a class object. The function raceDetails() simply gets the type of race and the number of swimmers, nothing wrong with that part. The functions getX() are simply input functions with some error checking. The issue is that trying to call the objects or any of their variables after everything has been entered simply gives me:
>>> swimmer0.fName
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
swimmer0.fName
NameError: name 'swimmer0' is not defined
I've added a list of every object created by the class ('instances') which prints:
<__main__.Swimmers object at 0x04182F88>
<__main__.Swimmers object at 0x04182E50>
and so on, which, combined with the working getX() functions, means the objects are being instantiated perfectly fine. I've tried everything I can think of, including nonlocals, changing scopes, adding intermediary functions, but none of it seems to work. The only thing I can think of is an issue with reference generation in the module namespace.
It's not essential that I use classes for this, and I could very easily use dictionaries or the like, but I want to try and learn classes as best as I can.
Using Windows 10, Python 3.9.2 32-bit
The problem is you're setting the string variable equal to the variable name you want ('swimmer0', 'swimmer1'...), but then you set string equal to the Swimmers class. Dynamically setting variables names is possible in python, but typically you'll want to use a dictionary (or another collections object) to store the objects.
def test():
style, swimmerNumber = raceDetails()
swimmers_dict = {}
for x in range(int(swimmerNumber)):
y = re.sub(".0", "", str(x))
string = "swimmer" + y
print("\n" + string + "\n")
swimmers_dict[x] = Swimmers()
x -= 1
return swimmers_dict
Related
So I have 2 different classes in python created in CDK.
one class is LambdaAutomationTaskStack that creates few lambda functions and links them to step functions task using lambda invoke.
so in short LambdaAutomationTaskStack creates a list type variable lambda_attached_task_names that contains lists of tasks associated with the lambdas.
class LambdaAutomationTaskStack(cdk.Stack):
def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
self.lambda_attached_task_names = list()
self.lambda_attached_task_names.append(self.prepare_check_lambda_function_a())
self.lambda_attached_task_names.append(self.prepare_check_lambda_function_b())
def prepare_check_lambda_function_a(self):
check_lambda_function_a = _lambda.Function(self, 'lambda_function_a',
code=_lambda.Code.from_asset('lambdas/lambda_function_a'),
handler='lambda_function_a.handler',
function_name=f'lambda_function_a',
runtime=_lambda.Runtime.PYTHON_3_8,
timeout=cdk.Duration.seconds(30),
)
check_lambda_function_a_as_task = sfn_tasks.LambdaInvoke(self, 'check_lambda_function_a_as_task',
lambda_function=check_lambda_function_a,
result_path='$.check_function_a')
return check_lambda_function_a_as_task
def prepare_check_lambda_function_b(self):
check_lambda_function_b = _lambda.Function(self, 'lambda_function_b',
code=_lambda.Code.from_asset('lambdas/lambda_function_b'),
handler='lambda_function_b.handler',
function_name=f'lambda_function_b',
runtime=_lambda.Runtime.PYTHON_3_8,
timeout=cdk.Duration.seconds(30),
)
check_lambda_function_b_as_task = sfn_tasks.LambdaInvoke(self, 'check_lambda_function_b_as_task',
lambda_function=check_lambda_function_b,
result_path='$.check_function_b')
return check_lambda_function_b_as_task
Another class StepFunctionAutomationStack accepts this list of tasks variable lambda_attached_task_names as part of the input to the step-function cdk stack.
Now in this class how I have created a definition like below:
Let say my lambda_attached_task_names has 2 values it should create definition like this:
definition = sfn.Chain.start(check_lambda_function_a_as_task)\
.next(check_lambda_function_b_as_task)
Let's say I have 5 tasks in my lambda_attached_task_names then definition should looks like this:
So, I made the change to create the definition like this:
definition = "sfn.Chain.start"
for index, value in enumerate(task_details):
if index == 0:
definition += "(" + str(value) + ")"
elif index < len(task_details) - 1:
definition += ".next(" + str(value) + ")"
else:
definition += ".next(" + str(value) + ")"
Now, If I passed this to my state machine:
sfn.StateMachine(
self, "StateMachine",
definition=definition,
timeout=cdk.Duration.seconds(30),
state_machine_name='anl-some-stack'
)
Now, this throws me
jsii.errors.JSIIError: Expected object reference, got "sfn.Chain.start(<aws_cdk.aws_stepfunctions_tasks.LambdaInvoke object at 0x7f0f666da650>).next(<aws_cdk.aws_stepfunctions_tasks.LambdaInvoke object at 0x7f0f672daad0>)"
So, how can I get the actual task associated in class LambdaAutomationTaskStack to class StepFunctionAutomationStack, not as an object?
These two classes are called and reference in the main python app.py
Update:
I tried to check the value using this agian in my main app.py
for index, value in enumerate(lambda_automation_stack.lambda_attached_task_names):
print(value.__dict__)
this gives me like this:
{'__jsii_ref__': CreateResponse(ref='#aws-cdk/aws-stepfunctions-tasks.LambdaInvoke#10013', interfaces=None)}
{'__jsii_ref__': CreateResponse(ref='#aws-cdk/aws-stepfunctions-tasks.LambdaInvoke#10018', interfaces=None)}
but If I combine these 2 classes in one class they all work fine.
I typically write CDK code in Typescript, not Python, so bear with me.
It appears you are creating a string for your definition, but the StateMachineProps.Definition property is expecting an IChainable object.
Your code as a result should be constructing a workflow and not a string, something like (forgive me, this is untested):
definition = sfn.Chain.start(check_lambda_function_a_as_task)
current_step = definition
for index, value in enumerate(task_details):#assuming task_details is an IChainable object
current_step.next(value)
current_step = value
#and leave this code the same
sfn.StateMachine(
self, "StateMachine",
definition=definition,
timeout=cdk.Duration.seconds(30),
state_machine_name='anl-some-stack'
)
New to python and OOP. Hopefully I'm using the correct terms. I'm using a list to hold all of my objects. I want to reference this list to get the name of the object that I would like to get a property value for. I then want to pass this name to a function to get one or more properties. But I'm getting a string error (because the list is returning a string of the object name and not the actual object).
Here is the code:
class creature():
def __init__(self, name, legs):
self.name = name
self.legs = legs
rat = creature("rat",4)
mouse = creature("mouse",4)
beaver = creature("beaver",4)
squirrel = creature("squirrel",4)
chimpanzee = creature("chimpanzee",2)
gorilla = creature("gorilla",2)
orangutan = creature("orangutan",2)
spider_monkey = creature("spider_monkey",2)
black_widow = creature("black_widow",8)
recluse = creature("recluse",8)
wolf_spider = creature("wolf_spider",8)
daddy_long_leg = creature("daddy_long_leg",8)
def checkLegs(critter):
nbrLegs = critter.legs
return success
animals = [
['rat', 'mouse', 'beaver', 'squirrel'],
['chimpanzee','gorilla','orangutan','spider_monkey'],
['black_widow','recluse','wolf_spider','daddy_long_leg']
]
numberOfLegs = checkLegs(recluse)
print("The Recluse has: ")
print(numberOfLegs)
print(" legs")
Here is the response:
The test animal is: orangutan
Traceback (most recent call last):
File "/Python37/help.py", line 32, in <module>
numberOfLegs = checkLegs(testAnimal)
File "Python37/help.py", line 20, in checkLegs
nbrLegs = critter.legs
AttributeError: 'str' object has no attribute 'legs'
There's a couple things here that are preventing this from working. Look at your checkLegs function. It is returning something called success...however, that's not being used anywhere, and since you haven't wrapped it in ""s (I assume you were trying to return the word success to check if the function works) it is trying to return it as a variable, but of course it's undefined. You want the function to return the result of the code you use the function to execute. In this case you want to return nbrLegs. You also need to check the indentation of your constructor. You also don't need the array of animals since you're already defining them in your class. Other than that you were pretty close. Here's your code, with the fixes implemented:
class creature():
def __init__(self, name, legs):
self.name = name
self.legs = legs
rat = creature("rat",4)
mouse = creature("mouse",4)
beaver = creature("beaver",4)
squirrel = creature("squirrel",4)
chimpanzee = creature("chimpanzee",2)
gorilla = creature("gorilla",2)
orangutan = creature("orangutan",2)
spider_monkey = creature("spider_monkey",2)
black_widow = creature("black_widow",8)
recluse = creature("recluse",8)
wolf_spider = creature("wolf_spider",8)
daddy_long_leg = creature("daddy_long_leg",8)
def checkLegs(critter):
nbrLegs = critter.legs
return nbrLegs
numberOfLegs = checkLegs(recluse)
print("The Recluse has: " + str(numberOfLegs) + " legs")
So, I'm trying to get this code to work in a cleaner way, mainly, through the use of a for loop, but having a really hard time trying to do so. I haven't been able to make a loop that assigns each value of the dictionary to a correspondent variable, so it can be used in the class. For context, the dictionary contains values obtained from another class, I just put those in the dict and sent it to this class, so I don't need to calculate those again.
def get_ipr_data(self):
self.reservoir_result_dict = ReservoirDataFrame.reservoir_result_dict
self.pb = self.reservoir_result_dict.get("pb")
self.rs = self.reservoir_result_dict.get("rs")
self.bo = self.reservoir_result_dict.get("bo")
self.uo = self.reservoir_result_dict.get("uo")
self.re = self.reservoir_result_dict.get("re")
self.j_index = self.reservoir_result_dict.get("j_index")
self.q_max = self.reservoir_result_dict.get("q_max")
self.pws = self.reservoir_result_dict.get("pws")
self.qb = self.reservoir_result_dict.get("qb")
You can use setattr function
for name in ["pb", "rs", "bo", "uo", "re", "j_index", "q_max", "pws", "qb"]:
setattr(self, name, self.reservoir_result_dict.get(name))
Documentation of setattr:
https://docs.python.org/3/library/functions.html#setattr
Delegating attributes is done by defining the __getattr__ method. You should store the dictionary only and then define __getattr__.
class Foo:
...
def get_ipr_data(self):
self.reservoir_result_dict = ReservoirDataFrame.reservoir_result_dict
def __getattr__(self, item):
return self.reservoir_result_dict[item]
Say I have an entry form for a GUI window that asks for a new setting and a value for that setting, which it then passes to another object that manages settings and expects **kwargs as input:
class SettingsForm(someFormClass):
def onSubmit(self):
new_setting = self.content['new setting'].get()
new_value = self.content['value'].get()
settings_instance.add_setting(new_setting=new_value)
This sets new_value to the literal string 'new_setting'. I've tried various ways to get around this, such as using a dictionary:
class SettingsForm(someFormClass):
def onSubmit(self):
new_setting = self.content['new setting'].get()
new_value = self.content['value'].get()
mydict = {}
mydict[new_setting] = new_value
settings_instance.add_setting(**mydict)
This works, but doesn't make much sense for a single pair of values... is there an obvious way that I'm missing?
This question already has answers here:
Why does comparing strings using either '==' or 'is' sometimes produce a different result?
(15 answers)
Closed 8 years ago.
So I am pretty new to python so be kind.
I am trying to create a global sort of object directory as a base for all my programs as a means to keep track of all created object instances in my programs.
so..
I create a class that holds a list of object references ( not id's ).
example:
class objDirectory:
name = ""
count = 0
objDir = []
def __init__( self ):
print( "Initiating object directory." )
name = "objDirectory"
self.count= 1
self.objDir = [ self ]
return
def getObj( self, name ):
print( "Searching directory for:", name )
for o in self.objDir:
if o.name is name:
print( "Returning:", name )
return obj
else:
print( "Search failed" )
return
But, once an object is added to a list and I run the get script it does not return my object. I even verify by using directory.objDir[x]. ( this always references my object) .
What am I not doing, or doing wrong?
Thanks.
Results:
setDirectory()
Initiating object directory.
Global directory reference set
test = obj( "test" )
Initiating: test
Duplicate check
Logging: test1
Object count: 2
t1 = directory.getObj( "test1" )
Searching directory for: test1
Search failed
print( directory.objDir )
[<main.objDirectory object at 0x032C86F0>, <main.obj object at 0x032C8710>]
I don't quite understand how you plan to use this object, however I find that there are a few problems with the __init__ method.
First of all, I guess that your object should be a singleton, however it is not. You define the class attributes here:
class objDirectory:
name = ""
count = 0
objDir = []
But in your __init__ method you always override them, instead of adding to them. This means that every time you will write something like a=objDirectory(), count will be set to 1 for that instance. Also, notice that (at least in python2.7), you'll need a #classmethod decorator for every function you wish be able to modify class attributes (as opposed to the instance's attributes). Like so:
class objDirectory:
count=0
#classmethod
def add_object(cls):
cls.count+=1
def __init__(self):
self.add_object()
This goes for objDir as well.
Second, in your __init__ method, you have a variable called name, which is never used. Perhaps you meant self.name?
There are better ways to implement singletons, however here is a simple example that might be easier to understand if you're new to python:
class mySingleton(object):
singletonObject = None
def __new__(cls):
if not cls.singletonObject:
cls.singletonObject = super(mySingleton, cls).__new__(cls)
return cls.singletonObject
The __new__ method is a static method which creates the actual instance. The return value is the new instance created. Overriding it like so will let me get the same instance for each call to mySingleton(); the statement mySingleton() is mySingleton() will always be true.