Some telephone operators have submitted their price lists including price per minute for different phone number prefixes.
Some test data, 2 price lists, look like this:
Operator A: 1 0.9 268 5.1 46 0.17 4620 0.0 468 0.15 4631 0.15 4673 0.9 46732 1.1 Operator B: 1 0.92 44 0.5 46 0.2 467 1.0 48 1.2
I want to find the lowest decimal number (the decimal number is a price per minute tax) for a given integer (where the integer is a telephone number or a prefix) in multiple data structures that I represented as Python tuples e.g. o1={1:0.1,2:0.21}
and then a list of those [o1,o2]
.
I found that this batch processing looking code seem to respond the expected result, but could it be done with a regex or more efficient, more readable, or other design improvement?
opa = {1:0.9, 268:5.1, 46:0.17, 4620:0.0, 468:0.15, 4631:0.15, 4673:0.9, 46732:1.1}
opb = {1:0.92, 44:0.5, 46:0.2, 467:1.0, 48:1.2}
oplist=[opa,opb]
def get(self):
n = int(self.request.get('n', '46'))
#for all ops
matchlist = []
matched_ops = []
matched_n=[0]
cheapest_index={}
cheapest_ops={}
index=0
while(n>0):
index=0
for operator in oplist:
try:
var = operator[n]
if not operator in matched_ops and n>=max(matched_n) :
matchlist.append(var)
matched_ops.append(operator)
cheapest_ops[var]=operator
cheapest_index[var]=index
matched_n.append(n)
except KeyError:
pass
index=index+1
n=int(n/10)
#find cheapest
pricematch = min(matchlist)
operator = cheapest_ops[pricematch]
result_op=cheapest_index[pricematch]
1 Answer 1
If I understand what you're looking for correctly, it's the cheapest rate for a particular phone number.
If you already have the rates of each operator as a dictionary of key/value pairs, then you don't need a regex at all. The following code finds the cheapest rate in a set of dictionaries:
opa = {1:0.9, 268:5.1, 46:0.17, 4620:0.0, 468:0.15, 4631:0.15, 4673:0.9, 46732:1.1}
opb = {1:0.92, 44:0.5, 46:0.2, 467:1.0, 48:1.2}
phone_number_prefixes = []
prefix_sets = [opa, opb]
for prefix_set in prefix_sets:
phone_number_prefixes.extend([prefix for prefix in prefix_set.keys()])
phone_number_prefixes = list(set(phone_number_prefixes)) # get rid of duplicates.
cheapest_rates = {}
for prefix in phone_number_prefixes:
rate = float('inf') # everything is less than infinity! ;)
for prefix_set in prefix_sets:
if prefix not in prefix_set:
continue
if prefix_set[prefix] < rate:
rate = prefix_set[prefix]
cheapest_rates.update({prefix: rate})
This gives:
{1: 0.9, 44: 0.5, 46: 0.17, 48: 1.2, 268: 5.1, 467: 1.0, 468: 0.15, 4620: 0.0, 4631: 0.15, 4673: 0.9, 46732: 1.1}
If you actually need to parse strings such as '46732 1.1' into dictionary key/value pairs, a regex would be a good fit for solving that problem. A little quick fiddling suggests that something like (\d+)\s*(\d+\.?\d*)
would capture what you're looking for. This RE matches: (\d+)
one or more digits, \s*
zero or more whitespaces and (\d+\.?\d*)
one or more digits followed by zero or one decimal points followed by zero or more digits. You can use this pattern by compiling it, folloed by python's re.split(string)
method.
pattern = re.compile('(\d+)\s+(\d+\.?\d*)')
numbers = pattern.match('46732 1.1')
key, value = numbers.groups()
key = int(key)
value = float(value)
{}
and[]
with test data that are supposed to match the price listing for telephone number routing given a prefix, so1
might not be routable while17
could be and such conditions that would make me think that a regex could be used. Now I appear to get the match I want so the code I posted might be done with a regex more efficiently. But I'm not sure that a regex is preferable. The example input telphone number should be e.g.46705551234
and then return the lowest decimal match for the opa, opb... in the example data set just added. \$\endgroup\${1: 0.1, 2: 0.21}
is not a tuple, it's a dictionary. \$\endgroup\$