Loop python code - python

self.textboxAnswer1.resize(100,50)
self.textboxAnswer2.resize(100,50)
self.textboxAnswer3.resize(100,50)
self.textboxAnswer4.resize(100,50)
self.textboxAnswer5.resize(100,50)
self.textboxAnswer6.resize(100,50)
Is there a way to put this code into a loop to become more efficient, it seems very repetitive.
using python

You can access class attributes by getattr:
for i in range(6):
getattr(self, 'textboxAnswer{}'.format(i)).resize(100,50)
Hope this helps!

It actually depends on the formulation of your object, but in this case (under the hypothesis I cannot modify the object for any reason) you can actually use the __dict__ and a regular expression:
import re
class T:
def __init__(self):
self.option1 = "1"
self.option2 = "2"
self.notthis = 3
def test(self):
for k in self.__dict__:
if re.compile("option").match(k): # selects only the attributes that start with "option"
print(self.__dict__[k])
t = T()
t.test()
It prints:
1
2
It is ugly and inefficient but does its job. If you can change how the attributes are stored in your object (using a list, a tuple, or any other collection), then follow that way, please.
Applied to you case it would be (rember to import re):
for k in self.__dict__:
if re.compile("textboxAnswer").match(k):
self.__dict__[k].resize(100, 50)

Stick the textboxAnswers in a loop, then just loop over it:
textboxes = # Add all the textboxes into a list here
for tBox in textboxes:
tBox.resize(100,50)

Related

How to access a dictionary value from within the same dictionary in Python? [duplicate]

