Repository navigation
Expand file tree
/
Copy pathBasic Calculator
More file actions
130 lines (110 loc) · 4.1 KB
/
Copy pathBasic Calculator
File metadata and controls
130 lines (110 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from dataclasses import dataclass
from enum import Enum, auto
import logging
# Setup logging
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
# ANSI colors
class Color:
RESET = "\033[0m"
GREEN = "\033[92m"
RED = "\033[91m"
CYAN = "\033[96m"
YELLOW = "\033[93m"
# Enum for calculator operations
class Operation(Enum):
ADD = auto()
SUBTRACT = auto()
MULTIPLY = auto()
DIVIDE = auto()
POWER = auto()
MODULUS = auto()
EXIT = auto()
@dataclass
class Calculator:
num1: float
num2: float
operation: Operation
def calculate(self) -> float:
"""Perform calculation based on the operation."""
if self.operation == Operation.ADD:
return self.num1 + self.num2
elif self.operation == Operation.SUBTRACT:
return self.num1 - self.num2
elif self.operation == Operation.MULTIPLY:
return self.num1 * self.num2
elif self.operation == Operation.DIVIDE:
if self.num2 == 0:
raise ZeroDivisionError("Cannot divide by zero.")
return self.num1 / self.num2
elif self.operation == Operation.POWER:
return self.num1 ** self.num2
elif self.operation == Operation.MODULUS:
if self.num2 == 0:
raise ZeroDivisionError("Cannot take modulus with zero.")
return self.num1 % self.num2
else:
raise ValueError("Invalid operation.")
def get_user_input() -> Calculator:
"""Get validated user input for the calculator."""
while True:
print(f"\n{Color.CYAN}Choose an operation:{Color.RESET}")
print("a. Add (+)")
print("b. Subtract (-)")
print("c. Multiply (*)")
print("d. Divide (/)")
print("e. Power (^)")
print("f. Modulus (%)")
print("g. Exit")
choice = input("Choose an option (a-g): ").lower()
if choice == 'g':
return Calculator(0, 0, Operation.EXIT)
operation_map = {
'a': Operation.ADD,
'b': Operation.SUBTRACT,
'c': Operation.MULTIPLY,
'd': Operation.DIVIDE,
'e': Operation.POWER,
'f': Operation.MODULUS
}
if choice in operation_map:
try:
num1 = float(input("Enter number 1: "))
num2 = float(input("Enter number 2: "))
return Calculator(num1, num2, operation_map[choice])
except ValueError:
print(f"{Color.RED}Invalid number input. Please enter numeric values.{Color.RESET}")
else:
print(f"{Color.YELLOW}Invalid choice. Please select a valid option.{Color.RESET}")
def main():
print(f"{Color.GREEN}Welcome to the Advanced Python Calculator! 🚀{Color.RESET}")
history = [] # store previous calculations
while True:
calc = get_user_input()
if calc.operation == Operation.EXIT:
print(f"{Color.CYAN}Hope your calculations went well. Goodbye! 👋{Color.RESET}")
break
try:
result = calc.calculate()
operator_symbols = {
Operation.ADD: "+",
Operation.SUBTRACT: "-",
Operation.MULTIPLY: "*",
Operation.DIVIDE: "/",
Operation.POWER: "^",
Operation.MODULUS: "%"
}
operator = operator_symbols[calc.operation]
output = f"{calc.num1} {operator} {calc.num2} = {result}"
print(f"{Color.GREEN}{output}{Color.RESET}")
history.append(output)
# Show history option
see_history = input("Do you want to see your calculation history? (y/n): ").lower()
if see_history == 'y':
print(f"\n{Color.CYAN}--- Calculation History ---{Color.RESET}")
for record in history:
print(record)
except ZeroDivisionError as e:
print(f"{Color.RED}Error: {e}{Color.RESET}")
print(f"\n{Color.YELLOW}Thanks for visiting my profile! Keep coding 💻{Color.RESET}")
if __name__ == "__main__":
main()