Python初学者——如何清理这段代码
这是我从零开始编写的第一个Python脚本的一部分。完整的代码是为了处理一些珠子,用于珠子工艺项目,并评估某些设计模式是否可行。代码是可以运行的,我用pylint检查过,分数超过了9.5,但有人告诉我“number_selection”这个函数分支太多,我希望能得到一些帮助来简化它。我知道一定有简单的方法可以让这段代码变得不那么冗长,去掉我所有的if语句,但我现在有点无从下手。
顺便提一下,“beads”是一个全局变量,是通过raw_input提供的。
任何建议都很感激。谢谢大家的帮助。
def number_suggestion():
''' if number entered does not work, then find the closest
usable numbers, figure out which number provides the greatest
number of design options and suggest that number.
'''
next_lower = beads
next_higher = beads
list1 = []
list2 = []
add_one = 1
# find next usable next_lower bead number
while next_lower >= 12 and next_lower % 6 != 0 and \
next_lower % 9 != 0 and next_lower % 12 != 0:
next_lower -= 1
# find next usable next_higher bead number
while next_higher >= 12 and next_higher % 6 != 0 and \
next_higher % 9 != 0 and next_higher % 12 != 0:
next_higher += 1
# add elements to list while counting to next usable number
if next_lower >= 12 and next_lower % 6 == 0:
list1.append(add_one)
if next_lower > 12 and next_lower % 9 == 0:
list1.append(add_one)
if next_lower > 12 and next_lower % 12 == 0:
list1.append(add_one)
if next_higher >= 12 and next_higher % 6 == 0:
list2.append(add_one)
if next_higher > 12 and next_higher % 9 == 0:
list2.append(add_one)
if next_higher > 12 and next_higher % 12 == 0:
list2.append(add_one)
# make a suggestion, but not if the number works
# in that case, return True
if beads >= 12 and beads % 6 == 0:
return
if beads >= 12 and beads % 12 == 0:
return
if beads >= 12 and beads % 9 == 0:
return
# if number is less than 12, print error message
if beads < 12:
print('Please use 12 or more beads in your design.')
return
# if number doesn't work, suggest better options
if len(list1) == len(list2):
print('\nThere was an error.')
print('Try either ' + str(next_lower) + ' or ' \
+ str(next_higher) + ' beads')
elif len(list1) > len(list2):
print('\nThere was an error.')
print('Try ' + str(next_lower) + ' beads instead.')
else:
print('\nThere was an error.')
print('Try ' + str(next_higher) + ' beads instead.')
1 个回答
1
我看过你的代码,并对它做了一些修改。
这些修改的原因我已经在代码里用注释写出来了。
# Test a number for being >= 12 and divisible by 6
test_div_06 = lambda num: num >= 12 and num % 6 == 0
# Test a number for being >= 12 and divisible by 9
test_div_09 = lambda num: num >= 12 and num % 9 == 0
# Test a number for being >= 12 and divisible by 12
test_div_12 = lambda num: num >= 12 and num % 12 == 0
# These are tests in a list
tests = [test_div_06, test_div_09, test_div_12]
# The original if statements were repeated everywhere.
# Now they are defined as functions only once.
def passes_test(test_count):
# Return a list of the tests applied to a number
return [test(test_count) for test in tests]
def passes_any(test_count):
# Return True if any of the tests are True
return any(passes_test(test_count))
def number_suggestion(bead_count):
'''
if number entered does not work, then find the closest
usable numbers, figure out which number provides the greatest
number of design options and suggest that number.
'''
# Sanity checks should occur first.
# Why calculate anything if you don't need to?
# If number is less than 12, print error message
if bead_count < 12:
print("Please use 12 or more beads in your design.")
return
# Number is fine; no suggestion needed
elif passes_any(bead_count):
return
# Find next usable next_lower bead number
next_lower = bead_count
while next_lower > 12 and not passes_any(next_lower):
next_lower -= 1
low_count = len(passes_test(next_lower))
# Find next usable next_higher bead number
next_higher = bead_count
while next_higher > 12 and not passes_any(next_higher):
next_higher += 1
high_count = len(passes_test(next_higher))
# If number doesn't work, suggest better options
# If common behaviour occurs independent of input state,
# it should be expressed that way.
# That's why this print statement was moved to here,
# because the value of counts had no effect on its occurrence.
print("\nThere was an error.")
if low_count == high_count:
print("Try either %d or %d beads" % (next_lower, next_higher))
else:
# The elif and else have been merged into one.
# The reason being its that their outcome is almost identical.
# We can calculate the next_best suggestion using an
# inline if else statement
next_best = next_lower if low_count > high_count else next_higher
print("Try %d beads instead." % next_best)
if __name__ == "__main__":
beads = raw_input("Please specify number of beads: ")
number_suggestion(int(beads))