As a beginner, I wrote the following python script that solves warrant 1 of this document - pp 436-438.
My solution, although works, seems to me as poorly designed and highly unmaintanable. I was thinking of putting talbe 4C-1 condition A/B as numpy arrays and use mapping to interpolate. I would also like to get rid of my "standard" ifs in the document.
How would you recommend I refactor the code so it is "professionally", more eficient, shorter, and of all correctly done.
Thanks
"""
Traffic Warrant 1
"""
def is_warranted_1(pop, spd_maj, vph_maj, vph_min,
lanes_maj, lanes_min, standard):
if standard == 1:
#Standard 1: (condition A) or (Condition B)
#8 hours used for condition a could be different than condition B
if lanes_maj == lanes_min == 1:
return (vph_maj >= 500 and vph_min >= 150) or (vph_maj >= 750 and vph_min >= 75)
if lanes_maj >= 2 and lanes_min == 1:
return (vph_maj >= 600 and vph_min >= 150) or (vph_maj >= 900 and vph_min >= 75)
if lanes_maj >= lanes_min >= 2:
return (vph_maj >= 600 and vph_min >= 200) or (vph_maj >= 900 and vph_min >= 100)
if lanes_maj == 1 and lanes_min >= 2:
return (vph_maj >= 500 and vph_min >= 200) or (vph_maj >= 750 and vph_min >= 100)
if standard == 2:
#Standard 2: (condition A) and (Condition B)
if lanes_maj == lanes_min == 1:
return (vph_maj >= 400 and vph_min >= 120) and (vph_maj >= 600 and vph_min >= 60)
if lanes_maj >= 2 and lanes_min == 1:
return (vph_maj >= 480 and vph_min >= 120) and (vph_maj >= 720 and vph_min >= 60)
if lanes_maj >= lanes_min >= 2:
return (vph_maj >= 480 and vph_min >= 160) and (vph_maj >= 720 and vph_min >= 80)
if lanes_maj == 1 and lanes_min >= 2:
return (vph_maj >= 500 and vph_min >= 160) and (vph_maj >= 600 and vph_min >= 80)
if standard == 3:
#Standard 3: rural area / Condition A or condition B
if pop <= 10000 or spd_maj >= 40:
if lanes_maj == lanes_min == 1:
return (vph_maj >= 350 and vph_min >= 105) or (vph_maj >= 525 and vph_min >= 53)
if lanes_maj >= 2 and lanes_min == 1:
return (vph_maj >= 420 and vph_min >= 105) or (vph_maj >= 630 and vph_min >= 53)
if lanes_maj >= lanes_min >= 2:
return (vph_maj >= 420 and vph_min >= 140) or (vph_maj >= 630 and vph_min >= 70)
if lanes_maj == 1 and lanes_min >= 2:
return (vph_maj >= 350 and vph_min >= 140) or (vph_maj >= 525 and vph_min >= 70)
if standard == 4:
#Standard 4: rural area / last measure / Condition A and Condition B
if pop <= 10000 or spd_maj >= 40:
if lanes_maj == lanes_min == 1:
return (vph_maj >= 280 and vph_min >= 84) and (vph_maj >= 420 and vph_min >= 42)
if lanes_maj >= 2 and lanes_min == 1:
return (vph_maj >= 336 and vph_min >= 84) and (vph_maj >= 504 and vph_min >= 42)
if lanes_maj >= lanes_min >= 2:
return (vph_maj >= 336 and vph_min >= 112) and (vph_maj >= 504 and vph_min >= 56)
if lanes_maj == 1 and lanes_min >= 2:
return (vph_maj >= 280 and vph_min >= 112) and (vph_maj >= 420 and vph_min >= 56)
import random
def test():
for i in range(1, 20):
pop = random.choice(range(5000,100000, 500))
spd_maj = random.choice(range(35,65, 5))
vph_maj = random.choice(range(200,2000, 50))
vph_min = random.choice(range(20,1000, 25))
lanes_maj = random.choice(range(1,4))
lanes_min = random.choice(range(1,4))
standard = random.choice(range(1,4))
result = is_warranted_1(pop, spd_maj, vph_maj, vph_min,
lanes_maj, lanes_min, standard)
print "pop: %s, spd_mmaj: %s, vph_maj: %s, vph_min: %s, lanes_maj: %s, \
lanes_min: %s, stnadard: %s. the result is %s" % (pop, spd_maj,
vph_maj, vph_min, lanes_maj, lanes_min, standard, result)
if __name__ == "__main__":
test()