Assignment_Arithmetic Formatter
SearchfreeCodeCamp.orgMenu
Scientific Computing with PythonScientific Computing with Python ProjectsArithmetic Formatter You will be working on this project with our Replit starter code. We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project: • Python for Everybody Video Course (14 hours) • Learn Python Video Course (10 hours) Students in primary school often arrange arithmetic problems vertically to make them easier to solve. For example, “235 + 52” becomes:
`235
- 52 —–`
Create a function that receives a list of strings that are arithmetic problems and returns the problems arranged vertically and side-by-side. The function should optionally take a second argument. When the second argument is set to True, the answers should be displayed.
Example
Function Call:
arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"])
Output:
`32 3801 45 123
- 698 - 2 + 43 + 49 —– —— —- —–`
Function Call:
arithmetic_arranger(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"], True)
Output:
`32 1 9999 523
- 8 - 3801 + 9999 - 49 —- —— —— —– 40 -3800 19998 474`
Rules
The function will return the correct conversion if the supplied problems are properly formatted, otherwise, it will return a string that describes an error that is meaningful to the user.
• Situations that will return an error:
◦ If there are too many problems supplied to the function. The limit is five, anything more will return: Error: Too many problems.
◦ The appropriate operators the function will accept are addition and subtraction. Multiplication and division will return an error. Other operators not mentioned in this bullet point will not need to be tested. The error returned will be Error: Operator must be '+' or '-'.
◦ Each number (operand) should only contain digits. Otherwise, the function will return Error: Numbers must only contain digits.
◦ Each operand (aka number on each side of the operator) has a max of four digits in width. Otherwise, the error string returned will be: Error: Numbers cannot be more than four digits.
• If the user supplied the correct format of problems, the conversion you return will follow these rules:
◦ There should be a single space between the operator and the longest of the two operands, the operator will be on the same line as the second operand, both operands will be in the same order as provided (the first will be the top one and the second will be the bottom.
◦ Numbers should be right-aligned.
◦ There should be four spaces between each problem.
◦ There should be dashes at the bottom of each problem. The dashes should run along the entire length of each problem individually. (The example above shows what this should look like.)
Development
Write your code in arithmetic_arranger.py. For development, you can use main.py to test your arithmetic_arranger() function. Click the “run” button and main.py will run.
Testing
The unit tests for this project are in test_module.py. We are running the tests from test_module.py in main.py for your convenience. The tests will run automatically whenever you hit the “run” button. Alternatively you may run the tests by inputting pytest in the console.
Submitting
Copy your project’s URL and submit it below.Solution LinkI’ve completed this challengeGet a HintAsk for Help
| Navigated to Scientific Computing with Python Projects - Arithmetic Formatter | Learn | freeCodeCamp.org |
Source Code
-
from replit
import re #Arithmetic problem defined in an inline format (like '3 + 2') and with a vertical representation output, adding also the result (optionally) class Problem: operands = [] operators = [] result = '' #Get operands (substrings containing only words characters) and operators (substrings not containing word characters neither spaces) def __init__(self,str): self.operands = re.split('\W+',str) self.operators = re.findall('[^\w\s]+',str) #verify if there are the amount of operands and operators as expected def check(self): if not self.operands or not self.operators: return False if len(self.operands) != 2 or len(self.operators) != 1: return False #change this to allow more than 2 operands return True #verify if found operator are know/allowed def check_operators(self,allowed_op=('+','-','*','/')): for operator in self.operators: if operator not in allowed_op: return False return True #verify if found operands are digits def check_operands(self): for operand in self.operands: if not operand.isdigit(): return False return True #verify if found operands are not too long def check_operands_size(self,max_digits=0): for operand in self.operands: if max_digits and len(operand) > max_digits: return False return True #get the result of the problem (result = operand1 operator operand2) as string def __calc_result(self): try: operations = { '+': (lambda a,b : a + b), '-': (lambda a,b : a - b), '*': (lambda a,b : a * b), '/': (lambda a,b : a / b), } result = int(self.operands[0]) for i,op in enumerate(self.operators,start=1): result = operations[op](result,int(self.operands[i])) self.result = str(result) except: self.result = '' #format the problem in vertical and rigth aligned, as an array of lines def write_txt(self,with_result=False): fill = 2 + len(max(self.operands,key=len)) if with_result: self.__calc_result() fill = max(fill,len(self.result)) txt = [] for i,num in enumerate(self.operands,start=-1): if i == -1: txt.append(num.rjust(fill,' ')) else: txt.append( self.operators[i] + num.rjust(fill-1,' ') ) txt.append(''.rjust(fill,'-')) if self.result: txt.append(self.result.rjust(fill,' ')) return txt #Error messages for check methods from Problem class class ProblemEx(Exception): msgs = [ "Error: undefined", "Error: Too many problems.", "Error: Operator must be '+' or '-'.", "Error: Numbers must only contain digits.", "Error: Numbers cannot be more than four digits." ] i = 0 def __init__(self, i): self.i = i def get_msg(self): return self.msgs[self.i] #Iterate a list of arithmetic problems defined in inline format and return all of them in a pretty vertical representation. def arithmetic_arranger(problems,with_results=False): matrix = [] ret = '' try: if len(problems) > 5: raise ProblemEx(1) for problem_str in problems: #create each arithmetic problem instance pr = Problem(problem_str) if not pr.check(): raise ProblemEx(0) if not pr.check_operands(): raise ProblemEx(3) if not pr.check_operands_size(4): raise ProblemEx(4) if not pr.check_operators(('+','-')): raise ProblemEx(2) matrix.append(pr.write_txt(with_results)) #join vertical representations of all arithmetic problems matrix = [[matrix[j][i] for j in range(len(matrix))] for i in range(len(matrix[0]))] #transpose matrix lines = [] for line in matrix: lines.append(' '.join(line)) ret = '\n'.join(lines) except ProblemEx as e: ret = e.get_msg() except Exception as e: ret = e return ret -
from drvrajesh (https://replit.com/@drvrajesh/fcc-arithmetic-arranger-final?v=1)
#completely original code and logic, with snippets from Beau def arithmetic_arranger(problems, display=False): operators = [] longest_operands = [] len_diffs = [] num_spaces = [] print_list = [] print_list_2 = [] print_list_3 = [] if len(problems) > 5: return "Error: Too many problems." for problem in range(len(problems)): if "+" in problems[problem]: problems[problem] = problems[problem].split(" + ") operators.append("+") elif "-" in problems[problem]: problems[problem] = problems[problem].split(" - ") operators.append("-") else: return "Error: Operator must be '+' or '-'." for problem in range(len(problems)): if problems[problem][0].isdigit() == False: return "Error: Numbers must only contain digits." elif problems[problem][1].isdigit() == False: return "Error: Numbers must only contain digits." for problem in range(len(problems)): if len(problems[problem][0]) > 4: return "Error: Numbers cannot be more than four digits." elif len(problems[problem][1]) > 4: return "Error: Numbers cannot be more than four digits." for problem in range(len(problems)): if len(problems[problem][0]) < len(problems[problem][1]): longest_operands.append("1") len_diffs.append(1 + (len(problems[problem][1])-len(problems[problem][0]))) else: longest_operands.append("-1") len_diffs.append(-1 - (len(problems[problem][0])-len(problems[problem][1]))) #--------------------------------- for lens in range(len(len_diffs)): if len_diffs[lens] > 0: for num_times_print in range(len_diffs[lens]): print_list.append(" ") print_list.append(" ") print_list.append(problems[lens][0]) if lens != (len(problems) - 1): print_list.append(" ") else: print_list.append(" ") print_list.append(problems[lens][0]) if lens != (len(problems) - 1): print_list.append(" ") for lens in range(len(len_diffs)): print_list_2.append(operators[lens]) if len_diffs[lens] < 0: for spaces in range(abs(len_diffs[lens])): print_list_2.append(" ") print_list_2.append(problems[lens][1]) if lens != (len(problems) - 1): print_list_2.append(" ") else: print_list_2.append(" ") print_list_2.append(problems[lens][1]) if lens != (len(problems) - 1): print_list_2.append(" ") for operands in range(len(longest_operands)): if longest_operands[operands] == "-1": for number_of_dashes in range(len(problems[operands][0])+2): print_list_3.append("-") else: for number_of_dashes in range(len(problems[operands][1])+2): print_list_3.append("-") if operands != (len(problems) - 1): print_list_3.append(" ") return_statement = ''.join(print_list) + "\n" + ''.join(print_list_2) + "\n" + ''.join(print_list_3) if display == True: solutions = [] print_list_4 = [] for problem in range(len(problems)): if operators[problem] == "+": solutions.append(int(problems[problem][0]) + int(problems[problem][1])) else: solutions.append(int(problems[problem][0]) - int(problems[problem][1])) for problem in range(len(problems)): if len(problems[problem][0]) > len(problems[problem][1]): num_spaces.append(len(str(problems[problem][0])) - len(str(solutions[problem]))) else: num_spaces.append(len(str(problems[problem][1])) - len(str(solutions[problem]))) for spaces in range(len(num_spaces)): for i in range(2 + int(num_spaces[spaces])): print_list_4.append(" ") print_list_4.append(solutions[spaces]) if spaces != (len(problems) - 1): print_list_4.append(" ") for i in range(len(print_list_4)): if isinstance(print_list_4[i], int): print_list_4[i] = str(print_list_4[i]) return_statement = ''.join(print_list) + "\n" + ''.join(print_list_2) + "\n" + ''.join(print_list_3) + "\n" + ''.join(print_list_4) return return_statement else: return return_statement -
my project (12 ; 11:00)
def arithmetic_arranger(problems,answer): if len(problems) > 5: # if ຄວາມຍາວຂອງບັ້ງເລກຫຼາບກວ່າ 5 ແມ່ນຈະ error return "Error: Too many problems." arranged_problems = "" for index,value in enumerate(problems): #( ສຳລັບ 32,+,8) operation = value.split(" ") # ແຍກ ແຕ່ລະຕົວອອກດ້ວຍຍະວ່າງ if operation[1] not in "-+": # ຖ້າໃນ ອິນພຸດບໍ່ມີເຄື່ອງໝາຍບວກຫຼືລົບ return "Error: Operator must be '+' or '-'. " # ກວດເບິ່ງວ່າຕົວເລກອິນພຸດຫຼາຍກວ່າ 4 ບໍ່ # (operation[2] is the ຕົວເລກທີ່ຈະຸືກລົບ ຫຼື ຖືກບວກ ສ່ວນ [0] ແມ່ນຕົວຕັ້ງ [1]ເຄື່ອງໝາຍບວກ ຫຼືລົບ) if len(operation[0]) > 4 or len(operation[2]) > 4: return "len(operation[0] > 4" # ປ່ຽນ string ເປັນຕົວເລກ try: value_1 = int(operation[0]) value_2 = int(operation[2]) except ValueError: return "Error: Numbers must only contain digits." # calculate the length of each line longest_value = max(len(operation[0]),len(operation[2])) width = longest_value + 2 # add spaces to each line #line 1 #line 2 # generate the correct number if the - below the problems statement # append the answer if necessary # ເຮັດການຕັ້ງບັ້ງເລກ ໂດຍການໃສ່ ---- temp_problems = f""" {value_1} {operation[1]} {value_2} ---- """ arranged_problems += temp_problems return arranged_problems -
my project (12; 12:00) (https://youtu.be/ZBJUihOVvVM?t=5845)
def arithmetic_arranger(problems): if len(problems) > 5: # if ຄວາມຍາວຂອງບັ້ງເລກຫຼາບກວ່າ 5 ແມ່ນຈະ error return "Error: Too many problems." arranged_problems = [] for index,value in enumerate(problems): #( ສຳລັບ 32,+,8) operation = value.split(" ") # ແຍກ ແຕ່ລະຕົວອອກດ້ວຍຍະວ່າງ if operation[1] not in "-+": # ຖ້າໃນ ອິນພຸດບໍ່ມີເຄື່ອງໝາຍບວກຫຼືລົບ return "Error: Operator must be '+' or '-'. " # ກວດເບິ່ງວ່າຕົວເລກອິນພຸດຫຼາຍກວ່າ 4 ບໍ່ # (operation[2] is the ຕົວເລກທີ່ຈະຸືກລົບ ຫຼື ຖືກບວກ ສ່ວນ [0] ແມ່ນຕົວຕັ້ງ [1]ເຄື່ອງໝາຍບວກ ຫຼືລົບ) if len(operation[0]) > 4 or len(operation[2]) > 4: return "len(operation[0] > 4" # ປ່ຽນ string ເປັນຕົວເລກ try: value_1 = int(operation[0]) value_2 = int(operation[2]) except ValueError: return "Error: Numbers must only contain digits." # calculate the length of each line longest_value = max(len(operation[0]),len(operation[2])) width = longest_value + 2 # operation = ["32", "+","8"] #output = f"{operation[0]:>{width}}\n {f'{operation[1]}{operation[2]}':>{width}} \n{'-'*width}" L1 = f"{operation[0]:>{width}}" L2 = f"{f'{operation[1]} {operation[2]}':>{width}}" d = '-' * width try: arranged_problems[0] = L1 except IndexError: arranged_problems.append((' ' * 4) + L1) try: arranged_problems[1] = L2 except IndexError: arranged_problems.append((' ' * 4) + L2) try: arranged_problems[2] = d except IndexError: arranged_problems.append((' ' * 4) + d) # generate the correct number if the - below the problems statement # append the answer if necessary # ເຮັດການຕັ້ງບັ້ງເລກ ໂດຍການໃສ່ ---- #temp_problems = f""" #{value_1} #{operation[1]} {value_2} #---- #""" #arranged_problems += temp_problems print(arranged_problems) return f"{arranged_problems[0]}\n{arranged_problems[1]}\n{arranged_problems[2]}" -
my project(13,( got in fail left)) (https://youtu.be/ZBJUihOVvVM?t=8761) (https://replit.com/@pinkeo/boilerplate-arithmetic-formatter-2#arithmetic_arranger.py)
def arithmetic_arranger(problems,*args): if len(problems) > 5: # if ຄວາມຍາວຂອງບັ້ງເລກຫຼາບກວ່າ 5 ແມ່ນຈະ error return "Error: Too many problems." arranged_problems = [] for index,value in enumerate(problems): #( ສຳລັບ 32,+,8) operation = value.split(" ") # ແຍກ ແຕ່ລະຕົວອອກດ້ວຍຍະວ່າງ if operation[1] not in "-+": # ຖ້າໃນ ອິນພຸດບໍ່ມີເຄື່ອງໝາຍບວກຫຼືລົບ return "Error: Operator must be '+' or '-'. " # ກວດເບິ່ງວ່າຕົວເລກອິນພຸດຫຼາຍກວ່າ 4 ບໍ່ # (operation[2] is the ຕົວເລກທີ່ຈະຸືກລົບ ຫຼື ຖືກບວກ ສ່ວນ [0] ແມ່ນຕົວຕັ້ງ [1]ເຄື່ອງໝາຍບວກ ຫຼືລົບ) if len(operation[0]) > 4 or len(operation[2]) > 4: return "Error: Numbers cannot be more than four digits." # ປ່ຽນ string ເປັນຕົວເລກ try: value_1 = int(operation[0]) value_2 = int(operation[2]) except ValueError: return "Error: Numbers must only contain digits." # calculate the length of each line longest_value = max(len(operation[0]),len(operation[2])) width = longest_value + 2 # operation = ["32", "+","8"] #output = f"{operation[0]:>{width}}\n {f'{operation[1]}{operation[2]}':>{width}} \n{'-'*width}" L1 = f"{operation[0]:>{width}}" L2 = operation[1] + f"{operation[2]:>{width-1}}" #L2 = f"{f'{operation[1]} {operation[2]}':>{width}}" d = '-' * width try: arranged_problems[0] += (' ' * 4) + L1 except IndexError: arranged_problems.append(L1) try: arranged_problems[1] += (' ' * 4) + L2 except IndexError: arranged_problems.append(L2) try: arranged_problems[2] += (' ' * 4) + d except IndexError: arranged_problems.append(d) # generate the correct number if the - below the problems statement # append the answer if necessary ans =int(operation[0]) + int(operation[2]) if operation[1] == "+" else int(operation[0])-int(operation[2]) a = f"{str(ans):>{width}}" if args: #ans =int(operation[0]) + int(operation[2]) if operation[1] == "+" else int(operation[0])-int(operation[2]) #a = f"{str(ans):>{width}}" try: arranged_problems[3] += (' ' * 4) + a except IndexError: arranged_problems.append(a) # ເຮັດການຕັ້ງບັ້ງເລກ ໂດຍການໃສ່ ---- #temp_problems = f""" #{value_1} #{operation[1]} {value_2} #---- #""" #arranged_problems += temp_problems #print(f"{arranged_problems[0]}\n{arranged_problems[1]}\n{arranged_problems[2]}") output = f"{arranged_problems[0]}\n{arranged_problems[1]}\n{arranged_problems[2]}" output = output + f"\n{arranged_problems[3]}" if args else output return output #return f"{arranged_problems[0]}\n{arranged_problems[1]}\n{arranged_problems[2]}" #print(arithmetic_arranger(["32 + 698" , "3801 - 2" , "45 + 43","123 + 49"])) #print(" 3 3801 45 123\n+ 855 - 2 + 43 + 49\n----- ----- ---- -----") #print("3 / 855", "3801 - 2", "45 + 43", "123 + 49") #print(' 32 1 45 123 988\n' # '- 698 - 3801 + 43 + 49 + 40\n' # '----- ------ ---- ----- -----\n' # ' -666 -3800 88 172 1028') -
The passed Project
def arithmetic_arranger(problems,*args): if len(problems) > 5: # if ຄວາມຍາວຂອງບັ້ງເລກຫຼາບກວ່າ 5 ແມ່ນຈະ error return "Error: Too many problems." arranged_problems = [] for index,value in enumerate(problems): #( ສຳລັບ 32,+,8) operation = value.split(" ") # ແຍກ ແຕ່ລະຕົວອອກດ້ວຍຍະວ່າງ if operation[1] not in "+-": return "Error: Operator must be '+' or '-'." # ຖ້າໃນ ອິນພຸດບໍ່ມີເຄື່ອງໝາຍບວກຫຼືລົບ # ກວດເບິ່ງວ່າຕົວເລກອິນພຸດຫຼາຍກວ່າ 4 ບໍ່ # (operation[2] is the ຕົວເລກທີ່ຈະຸືກລົບ ຫຼື ຖືກບວກ ສ່ວນ [0] ແມ່ນຕົວຕັ້ງ [1]ເຄື່ອງໝາຍບວກ ຫຼືລົບ) if len(operation[0]) > 4 or len(operation[2]) > 4: return "Error: Numbers cannot be more than four digits." # ປ່ຽນ string ເປັນຕົວເລກ try: value_1 = int(operation[0]) value_2 = int(operation[2]) except ValueError: return "Error: Numbers must only contain digits." # calculate the length of each line longest_value = max(len(operation[0]),len(operation[2])) width = longest_value + 2 # operation = ["32", "+","8"] #output = f"{operation[0]:>{width}}\n {f'{operation[1]}{operation[2]}':>{width}} \n{'-'*width}" L1 = f"{operation[0]:>{width}}" L2 = operation[1] + f"{operation[2]:>{width-1}}" #L2 = f"{f'{operation[1]} {operation[2]}':>{width}}" d = '-' * width try: arranged_problems[0] += (' ' * 4) + L1 except IndexError: arranged_problems.append(L1) try: arranged_problems[1] += (' ' * 4) + L2 except IndexError: arranged_problems.append(L2) try: arranged_problems[2] += (' ' * 4) + d except IndexError: arranged_problems.append(d) # generate the correct number if the - below the problems statement # append the answer if necessary ans =int(operation[0]) + int(operation[2]) if operation[1] == "+" else int(operation[0])-int(operation[2]) a = f"{str(ans):>{width}}" if args: #ans =int(operation[0]) + int(operation[2]) if operation[1] == "+" else int(operation[0])-int(operation[2]) #a = f"{str(ans):>{width}}" try: arranged_problems[3] += (' ' * 4) + a except IndexError: arranged_problems.append(a) # ເຮັດການຕັ້ງບັ້ງເລກ ໂດຍການໃສ່ ---- #temp_problems = f""" #{value_1} #{operation[1]} {value_2} #---- #""" #arranged_problems += temp_problems #print(f"{arranged_problems[0]}\n{arranged_problems[1]}\n{arranged_problems[2]}") output = f"{arranged_problems[0]}\n{arranged_problems[1]}\n{arranged_problems[2]}" output = output + f"\n{arranged_problems[3]}" if args else output return output #return f"{arranged_problems[0]}\n{arranged_problems[1]}\n{arranged_problems[2]}" #print(arithmetic_arranger(["32 + 698" , "3801 - 2" , "45 + 43","123 + 49"])) #print(" 3 3801 45 123\n+ 855 - 2 + 43 + 49\n----- ----- ---- -----") #print("3 / 855", "3801 - 2", "45 + 43", "123 + 49") #print(' 32 1 45 123 988\n' # '- 698 - 3801 + 43 + 49 + 40\n' # '----- ------ ---- ----- -----\n' # ' -666 -3800 88 172 1028')