# Assignment 1: Programming Basics

## Introduction: A Simple Calculator as your first computer program!

As part of this assignment, you will create and implement a computer program from scratch. By the end of the assignment, your program will function as a Simple Calculator!

On Task 1, you will implement a Simple Calculator that performs arithmetic operations based on the user's input. If you have any questions, please, ask your group tutor or attend the coaching session.
On Task 2, you can extend the functionality of your Calculator to hold and present the past results of all the performed arithmetic operations. If you have any questions, please, check out Python lists or ask your tutor.

## Task 1: A Simple Calculator

Implement a simple calculator. Your calculator should provide the four basic arithmetic operations and a termination option(add, subtract, multiply, divide, end) and adhere to this specification:

• The program shall ask the user to enter/select the desired operation (add/subtract/multiply/divide/end).
• When the user selects an arithmetic operation, the program shall ask the user to input the two operands, calculate the result, and print the result.
• The program is executed repeatedly until the user actively stops it using the command end.

### Task 1.1: Retrieve the user's input (1 Point)

Let's imagine that you buy a calculator.
As a user, the first thing you would expect from your calculator is to accept two operands (e.g. 2 and 5) and an operation (e.g, "add" or "+" and "subtract" or "-"). You could also expect that there is a termination option (e.g. "end" or "off").
As a programmer, you should write the code that retrieves the input that the user expects to give.

In [1]:
# HINTS: To retrieve the user's input, use the built-in function input() that was presented to you during the lecture. Check out the lecture slides or the tutorial https://www.programiz.com/python-programming/methods/built-in/input.
# You can call the function 3 times to retrieve the 1st operand, the 2nd operand and the operation (including "end"), respectively. On each function call, assign the returned value to a new variable so that you can use it later on your program! By the end, you should have defined 3 new variables: mode, op1 and op2.
# IMPORTANT: The function input() returns a string value. You need to convert the operands (op1 and op2) to a valid datatype (e.g. floats or integers) so that you can make calculations later. Check out the tutorial on Type Conversion https://www.programiz.com/python-programming/type-conversion-and-casting.

# 1. Add below the code for retrieving one of ["add","subtract","divide", "multiply", "divide", "end"] (using input()) and assign it to a new variable named mode.

# 2. Print the arithmetic or termination operation by passing as an argument the variable mode to the built-in function print().

# 3. Add below the code for retrieving the 1st operand, convert it to a valid datatype and assign it to a new variable named op1.

# 4. Print the 1st operand by passing as an argument the variable op1 to the built-in function print().

# 5. Add below the code for retrieving the 2nd operand, convert it to a valid datatype and assign it to a new variable op2.

# 6. Print the 2st operand by passing as an argument the variable op2 to the built-in function print().

# IMPORTANT - Remember to remove raise NotImplementedError() before starting coding.

_
### BEGIN SOLUTION
print(mode)
op1 = int(input("Please give a first operand: ")) #type conversion because input() returns a string value
print(op1)
op2 = int(input("Please give a second operand: ")) #type conversion because input() returns a string value
print(op2)
### END SOLUTION


4
In [2]:
# After running the cell with your solution, run this cell to test if you sucessfully defined the variables "mode", "op1" and "op2".
from nose.tools import assert_true

assert_true(isinstance(mode,str))
assert_true(isinstance(op1,float) or isinstance(op1,int))
assert_true(isinstance(op2,float) or isinstance(op2,int))



### Task 1.2: Implement a function that performs an arithmentic operation based on 2 operands and 1 operator and returns the result (3 Points)

Once the user gives their input to the calculator, they expect a result!
As a programmer, you will write a function named calculate that receives 2 operands and 1 operator as parameters. Based on the operator, the body of the function performs the corresponding arithmetic operation by using the 2 operands. At the end, the function should return the result of the arthmetic operation.
For example, if the operator is equal to "add", then the control flow should be such that the function will perform the addition(+) of the two operands. Remember to assign the returned value of the arithmetic operation to a variable (e.g. a variable named "result") and return it!

In [2]:
# HINTS: To define the function named "calculate" follow the steps that were presented to you during the lecture or check out the tutorial https://www.programiz.com/python-programming/function.

# 1. Add the function definition: It should include 1) the keyword "def", 2) the name(identifier) of the function(here calculate) and the 3 parameters: operand1, operand2, operation.

# 2. Specify the control flow in such a way that based on the operator a different arithmetic operation is performed using the 2 operands and the returned value of the operation is assigned to a varible. Check out the "helloworld" example that was presented to you during the lecture to get familiar with the "if" and "else" statements. Alternatively, check out the tutorial https://www.programiz.com/python-programming/if-elif-else.
# IMPORTANT: Remember that we are implementing a) a function and b) if/else statements, so indentation is important!

# 3. Return a variable that holds the value of the perfomed operation (e.g. a variable named "result"). Indentation is still important because you are implementing a function!

# IMPORTANT - Remember to remove raise NotImplementedError() before starting coding.

_
### BEGIN SOLUTION
def calculate(operand1, operand2, operation): #if-elif-else --> only the action for the first true statement executes
return operand1 + operand2
elif operation == 'subtract':
return operand1 - operand2
elif operation == 'multiply':
return operand1 * operand2
elif operation == 'divide':
# check zero division
if operand2 == 0:
print('I cannot divide by 0.')
return None
return operand1 / operand2

