Spaces:
No application file
No application file
TurkuPythonExercises
/
Week 7 Libraries and More Python
/[FIXED]20. Own programming language, Part 3: Jump command
| '''Jump command | |
| Implement the function | |
| execute(code: str) -> str | |
| in addition to the properties of the previous functions, the following additional commands: | |
| LABEL location | |
| The command adds the named location to the code. | |
| The command does not by itself cause any changes in the code execution. | |
| The given location may be any STRING of letters and numbers. | |
| GOTO place | |
| Code execution continues from the given named location. | |
| The location must be named by the LABEL instruction. | |
| The location may be in the code before or after the jump instruction. | |
| The program need not worry about possible eternal loops, this is left to the programmer. | |
| Example programs for testing instructions: | |
| Program: | |
| LET a=29 | |
| GOTO end | |
| INC a 10 # SKIP THIS LINE | |
| INC a 20 # SKIP THIS LINE | |
| LABEL end | |
| PRINT a | |
| The program returns the printout: | |
| 29 | |
| Program: | |
| LET a=88 | |
| GOTO point1 | |
| INC a 10 # SKIP THIS LINE | |
| INC a 20 # SKIP THIS LINE | |
| LABEL point1 | |
| PRINT a | |
| GOTO per2 | |
| DEC a 20 # SKIP THIS LINE | |
| DEC a 30 # SKIP THIS LINE | |
| LABEL per2 | |
| PRINT a | |
| The program returns the result: | |
| 88 | |
| 88 | |
| Program: | |
| GOTO point1 | |
| LABEL point3 # from below | |
| PRINT a | |
| GOTO end # go to 'end' on the last line | |
| LABEL point2 # from below | |
| DEC a 10 | |
| GOTO point3 # go up to point3 | |
| LABEL point1 # From line 1 | |
| LET a=53 | |
| GOTO point2 # them go up to point2 | |
| LABEL end # from above | |
| The program returns the result: | |
| 43 | |
| ''' | |
| def execute(code: str) -> str: | |
| variables = {'a': 0, 'b': 0, 'c': 0, 'd': 0} | |
| output = [] | |
| ################### | |
| # Refactored for this exercise to keep track of line number for LABEL | |
| ################### | |
| # Split the code into lines and strip whitespace | |
| lines = [line.strip() for line in code.split('\n')] | |
| # Track labels and their corresponding line numbers | |
| labels = {} | |
| for i, line in enumerate(lines): | |
| if line.startswith('LABEL'): | |
| _, location = line.split() | |
| labels[location] = i # Store the line number of the label | |
| i = 0 | |
| while i < len(lines): | |
| line = lines[i] | |
| # Skip empty lines | |
| if not line: | |
| i += 1 | |
| continue | |
| ################### | |
| if line.startswith('LET'): | |
| _, assignment = line.split(' ', 1) | |
| var, value = assignment.split('=') | |
| if var in variables: | |
| variables[var] = int(value) | |
| i += 1 | |
| else: | |
| raise ValueError(f"Invalid variable name: {var}") | |
| elif line.startswith('PRINT'): | |
| _, var = line.split() | |
| if var in variables: | |
| output.append(str(variables[var])) | |
| i += 1 | |
| else: | |
| raise ValueError(f"Undefined variable: {var}") | |
| ########################################## | |
| # 19. part 2 | |
| ########################################## | |
| elif line.startswith('INC') or line.startswith('DEC'): | |
| # Handle INC and DEC commands | |
| parts = line.split() | |
| command = parts[0] | |
| var1 = parts[1] | |
| if var1 not in variables: | |
| raise ValueError(f"Invalid variable name: {var1}") | |
| if len(parts) == 3: | |
| # Check if parts[2] is an integer | |
| try: | |
| value = int(parts[2]) # Try to convert parts[2] to an integer | |
| # If conversion succeeds | |
| # INC/DEC variable number | |
| if command == 'INC': | |
| variables[var1] += value | |
| elif command == 'DEC': | |
| variables[var1] -= value | |
| i += 1 | |
| # parts[2] is NOT an integer | |
| except ValueError: | |
| # INC/DEC variable1 variable2 | |
| var2 = parts[2] | |
| if var2 not in variables: | |
| raise ValueError(f"Invalid variable name: {var2}") | |
| if command == 'INC': | |
| variables[var1] += variables[var2] | |
| elif command == 'DEC': | |
| variables[var1] -= variables[var2] | |
| i += 1 | |
| else: | |
| raise ValueError(f"Invalid command format: {line}") | |
| ########################################## | |
| ########################################## | |
| # 20. part 3 | |
| ########################################## | |
| elif line.startswith('LABEL'): | |
| # Labels are already processed, so just 'skip' the line | |
| i += 1 | |
| elif line.startswith('GOTO'): | |
| _, location = line.split() | |
| if location in labels: | |
| i = labels[location] # Jump to the line number of the label | |
| else: | |
| raise ValueError(f"Undefined label: {location}") | |
| ########################################## | |
| else: | |
| raise ValueError(f"Invalid command: {line}") | |
| joined_output = '\n'.join(output) | |
| joined_output+='\n' | |
| return joined_output | |
| eg1='''LET a=29 | |
| GOTO end | |
| INC a 10 | |
| INC a 20 | |
| LABEL end | |
| PRINT a''' | |
| print(execute(eg1)) | |
| 29 | |
| eg2='''LET a=88 | |
| GOTO point1 | |
| INC a 10 | |
| INC a 20 | |
| LABEL point1 | |
| PRINT a | |
| GOTO per2 | |
| DEC a 20 | |
| DEC a 30 | |
| LABEL per2 | |
| PRINT a''' | |
| print(execute(eg2)) | |
| 88 | |
| 88 | |
| eg3='''GOTO point1 | |
| LABEL point3 | |
| PRINT a | |
| GOTO end | |
| LABEL point2 | |
| DEC a 10 | |
| GOTO point3 | |
| LABEL point1 | |
| LET a=53 | |
| GOTO point2 | |
| LABEL end''' | |
| print(execute(eg3)) | |
| 43 | |
| '''autograder actual, expected output | |
| Testing code: | |
| LET a=96 | |
| GOTO end | |
| INC a 10 | |
| INC a 20 | |
| LABEL end | |
| PRINT a | |
| Program outputs: | |
| 96 | |
| Testing code: | |
| LET a=58 | |
| GOTO spot1 | |
| INC a 10 | |
| INC a 20 | |
| LABEL spot1 | |
| PRINT a | |
| GOTO spot2 | |
| DEC a 20 | |
| DEC a 30 | |
| LABEL spot2 | |
| PRINT a | |
| Program outputs: | |
| 58 | |
| 58 | |
| Testing code: | |
| GOTO spot1 | |
| LABEL spot3 | |
| PRINT a | |
| GOTO end | |
| LABEL spot2 | |
| DEC a 10 | |
| GOTO spot3 | |
| LABEL spot1 | |
| LET a=80 | |
| GOTO spot2 | |
| LABEL end | |
| Program outputs: | |
| 70 | |
| ''' | |