Reputation: 4130
I'm trying to put together a tool that has a notion of 'level'. Each 'level' has a set of variables that are needed to support the activity I want to achieve that are specific to each level.
I have written a hard-coded version that works (to a degree) but it is limited to the number of levels I have hard-coded. It strikes me that there must be a slicker way of writing this func so can generate the level vars on the fly:
def levelVarsGetter(level):
if level == 1:
levelDict = {'URLRegEx':baseDict['L1Regex'], 'titleRegEx':baseDict['L1TitleRegex'], 'buildPortion':baseDict['L1buildPortion'], 'levelParser':'level_1'}
elif level ==2:
levelDict = {'URLRegEx':baseDict['L2Regex'], 'titleRegEx':baseDict['L2TitleRegex'], 'buildPortion':baseDict['L2buildPortion'], 'levelParser':'level_2'}
elif level ==3:
levelDict = {'URLRegEx':baseDict['L3Regex'], 'titleRegEx':baseDict['L3TitleRegex'], 'buildPortion':baseDict['L3buildPortion'], 'levelParser':'level_3'}
elif level ==4:
levelDict = {'URLRegEx':baseDict['L4Regex'], 'titleRegEx':baseDict['L4TitleRegex'], 'buildPortion':baseDict['L4buildPortion'], 'levelParser':'level_4'}
elif level ==5:
levelDict = {'URLRegEx':baseDict['L5Regex'], 'titleRegEx':baseDict['L5TitleRegex'], 'buildPortion':baseDict['L5buildPortion'], 'levelParser':'level_5'}
return levelDict
All the vars in the dict are manually entered in an initialisation func. There labels can be changed if required.
for context, the referring code:
for x in xrange (1, baseDict['numberOfLevels']+1):
links=[]
levelDict= levelVarsGetter(x)
URLRegEx = levelDict['URLRegEx']
titleRegEx = levelDict['titleRegEx']
buildPortion = levelDict['buildPortion']
level = levelDict['levelParser']
go = siteParser()
Upvotes: 0
Views: 101
Reputation: 78610
You could just do:
def levelVarsGetter(l):
return {'URLRegEx': baseDict['L%dRegex' % l],
'titleRegEx': baseDict['L%dTitleRegex' % l],
'buildPortion': baseDict['L%dbuildPortion' % l],
'levelParser': 'level_%d' % l}
However, I suspect your data structure should be designed differently. Whatever is stored in baseDict
could instead be stored in a dictionary that is first keyed by level, then by type, like
{1: {"Regex": ..., "TitleRegex": ..., "buildPortion": ...},
2: {"Regex": ..., "TitleRegex": ..., "buildPortion": ...}...
If your levels are sequential (doesn't skip numbers), you should keep them as a list:
levels = [{"Regex": ..., "TitleRegex": ..., "buildPortion": ...},
{"Regex": ..., "TitleRegex": ..., "buildPortion": ...}...
(though note that you'd have to access it as levels[0]
to get level 1).
Indeed, it's likely the the best design is to have a class called Level
that has attributes regex
, title_regex
, and so on. This would let the Level
class also contain methods for common tasks. For example:
class Level:
def __init__(self, url_regex, title_regex, build_portion):
self.url_regex = url_regex
self.title_regex = title_regex
self.build_portion = build_portion
def method1(self):
"""use build_portion to do something"""
self.build_portion.do_something()
def method2(self):
"""use title_regex and url_regex to do something else"""
x = self.title_regex + self.url_regex
x.do_something_else()
Upvotes: 7
Reputation: 26160
Is there a reason you can't just put this in a list, and use the list indeces as your level numbers? Ex:
levels = [{'URLRegEx' : 'l1url', 'titleRegEx' : 'l1title', 'buildPortion' : 'l1build'},
{'URLRegEx' : 'l2url', 'titleRegEx' : 'l2title', 'buildPortion' : 'l2build'},
...]
Upvotes: 0