I'm new to Python, and am sort of surprised I cannot do this.
dictionary = {
'a' : '123',
'b' : dictionary['a'] + '456'
}
I'm wondering what the Pythonic way to correctly do this in my script, because I feel like I'm not the only one that has tried to do this.
EDIT: Enough people were wondering what I'm doing with this, so here are more details for my use cases. Lets say I want to keep dictionary objects to hold file system paths. The paths are relative to other values in the dictionary. For example, this is what one of my dictionaries may look like.
dictionary = {
'user': 'sholsapp',
'home': '/home/' + dictionary['user']
}
It is important that at any point in time I may change dictionary['user'] and have all of the dictionaries values reflect the change. Again, this is an example of what I'm using it for, so I hope that it conveys my goal.
From my own research I think I will need to implement a class to do this.
No fear of creating new classes -
You can take advantage of Python's string formating capabilities
and simply do:
class MyDict(dict):
def __getitem__(self, item):
return dict.__getitem__(self, item) % self
dictionary = MyDict({
'user' : 'gnucom',
'home' : '/home/%(user)s',
'bin' : '%(home)s/bin'
})
print dictionary["home"]
print dictionary["bin"]
Nearest I came up without doing object:
dictionary = {
'user' : 'gnucom',
'home' : lambda:'/home/'+dictionary['user']
}
print dictionary['home']()
dictionary['user']='tony'
print dictionary['home']()
>>> dictionary = {
... 'a':'123'
... }
>>> dictionary['b'] = dictionary['a'] + '456'
>>> dictionary
{'a': '123', 'b': '123456'}
It works fine but when you're trying to use dictionary it hasn't been defined yet (because it has to evaluate that literal dictionary first).
But be careful because this assigns to the key of 'b' the value referenced by the key of 'a' at the time of assignment and is not going to do the lookup every time. If that is what you are looking for, it's possible but with more work.
What you're describing in your edit is how an INI config file works. Python does have a built in library called ConfigParser which should work for what you're describing.
This is an interesting problem. It seems like Greg has a good solution. But that's no fun ;)
jsbueno as a very elegant solution but that only applies to strings (as you requested).
The trick to a 'general' self referential dictionary is to use a surrogate object. It takes a few (understatement) lines of code to pull off, but the usage is about what you want:
S = SurrogateDict(AdditionSurrogateDictEntry)
d = S.resolve({'user': 'gnucom',
'home': '/home/' + S['user'],
'config': [S['home'] + '/.emacs', S['home'] + '/.bashrc']})
The code to make that happen is not nearly so short. It lives in three classes:
import abc
class SurrogateDictEntry(object):
__metaclass__ = abc.ABCMeta
def __init__(self, key):
"""record the key on the real dictionary that this will resolve to a
value for
"""
self.key = key
def resolve(self, d):
""" return the actual value"""
if hasattr(self, 'op'):
# any operation done on self will store it's name in self.op.
# if this is set, resolve it by calling the appropriate method
# now that we can get self.value out of d
self.value = d[self.key]
return getattr(self, self.op + 'resolve__')()
else:
return d[self.key]
#staticmethod
def make_op(opname):
"""A convience class. This will be the form of all op hooks for subclasses
The actual logic for the op is in __op__resolve__ (e.g. __add__resolve__)
"""
def op(self, other):
self.stored_value = other
self.op = opname
return self
op.__name__ = opname
return op
Next, comes the concrete class. simple enough.
class AdditionSurrogateDictEntry(SurrogateDictEntry):
__add__ = SurrogateDictEntry.make_op('__add__')
__radd__ = SurrogateDictEntry.make_op('__radd__')
def __add__resolve__(self):
return self.value + self.stored_value
def __radd__resolve__(self):
return self.stored_value + self.value
Here's the final class
class SurrogateDict(object):
def __init__(self, EntryClass):
self.EntryClass = EntryClass
def __getitem__(self, key):
"""record the key and return"""
return self.EntryClass(key)
#staticmethod
def resolve(d):
"""I eat generators resolve self references"""
stack = [d]
while stack:
cur = stack.pop()
# This just tries to set it to an appropriate iterable
it = xrange(len(cur)) if not hasattr(cur, 'keys') else cur.keys()
for key in it:
# sorry for being a duche. Just register your class with
# SurrogateDictEntry and you can pass whatever.
while isinstance(cur[key], SurrogateDictEntry):
cur[key] = cur[key].resolve(d)
# I'm just going to check for iter but you can add other
# checks here for items that we should loop over.
if hasattr(cur[key], '__iter__'):
stack.append(cur[key])
return d
In response to gnucoms's question about why I named the classes the way that I did.
The word surrogate is generally associated with standing in for something else so it seemed appropriate because that's what the SurrogateDict class does: an instance replaces the 'self' references in a dictionary literal. That being said, (other than just being straight up stupid sometimes) naming is probably one of the hardest things for me about coding. If you (or anyone else) can suggest a better name, I'm all ears.
I'll provide a brief explanation. Throughout S refers to an instance of SurrogateDict and d is the real dictionary.
A reference S[key] triggers S.__getitem__ and SurrogateDictEntry(key) to be placed in the d.
When S[key] = SurrogateDictEntry(key) is constructed, it stores key. This will be the key into d for the value that this entry of SurrogateDictEntry is acting as a surrogate for.
After S[key] is returned, it is either entered into the d, or has some operation(s) performed on it. If an operation is performed on it, it triggers the relative __op__ method which simple stores the value that the operation is performed on and the name of the operation and then returns itself. We can't actually resolve the operation because d hasn't been constructed yet.
After d is constructed, it is passed to S.resolve. This method loops through d finding any instances of SurrogateDictEntry and replacing them with the result of calling the resolve method on the instance.
The SurrogateDictEntry.resolve method receives the now constructed d as an argument and can use the value of key that it stored at construction time to get the value that it is acting as a surrogate for. If an operation was performed on it after creation, the op attribute will have been set with the name of the operation that was performed. If the class has a __op__ method, then it has a __op__resolve__ method with the actual logic that would normally be in the __op__ method. So now we have the logic (self.op__resolve) and all necessary values (self.value, self.stored_value) to finally get the real value of d[key]. So we return that which step 4 places in the dictionary.
finally the SurrogateDict.resolve method returns d with all references resolved.
That'a a rough sketch. If you have any more questions, feel free to ask.
If you, just like me wandering how to make #jsbueno snippet work with {} style substitutions, below is the example code (which is probably not much efficient though):
import string
class MyDict(dict):
def __init__(self, *args, **kw):
super(MyDict,self).__init__(*args, **kw)
self.itemlist = super(MyDict,self).keys()
self.fmt = string.Formatter()
def __getitem__(self, item):
return self.fmt.vformat(dict.__getitem__(self, item), {}, self)
xs = MyDict({
'user' : 'gnucom',
'home' : '/home/{user}',
'bin' : '{home}/bin'
})
>>> xs["home"]
'/home/gnucom'
>>> xs["bin"]
'/home/gnucom/bin'
I tried to make it work with the simple replacement of % self with .format(**self) but it turns out it wouldn't work for nested expressions (like 'bin' in above listing, which references 'home', which has it's own reference to 'user') because of the evaluation order (** expansion is done before actual format call and it's not delayed like in original % version).
Write a class, maybe something with properties:
class PathInfo(object):
def __init__(self, user):
self.user = user
#property
def home(self):
return '/home/' + self.user
p = PathInfo('thc')
print p.home # /home/thc
As sort of an extended version of #Tony's answer, you could build a dictionary subclass that calls its values if they are callables:
class CallingDict(dict):
"""Returns the result rather than the value of referenced callables.
>>> cd = CallingDict({1: "One", 2: "Two", 'fsh': "Fish",
... "rhyme": lambda d: ' '.join((d[1], d['fsh'],
... d[2], d['fsh']))})
>>> cd["rhyme"]
'One Fish Two Fish'
>>> cd[1] = 'Red'
>>> cd[2] = 'Blue'
>>> cd["rhyme"]
'Red Fish Blue Fish'
"""
def __getitem__(self, item):
it = super(CallingDict, self).__getitem__(item)
if callable(it):
return it(self)
else:
return it
Of course this would only be usable if you're not actually going to store callables as values. If you need to be able to do that, you could wrap the lambda declaration in a function that adds some attribute to the resulting lambda, and check for it in CallingDict.__getitem__, but at that point it's getting complex, and long-winded, enough that it might just be easier to use a class for your data in the first place.
This is very easy in a lazily evaluated language (haskell).
Since Python is strictly evaluated, we can do a little trick to turn things lazy:
Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))
d1 = lambda self: lambda: {
'a': lambda: 3,
'b': lambda: self()['a']()
}
# fix the d1, and evaluate it
d2 = Y(d1)()
# to get a
d2['a']() # 3
# to get b
d2['b']() # 3
Syntax wise this is not very nice. That's because of us needing to explicitly construct lazy expressions with lambda: ... and explicitly evaluate lazy expression with ...(). It's the opposite problem in lazy languages needing strictness annotations, here in Python we end up needing lazy annotations.
I think with some more meta-programmming and some more tricks, the above could be made more easy to use.
Note that this is basically how let-rec works in some functional languages.
The jsbueno answer in Python 3 :
class MyDict(dict):
def __getitem__(self, item):
return dict.__getitem__(self, item).format(self)
dictionary = MyDict({
'user' : 'gnucom',
'home' : '/home/{0[user]}',
'bin' : '{0[home]}/bin'
})
print(dictionary["home"])
print(dictionary["bin"])
Her ewe use the python 3 string formatting with curly braces {} and the .format() method.
Documentation : https://docs.python.org/3/library/string.html