# invalid operation
print(f"'{operation}' unknown")
return None
### END SOLUTION


In [4]:
# After running the cell with your solution, run this cell to test if you sucessfully implemented the function "calculate".
from nose.tools import assert_equal
assert_equal(my_result,7)

# For subtraction
my_result = calculate(2,5,"subtract")
assert_equal(my_result,-3)

# For multiplication
my_result = calculate(2,5,"multiply")
assert_equal(my_result,10)

# For division
my_result = calculate(2,5,"divide")
assert_equal(my_result,0.4)

# For division by 0
my_result = calculate(2,0,"divide")
assert_equal(my_result,None)

# For uknown operation
my_result = calculate(2,0,"my_operation")
assert_equal(my_result,None)


I cannot divide by 0. 'my_operation' unknown

### Task 1.3: Call your function by passing the user's input and print the result for the user

Right now:

• you can retrieve 2 operands and 1 operator (or end) from the user,
• you have a function that performs an arithmetic operation based on 2 operands and 1 operator and returns the result.
Let's link the two to make a functional calculator!
The calculator program should be executed repeatedly (check out while loops!): a) asking for the user's input and converting it to a valid datatype, b) calling the function by passing the necessary arguments and, c) printing the result so that the user can see it! The repetition should terminate when the user's input is equal to end.
In [6]:
##### HINTS Take care of the indentation whenever you use a while loop or if/else statements!

# 1. Introduce a "while True" loop that is performed continuously except if the user's input becomes equal to "end". Check out the lecture slides or the tutorials https://www.programiz.com/python-programming/while-loop.

# 2. Ask for the user's input to retrieve the operator (or the "end" keyword) and the 2 operands. You can copy and paste the code that you implemented on Task 1.1. If "mode" is equal to "end" then the while-loop should "break", because the user does not wish to perform any new operations. Check out how to "break" and "continue" in a while-loop here and https://www.programiz.com/python-programming/break-continue.

# 3. Still in the loop? Then retrieve and convert the other two inputs from the user. You can copy and paste the code that you implemented on Task 1.1. If you can, check if the values of "operand1" and "operand2" are valid (e.g. they are not words).

# 4. Use the variables that hold the values of the user's input as arguments to call the function calculate() and ASSIGN the returned value of calculate() to a new variable named "result".

# 5. Print the variable "result" so that the user can see it!

# IMPORTANT - Remember to remove raise NotImplementedError() before starting coding.
_
### BEGIN SOLUTION
while True:
# ask the user to type the command

# process the ops without user inputs
if mode == 'end':
# finish the script
print('Application terminated.')
break

op1 = op2 = 0
# ask the two operands with validating the input
while True:
try:
op1 = float(input("Please give a first operand: "))
op2 = float(input("Please give a second operand: "))
except ValueError as e: # conversion to float failed
# the error message contains the value for op1/op2
print(str(e).split()[-1], ' must be a number.')
continue
break

result = calculate(op1, op2, mode)
if result is None:
continue
print(f"Result: {result}")

# 1 point for correct repetition and termination with the "end" command
# 1 point for correct usage of input() and sucessful conversion of operands
# 1 point for correct calculation of the result
# 0.5 points for assigning the returned value of calculate() to a variable
# 0.2 points for checking for valid input of operands
# 1.3 if the application logic and structure make sense
### END SOLUTION



Extend your program with a "history": The program shall record each executed arithmetic operation using a Python List. Furthermore, it should be possible to display this list using an additional command "history" and not just "add", "subtract", "multiply", "divide" or "end". Please, consult the tutorial https://www.programiz.com/python-programming/list to learn how you can initialize a list, append a new element to a list (e.g. the result of an arithmetic operation) and print a list.

In [9]:
#HINTS: Copy and paste your calculator code from Task 1.3 in order to extend it! Extend the code by initializing __only once__ (above the while-loop) an empty __list named "history"__. Within the while-loop introduce a new "if" statement that checks whether the user's input is equal to "history". Specifically, if the user's input is equal to "history", print the content of the list "history" (i.e. print the variable named "history" that holds the value of the list) and then "continue" in the loop. If the user actually wants to perform an arithmetic operation, then calculate the result (based on your previous code) and append the new result to the "history" list!

_
### BEGIN SOLUTION
# ------------------> Initialize an empty history list
history = []

while True:

# ask the user to type the command

# process the ops without user inputs
if mode == 'end':
# finish the script
print('Application terminated.')
break #loop verlassen

# process the ops without user inputs
if mode == 'history':
# ------------------> print the history
print("Printing history: ", history)
for r in history:
print(r)
continue #wieder an den Beginn von Loop gehen

op1 = op2 = 0
# ask the two operands with validating the input
while True:
try:
op1 = float(input("Please give a first operand: "))
op2 = float(input("Please give a second operand: "))
except ValueError as e: # conversion to float failed
# the error message contains the value for op1/op2
print(str(e).split()[-1], ' must be a number.')
continue
break

result = calculate(op1, op2, mode)
if result is None:
continue

# Store the calculation to history
print(f"Result: {result}")

# ------------------> Store the result in history
history.append(f"{mode} {op1} {op2} -> {result}")

# 0.25 for correct successful initilization
# 0.25 for correct appending
# 0.25 for correct printing (even if they print only the results of the calculation)
# 0.25 for logical placement of all the above

### END SOLUTION


print("This task is optional. Test it by yourself. In the case of questions, contact your group tutor.")