Printing attributes outside of a class getattr Python - python-3.x

I am trying to print out result1.key and result2.key by using the getattr. However I cannot get the last print function to work. I get the Error: NameError: name 'key' is not defined. How would I be able to make the print functions print(getattr(result1, key)) print(getattr(result2, key)) work to get the Expected Output?
results = ["result1", "result2"]
valuelist1 = [3, 5]
valuelist2 = [10, 6]
def func(val, val2):
return val* val2 + val2/2
class Dummy:
def __init__(self, val, val2):
self.key = func(val, val2)
for counter, runs in enumerate(results):
dummy = Dummy(valuelist1[counter], valuelist2[counter])
globals()[runs] = dummy
print(result1.key)
print(result2.key)
for name in results:
print(getattr(name, "key"))
Expected output:
35.0
33.0
35.0
33.0

You assign the Dummy instance to the globals(). So you need to access them in the same way, because name is only the string/name of your variable (in the global scope).
Do
for name in results:
print(globals()[name].key)
or
for name in results:
print(getattr(globals()[name], "key"))
or (but in general I wouldn't recommend to use eval(), only mentioned as another possible way for the sake of completeness)
for name in results:
print(eval(name).key)

Related

How can I make an Enum that allows reused keys? [duplicate]

I'm trying to get the name of a enum given one of its multiple values:
class DType(Enum):
float32 = ["f", 8]
double64 = ["d", 9]
when I try to get one value giving the name it works:
print DType["float32"].value[1] # prints 8
print DType["float32"].value[0] # prints f
but when I try to get the name out of a given value only errors will come:
print DataType(8).name
print DataType("f").name
raise ValueError("%s is not a valid %s" % (value, cls.name))
ValueError: 8 is not a valid DataType
ValueError: f is not a valid DataType
Is there a way to make this? Or am I using the wrong data structure?
The easiest way is to use the aenum library1, which would look like this:
from aenum import MultiValueEnum
class DType(MultiValueEnum):
float32 = "f", 8
double64 = "d", 9
and in use:
>>> DType("f")
<DType.float32: 'f'>
>>> DType(9)
<DType.double64: 'd'>
As you can see, the first value listed is the canonical value, and shows up in the repr().
If you want all the possible values to show up, or need to use the stdlib Enum (Python 3.4+), then the answer found here is the basis of what you want (and will also work with aenum):
class DType(Enum):
float32 = "f", 8
double64 = "d", 9
def __new__(cls, *values):
obj = object.__new__(cls)
# first value is canonical value
obj._value_ = values[0]
for other_value in values[1:]:
cls._value2member_map_[other_value] = obj
obj._all_values = values
return obj
def __repr__(self):
return '<%s.%s: %s>' % (
self.__class__.__name__,
self._name_,
', '.join([repr(v) for v in self._all_values]),
)
and in use:
>>> DType("f")
<DType.float32: 'f', 8>
>>> Dtype(9)
<DType.float32: 'd', 9>
1 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

python: any way to print the recent variable defined

I have sample code
a=10
print(recent_variable) -- it should print value of a
b=20
print(recent_variable) -- it should print value of b
c = [10,12]
print(recent_variable) -- it should print value of c
d= somfunc()
print(recent_variable) -- it should print value of d
any possible way of doing this
Intead of writing the python variable name in the print i can just put print(some syntax to show the recent variable) and it prints it value`
If you had a very narrow use case in mind you could create your own memoized assignment function that keeps track of the last value assigned through it (see below). As a general solution, of course, that approach would not be appropriate.
Example:
import random
def memo_assign(value):
if not getattr(memo_assign, "last_value", None):
memo_assign.last_value = None
memo_assign.last_value = value
return value
a = memo_assign(10)
print(a, memo_assign.last_value)
b = memo_assign(20)
print(b, memo_assign.last_value)
c = memo_assign([10,12])
print(c, memo_assign.last_value)
d = memo_assign(random.randint(1, 100))
print(d, memo_assign.last_value)
Output:
10 10
20 20
[10, 12] [10, 12]
9 9

Is there a way to extract function parameters from a dictionary?

I am trying to create some more functional code in Python and I want to know if it is possible to transform dictionary (key,values) to pass as a function parameter.
I am currently doing this in a more imperative way, where I filter and then manually extract each key depending on the result of the filter. My current code:
def a(i: int, config: dict):
function_array = [function1, function2, function3]
selected = function_array[i]
if (i == "0"):
result = selected(x = config['x'])
elif (i == "1"):
result = selected(y = config['y'])
elif (i == "2"):
result = selected(z = config['z'])
return result
The current result is correct, but when I have many cases, I need to hardcode each parameter for the specified function. So, that is why I want to know if it is possible to pass the config object as I want (with an x when i is 0, for example) and then just do something like this:
def a(i: int, config: dict):
function_array = [function1, function2, function3]
result = function_array[i](config)
return result
The syntax for passing items from a dictionary as function parameters is simply selected(**config)
So for your example, it would look something like this:
def function1(x=0):
return x + 1
def function2(y=42):
return y * 2
def function3(z=100):
return z
def a(i, config):
function_array = [function1, function2, function3]
selected = function_array[i]
return selected(**config)
config = {x: 10}
a(0, config) # calls function1(x=10)
config = {y: 20}
a(1, config) # calls function2(y=20)
config = {}
a(2, config) # calls function3()
Every python function can be instructed to take a dictionary of keywords. See e.g. https://www.pythoncheatsheet.org/blog/python-easy-args-kwargs . (Official source at https://docs.python.org/3/reference/compound_stmts.html#function-definitions, but it's harder to read.)
You could do:
def a(i: int, keyword: str, **kwargs: dict):
if keyword in kwargs:
result = kwargs[keyword](i)
and you would run it with something like:
a(5, "func3", func1=print, func2=sum, func3=all)
Or, you could just pass a dictionary itself into the function:
def a(i: int, keyword: str, config: dict)
if keyword in config:
result = config[keyword](i)
This would be run with something like:
a(5, "func3", {"func1": print, "func2": sum, "func3": all})
The only difference is that the ** in the function declaration tells python to automatically make a dictionary out of explicit keywords. In the second example, you make the dictionary by yourself.
There's an important thing happening behind the scenes here. Functions are being passed around just like anything else. In python, functions are still objects. You can pass a function just as easily as you can pass an int. So if you wanted to have a list of lists, where each inner list is a function with some arguments, you easily could:
things_to_do = [[sum, 5, 7, 9], [any, 1, 0], [all, 1, 0]]
for thing_list in things_to_do:
function = thing_list[0]
args = thing_list[1:]
print(function(args))
And you'll get the following results:
21
True
False
(Note also that all of those functions take an iterable, such as a list. If you want to pass each argument separately, you would use *args instead of args.)
You can do it with defined functions, too. If you have
def foo1(arg1):
pass
def foo2(arg1, arg2):
pass
you can just as easily have
things_to_do = [[sum, 5, 7, 9], [foo1, 'a'], [foo2, 0, None]]

I am getting the error : ValueError: not enough values to unpack (expected 2, got 1). What could be the problem?

Im running a mapreduce job, but it keeps failing saying missing input. Unfortunately its not showing where its missing either
from mrjob.job import MRJob
from mrjob.step import MRStep
import re
class flight_combination(MRJob):
def steps(self):
return [MRStep(mapper=self.mapper_1,reducer=self.reducer_1)]
def mapper_1(self,_,value):
group1 = {}
group2 = {}
parts = value.split(",")
destination = parts[0]
origin = parts[1]
count = parts[2]
group1[destination] = {'Origin': origin, 'count': count}
group2[origin] = {'Destination':destination,'count':count}
yield group1
yield group2
def reducer_1(self,key,value):
g1,g2 = data
for key1 in g1:
for key2 in g2:
if g1[key1]['Origin'] == g2[key2]['Destination']:
total = int(g1[key1]['count'])*int(g2[key2]['count'])
yield (key1,key2,total)
if __name__ == '__main__':
flight_combination.run()
Following is the error:
`File "wd.py", line 35, in <module>
flight_combination.run()
…...
File "/usr/lib/python3.6/site-packages/mrjob/job.py", line 536, in run_mapper
for out_key, out_value in mapper(key, value) or ():
ValueError: not enough values to unpack (expected 2, got 1)`
The run method of the object type flight_combination is expecting 2 arguments, but provided with 1 argument. ( Python by default takes self as the first argument for methods invoked on object)
To fix this -
as the method run is defined in the parent class, go through its definition and pass the other argument.
Override the run method by redefining it flight_combination class and provide your logic.

Can't add variable to an instance of List

I'd like to add a variable called foo to the weights of a Conv2D layer to keep track of some book keeping.
This is my attempt:
kernels = model.get_layer(name='conv2d_1').get_weights()
kernels.foobar = 4
Note that kernels is of type list.
However, the previous code produce the following error:
AttributeError: 'list' object has no attribute 'foobar'
Any idea?
You can't use kernels.__setattr__('foobar', 4) / setattr(kernels, 'foobar', 4) in the way that you want, so you can't set an arbitrary attribute like you can with a custom class.
Perhaps in this case you do a very basic subclass on list:
class Kernels(list):
def __setattr__(self, attr, x):
# Make sure you aren't overriding some method of lists,
# such as `.append()`
if attr in self.__dir__():
raise ValueError('%s is already a method.')
super().__setattr__(attr, x)
>>> k = Kernels([1, 2, 3])
>>> k.foobar = 4
>>> k
[1, 2, 3]
>>> k.foobar
4

Resources