Python: how to use some kind of generic setter?

I've made this code:
if fc.get('field_photo_1'):
pt.photo1 = fc.get('field_photo_1')
if fc.get('field_photo_2'):
pt.photo2 = fc.get('field_photo_2')
if fc.get('field_photo_3'):
pt.photo3 = fc.get('field_photo_3')
I'd like to optimize it to some kind of code like this:
update_field(photo1, 'field_photo_1'):
update_field(photo2, 'field_photo_2'):
update_field(photo3, 'field_photo_3'):
I just don't know how make kinddof a setter with index in python. How would you implement the update_field() function?
You could take a look at the setattr() function.
I would suggest making an array of photos and then iterate strings with a for loop instead of trying to create such setter. It's easier to understand and doesn't do uncommon things with your class that other programmers might not expect.
class Pt:
def __init__(self):
self.photos = [None for i in range(3)]
pt = Pt()
for i in range(1,4)
fieldString = 'field_photo_{0}'.format(i)
if fc.get(fieldString):
pt.photos[i] = fc.get(fieldString)
You are looking for setattr, which accepts string attribute names.
Try this:
for x in range(1, 4):
attrname = "photo_".format(x)
setattr(pt, attrname, fc["field_".format(attrname)])
You should probably refactor your code though to use lists.
If you are wanting to set the pt attribute based on the passed parameter, setattr is the way to go.
def update_field(attribute, value):
setattr(pt, attribute, value)
The other answers here assume that you are iterating through a preset number of photo attributes. If you are wanting a single set, then the above should work. If looking to set them all, Ben's or Ritave's answer might be more suitable.
Depending on the scope of the "pt" variable. You might have to do something like setattr(self.pt, attribute, value).
You could use a dict:
photos = dict()
photos['photo1'] = fc.get('field_photo_1')
# etc...
Or more concisely:
photos = {photo: fc.get(photo) for photo in ('field_photo_1', 'field_photo_2', 'field_photo_3')}

