Spaces:
No application file
No application file
TurkuPythonExercises
/
Week 7 Libraries and More Python
/[FIXED]21. Own programming language, Part 4: Condition clause
| '''Condition clause | |
| Implement the function | |
| execute(code: str) -> str | |
| in addition to the properties of the previous functions: | |
| JUMP place IF variable==value | |
| Code execution will continue from the named location after the command if the value of the given variable satisfies the condition. | |
| You can assume that the value is a CONSTANT VALUE (not another variable). | |
| Also, the program does not need to understand anything other than the equality operator. | |
| Example programs for testing instructions: | |
| Program: | |
| LET a=13 | |
| JUMP end IF a==13 # if variable matches the condition, JUMP to the 'end' LABEL | |
| INC a 10 # SKIP THIS LINE if JUMP. It is in between the JUMP and LABEL end lines | |
| INC a 15 # SKIP THIS LINE if JUMP. It is in between the JUMP and LABEL end lines | |
| LABEL end # JUMP here | |
| PRINT a | |
| Execution of the program returns: | |
| 13 | |
| Program: | |
| LET a=27 | |
| LABEL start # from below | |
| PRINT a | |
| INC a 1 | |
| JUMP end IF a==32 # if variable matches the condition, JUMP to the 'end' LABEL | |
| GOTO start # SKIP THIS LINE if JUMP. It is in between the JUMP and LABEL end lines. If not JUMPing, go up to 'start' LABEL | |
| LABEL end | |
| Program execution returns: | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| Programme: | |
| LET c=12 | |
| LET d=1 | |
| LABEL loop | |
| PRINT c | |
| DEC c d | |
| JUMP continue IF c==1 # if variable matches the condition, JUMP to the 'continue' LABEL | |
| GOTO loop # SKIP THIS LINE if JUMP. It is in between the JUMP and LABEL end lines. If not JUMPing, go up to 'loop' LABEL | |
| LABEL continue | |
| Program execution returns: | |
| 12 | |
| 11 | |
| 10 | |
| 9 | |
| 8 | |
| 7 | |
| 6 | |
| 5 | |
| 4 | |
| 3 | |
| 2 | |
| ''' | |
| def execute(code: str) -> str: | |
| variables = {'a': 0, 'b': 0, 'c': 0, 'd': 0} | |
| output = [] | |
| # 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}") | |
| ########################################## | |
| ########################################## | |
| # 21. part 4 | |
| ########################################## | |
| elif line.startswith('JUMP'): | |
| parts = line.split() | |
| # eg JUMP end IF a==13 --becomes--> ['JUMP','end','IF','a==13'] | |
| # Format: JUMP jump_to_locationname IF variable==value | |
| jump_to_locationname = parts[1] | |
| condition = parts[3] | |
| var, value = condition.split('==') | |
| # Check if the variable exists | |
| if var not in variables: | |
| raise ValueError(f"Undefined variable: {var}") | |
| # Check the condition | |
| if variables[var] == int(value): | |
| # Jump to the specified label | |
| if jump_to_locationname in labels: | |
| i = labels[jump_to_locationname] | |
| else: | |
| raise ValueError(f"Undefined label: {jump_to_locationname}") | |
| else: | |
| # Continue to the next line | |
| i += 1 | |
| ########################################## | |
| else: | |
| raise ValueError(f"Invalid command: {line}") | |
| joined_output = '\n'.join(output) | |
| joined_output+='\n' | |
| return joined_output | |
| eg1='''LET a=13 | |
| JUMP end IF a==13 | |
| INC a 10 | |
| INC a 15 | |
| LABEL end | |
| PRINT a''' | |
| print(execute(eg1)) | |
| 13 | |
| eg2='''LET a=27 | |
| LABEL start | |
| PRINT a | |
| INC a 1 | |
| JUMP end IF a==32 | |
| GOTO start | |
| LABEL end''' | |
| print(execute(eg2)) | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| eg3='''LET c=12 | |
| LET d=1 | |
| LABEL loop | |
| PRINT c | |
| DEC c d | |
| JUMP continue IF c==1 | |
| GOTO loop | |
| LABEL continue''' | |
| print(execute(eg3)) | |
| 12 | |
| 11 | |
| 10 | |
| 9 | |
| 8 | |
| 7 | |
| 6 | |
| 5 | |
| 4 | |
| 3 | |
| 2 | |
| '''Autograder actual, expected output (53 lines) | |
| Testing code: | |
| LET a=25 | |
| JUMP end IF a==25 | |
| INC a 10 | |
| INC a 15 | |
| LABEL end | |
| PRINT a | |
| Program outputs: | |
| 25 | |
| Testing code: | |
| LET a=62 | |
| LABEL start | |
| PRINT a | |
| INC a 1 | |
| JUMP end IF a==67 | |
| GOTO start | |
| LABEL end | |
| Program outputs: | |
| 62 | |
| 63 | |
| 64 | |
| 65 | |
| 66 | |
| Testing code: | |
| LET c=13 | |
| LET d=1 | |
| LABEL loop | |
| PRINT c | |
| DEC c d | |
| JUMP continue IF c==1 | |
| GOTO loop | |
| LABEL continue | |
| Program outputs: | |
| 13 | |
| 12 | |
| 11 | |
| 10 | |
| 9 | |
| 8 | |
| 7 | |
| 6 | |
| 5 | |
| 4 | |
| 3 | |
| 2 | |
| ''' |