我刚刚完成了 freeCodeCamp 的算术计算器项目。我使用 Pycharm Community Edition 2020 作为我的软件来测试我的计算器中的问题。此链接提供了问题的要点和设置:算术格式化程序帮助输出
我应该对我的代码进行单元测试,以确保我的计算器适用于所有情况。我不知道如何执行此操作或从哪里开始(Python 的科学计算课程从未教过如何在 repli 中进行单元测试)。任何关于我应该首先测试我的代码的帮助将不胜感激!因为我是技术术语的新手,所以一个非常易于理解的解释会很棒。
replit上有三个文件,我将在每个文件中分享代码:
第一个文件: main.py。我不确定在这里做什么。
# This entrypoint file to be used in development. Start by reading README.md
from pytest import main
from arithmetic_arranger import arithmetic_arranger
print(arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"]))
# Run unit tests automatically
main()
第二个文件:算术_arranger.py。这就是挑战:构建一个 Python 函数,该函数将列表作为输入(如果要显示答案,还需要一个附加参数)并垂直输出算术问题。我相信我的代码有效,所以这应该不是问题。
def arithmetic_arranger(problems, answer):
if len(problems) > 5:
print("Error: Too many problems.")
quit()
first_operand = list()
op_sign = list()
second_operand = list()
for problem in problems:
pieces = problem.split()
first_operand.append(pieces[0])
op_sign.append(pieces[1])
second_operand.append(pieces[2])
for sign in op_sign:
if sign == "*" or sign == "/":
print("Error: Operator must be '+' or '-'.")
quit()
for op1 in first_operand:
if len(op1) > 4:
print("Error: Numbers cannot be more than four digits.")
quit()
try:
integer = int(op1)
except:
print("Error: Numbers must only contain digits.")
quit()
for op2 in second_operand:
if len(op2) > 4:
print("Error: Numbers cannot be more than four digits.")
quit()
try:
integer = int(op2)
except:
print("Error: Numbers must only contain digits.")
quit()
new_str1 = '' # an empty string to add each of the stringed integers.
str1 = ' ' # a string with two whitespaces for each sign.
# For for first line:
for i in range(len(first_operand)): # length of first_operand is dependent upon how many numbers the user inputs.
if len(str(first_operand[i])) < len(str(second_operand[i])):
numb_of_spaces1 = len(str(second_operand[i])) - len(str(first_operand[i]))
new_str1 = new_str1 + str1 + ' ' * numb_of_spaces1 + str(first_operand[i]) + ' ' * 4
else:
new_str1 = new_str1 + str1 + str(first_operand[i]) + ' ' * 4
# For second line:
new_str2 = '' # a string with no whitespaces
str2 = ' ' # a string with one whitespace
# For third line, the number of underscores depends on the sign:
new_str3 = ''
for j in range(len(second_operand)): # length of op_sign is dependent upon how many numbers the user inputs.
if len(str(first_operand[j])) > len(str(second_operand[j])):
numb_of_spaces2 = len(str(first_operand[j])) - len(str(second_operand[j]))
new_str2 = new_str2 + str(op_sign[j]) + str2 + ' ' * numb_of_spaces2 + str(second_operand[j]) + ' ' * 4
new_str3 = new_str3 + '_' * len(str(op_sign[j]) + str2 + ' ' * numb_of_spaces2 + str(second_operand[j])) + ' ' * 4
else:
new_str2 = new_str2 + str(op_sign[j]) + str2 + str(second_operand[j]) + ' ' * 4
new_str3 = new_str3 + '_' * len(str(op_sign[j]) + str2 + str(second_operand[j])) + ' ' * 4
# If the user wants the answers to their problems
if answer == "True":
new_str4 = '' # create an empty string for the answers
str4 = ' ' # string with two whitespaces
str4_b = ' ' # string with one whitespace for negative numbers
for m in range(len(op_sign)):
if op_sign[m] == '+':
outcome = int(first_operand[m]) + int(second_operand[m])
if outcome >= 0 and len(str(outcome)) <= 4:
new_str4 = new_str4 + str4 + str(outcome) + ' '*4 # adds two spaces for 4 or less digits
else:
new_str4 = new_str4 + str4_b + str(outcome) + ' '*4 # adds one white space for 5 digits
else:
outcome = int(first_operand[m]) - int(second_operand[m])
if outcome < 0:
new_str4 = new_str4 + str4_b + str(outcome) + ' '*4
elif outcome == 0:
numb_of_spaces4 = len(str(first_operand[m])) - len(str(outcome))
new_str4 = new_str4 + str4 + ' ' * numb_of_spaces4 + str(outcome) + ' ' * 4
else:
if len(first_operand[m]) == 4 and len(str(outcome)) == 4:
new_str4 = new_str4 + str4 + str(outcome) + ' '*4 # four digits for both first operand and outcome
elif len(first_operand[m]) == 4 and len(str(outcome)) == 3:
new_str4 = new_str4 + ' '*3 + str(outcome) + ' '*4 # four digits for first operand and three digits for outcome
elif len(first_operand[m]) == 4 and len(str(outcome)) == 2:
new_str4 = new_str4 + ' '*4 + str(outcome) + ' '*4 # four digits for first operand and two digits for outcome
elif len(first_operand[m]) == 4 and len(str(outcome)) == 1:
new_str4 = new_str4 + ' '*5 + str(outcome) + ' '*4 # four digits for first operand and one digit for outcome
elif len(first_operand[m]) == 3 and len(str(outcome)) == 3:
new_str4 = new_str4 + str4 + str(outcome) + ' '*4 # three digits for first operand and three digits for outcome
elif len(first_operand[m]) == 3 and len(str(outcome)) == 2:
new_str4 = new_str4 + ' '*3 + str(outcome) + ' '*4 # three digits for first operand and two digits for outcome
elif len(first_operand[m]) == 3 and len(str(outcome)) == 1:
new_str4 = new_str4 + ' '*4 + str(outcome) + ' '*4 # three digits for first operand and one digit for outcome
elif len(first_operand[m]) == 2 and len(str(outcome)) == 2:
new_str4 = new_str4 + str4 + str(outcome) + ' '*4 # two digits for first operand and two digits for outcome
elif len(first_operand[m]) == 2 and len(str(outcome)) == 1:
new_str4 = new_str4 + ' '*3 + str(outcome) + ' '*4 # two digits for first operand and one digit for outcome
else:
new_str4 = new_str4 + str4 + str(outcome) + ' '*4 # one digit for first operand and one digit for outcome
outcome = str(outcome)
outcome = outcome.lstrip('-')
if len(outcome) == 5:
new_str4 = new_str4 + str4_b + outcome + ' ' * 4
arranged_problems = new_str1 + '\n' + new_str2 + '\n' + new_str3 + '\n' + new_str4
return arranged_problems
else:
arranged_problems = new_str1 + '\n' + new_str2 + '\n' + new_str3
return arranged_problems
第三个文件:test_module.py我不知道在这里做什么。
import pytest
from arithmetic_arranger import arithmetic_arranger
test_cases = [
pytest.param(
[['3801 - 2', '123 + 49']],
' 3801 123\n'
'- 2 + 49\n'
'------ -----',
'Expected different output when calling "arithmetic_arranger()" with ["3801 - 2", "123 + 49"]',
id='test_two_problems_arrangement1'),
pytest.param(
[['1 + 2', '1 - 9380']],
' 1 1\n'
'+ 2 - 9380\n'
'--- ------',
'Expected different output when calling "arithmetic_arranger()" with ["1 + 2", "1 - 9380"]',
id='test_two_problems_arrangement2'),
pytest.param(
[['3 + 855', '3801 - 2', '45 + 43', '123 + 49']],
' 3 3801 45 123\n'
'+ 855 - 2 + 43 + 49\n'
'----- ------ ---- -----',
'Expected different output when calling "arithmetic_arranger()" with ["3 + 855", "3801 - 2", "45 + 43", "123 + 49"]',
id='test_four_problems_arrangement'),
pytest.param(
[['11 + 4', '3801 - 2999', '1 + 2', '123 + 49', '1 - 9380']],
' 11 3801 1 123 1\n'
'+ 4 - 2999 + 2 + 49 - 9380\n'
'---- ------ --- ----- ------',
'Expected different output when calling "arithmetic_arranger()" with ["11 + 4", "3801 - 2999", "1 + 2", "123 + 49", "1 - 9380"]',
id='test_five_problems_arrangement'),
pytest.param(
[['44 + 815', '909 - 2', '45 + 43', '123 + 49',
'888 + 40', '653 + 87']],
'Error: Too many problems.',
'Expected calling "arithmetic_arranger()" with more than five problems to return "Error: Too many problems."',
id='test_too_many_problems'),
pytest.param(
[['3 / 855', '3801 - 2', '45 + 43', '123 + 49']],
"Error: Operator must be '+' or '-'.",
'''Expected calling "arithmetic_arranger()" with a problem that uses the "/" operator to return "Error: Operator must be '+' or '-'."''',
id='test_incorrect_operator'),
pytest.param(
[['24 + 85215', '3801 - 2', '45 + 43', '123 + 49']],
'Error: Numbers cannot be more than four digits.',
'Expected calling "arithmetic_arranger()" with a problem that has a number over 4 digits long to return "Error: Numbers cannot be more than four digits."',
id='test_too_many_digits'),
pytest.param(
[['98 + 3g5', '3801 - 2', '45 + 43', '123 + 49']],
'Error: Numbers must only contain digits.',
'Expected calling "arithmetic_arranger()" with a problem that contains a letter character in the number to return "Error: Numbers must only contain digits."',
id='test_only_digits'),
pytest.param(
[['3 + 855', '988 + 40'], True],
' 3 988\n'
'+ 855 + 40\n'
'----- -----\n'
' 858 1028',
'Expected solutions to be correctly displayed in output when calling "arithmetic_arranger()" with ["3 + 855", "988 + 40"] and a second argument of `True`.',
id='test_two_problems_with_solutions'),
pytest.param(
[['32 - 698', '1 - 3801', '45 + 43', '123 + 49', '988 + 40'], True],
' 32 1 45 123 988\n'
'- 698 - 3801 + 43 + 49 + 40\n'
'----- ------ ---- ----- -----\n'
' -666 -3800 88 172 1028',
'Expected solutions to be correctly displayed in output when calling "arithmetic_arranger()" with five arithmetic problems and a second argument of `True`.',
id='test_five_problems_with_solutions'),
]
@pytest.mark.parametrize('arguments,expected_output,fail_message', test_cases)
def test_template(arguments, expected_output, fail_message):
actual = arithmetic_arranger(*arguments)
assert actual == expected_output, fail_message