How can I create n numbers of instances for a class?

I am trying to write a code whereby I can set a variable, say n, to create n numbers of instances for that particular class. The instances have to be named 'Node_1', 'Node_2'...'Node_n'. I've tried to do this in several ways using the for loop, however I always get the error: 'Can't assign to operator.'
My latest effort is as follows:
class C():
pass
for count in range(1,3):
"node"+str(count)=locals()["C"]()
print(node)
I understand that the "node" + str(count) is not possible, but I don't see how I can solve this issue.
Any help on the matter will be greatly appreciated.
You could do what you're trying to do, but it's a really bad idea. You should either use a list or a dict; since you seem to want the names to be nodeX, and starting from 1, you should use a dict.
nodes = {'node{}'.format(x): C() for x in range(1, 3)}
Depending on what you're doing, you could also use a defaultdict.
from collections import defaultdict
nodes = defaultdict(C)
print(nodes['node1'])
nodes['node2'].method()
print(nodes['anything-can-go-here'])
Once you're doing that though, there's no need for the 'node' prefix.
The best pattern for creating several similar objects is a list comprehension:
class C():
pass
nodes = [C() for i in range(3)]
This leaves you with three objects of class C, stored in a list called nodes. Access each object in the normal way, with indexing (e.g. nodes[0]).
You're trying to assign a value to a string. You can write Node_1 = C(), but "Node_1" = C() is meaningless, as "Node_1" is a string literal, not an identifier.
It's a little sketchy, but you can use the locals() dictionary to access the identifiers by name:
for count in range(1, 3):
locals()["node" + str(count)] = C()
...and, having done that, you can then use node1 and node2 as if they were defined explicitly in your code.
Typically, however, it's preferable to not access your locals this way, rather you should probably be using a separate dictionary of your own creation that stands on its own and contains the values there:
nodes = {}
for count in range(1, 3):
nodes[count] = C()
... and the values can then be accessed like so: nodes[1], nodes[2], etc.
What I like to do, to keep a registry of all the instances of a class:
class C(object):
instances = {}
def __new__(cls, *args, **kwargs):
instance = super(C, cls).__new__(cls, *args, **kwargs)
instance_name = 'node_{}'.format(len(cls.instances))
cls.instances[instance_name] = instance
return instance
if __name__ == '__main__':
for _ in range(3):
C()
print C.instances
OrderedDict([('node_0', <main.C object at 0x10c3fe8d0>), ('node_1', <main.C object at 0x10c4cb610>), ('node_2', <main.C object at 0x10c4e04d0>)])

Variable referring to class members - Python

I'm trying to create a way to apply a prefix to an item which would modify the item's existing stats. For example in the code below I am trying to apply the 'huge' prefix to the 'jar' item. I'd like to make the code reusable so that I could have different prefixes ('fast', 'healthy') that would modify different item stats.
Is it possible to hold the name of a class member in a variable?
If so, is there any reason I shouldn't?
If not, what alternatives are there?
class Prefix(object):
def __init__(self, word, stat, valu):
self.word = word
self.stat = stat
self.valu = valu
class Item(object):
def __init__(self, name, size):
self.name = name
self.size = size
def apply_prefix(self, prefix):
self.prefix.stat += prefix.valu # <-- Here is my issue
self.name = prefix.word + ' ' + self.name
# My hope is to make the code reusable for any stat
def print_stats(self):
print self.name, self.size
def main():
jar = Item('jar', 10)
huge_prefix = Prefix('huge', 'size', 5)
jar.apply_prefix(huge_prefix)
jar.print_stats()
You're trying to dynamically refer to some attribute. You do that by using getattr. And if you want to set the attribute, well... that's setattr :)
def apply_prefix(self, prefix):
target_attr = getattr(self,prefix.stat) #dynamically gets attr
setattr(self,prefix.stat,target_attr+prefix.valu)
As to whether this is the best coding style: it depends. There are some instances that code is made more clear by use of getattr. Since right now you only have two stats, it seems excessive to need this kind of dynamic attribute referencing, since I could easily do:
bogus_prefix = Prefix('huge','bogus',3)
Which is a valid Prefix, but throws an AttributeError when I try to apply it. That's not the most straightforward thing to debug.
However, there are bonuses to the getattr approach: if you add more stats, you don't have to change a bit (haha) of code in Prefix.
Other alternatives? There are always options in Python. :-)
The way I'd do it is to make Prefix just a dict of word:value pairs. Then apply_prefix would loop over the word keys, updating as many values as I wanted in one shot. It's a similarly dynamic approach, but a bit more scalable.

Python reverse introspection

Lets suppose this example: Two siblings classes where one loads the other class as a new attribute and then i wish to use this attribute from the main class inside the sibling.
a = 2
class AN(object):
def __init__(self,a):
self.aplus = a + 2
self.BECls = BE(a)
class BE(object):
def __init__(self,a):
print a
def get_aplus(self):
????
c = AN(a)
and i'd like to do:
c.BECls.get_aplus()
and this shall return something like self.self.aplus (metaphorically), that would be 4
Resuming: get aplus attribute from AN inside BE class, without declaring as arguments, but doing a "Reverse introspection", if it possible, considering the 'a' variable must be already loaded trough AN.
Sorry if I not made myself clear but I've tried to simplify what is happening with my real code.
I guess the problem may be the technique i'm using on the classes. But not sure what or how make it better.
Thanks
OP's question:
get aplus attribute from AN inside BE class, without declaring as
arguments, but doing a "Reverse introspection", if it possible,
considering the 'a' variable must be already loaded trough AN.
The closest thing we have to "reverse introspection" is a search through gc.getreferrers().
That said, it would be better to simply make the relationship explicit
class AN(object):
def __init__(self,a):
self.aplus = a + 2
self.BECls = BE(self, a)
class BE(object):
def __init__(self, an_obj, a):
self.an_obj = an_obj
print a
def get_aplus(self):
return self.an_obj.aplus
if __name__ == '__main__':
a = 2
c = AN(a)
print c.BECls.get_aplus() # this returns 4

Categories