Added PyPortal Calculator
This commit is contained in:
parent
8c27d6ac9e
commit
64dd3bdb66
4 changed files with 6289 additions and 1 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,5 +1,5 @@
|
|||
*~
|
||||
Hue_Controller/secrets.h
|
||||
.idea
|
||||
|
||||
*.DS_Store
|
||||
CircuitPython_Logger/secrets\.py
|
||||
|
|
|
|||
109
PyPortal_Calculator/calculator.py
Executable file
109
PyPortal_Calculator/calculator.py
Executable file
|
|
@ -0,0 +1,109 @@
|
|||
"""
|
||||
Class that handles the input and calculations
|
||||
"""
|
||||
|
||||
# Calculator Class
|
||||
class Calculator:
|
||||
def __init__(self, calc_display, clear_button, label_offset):
|
||||
self._calc_display = calc_display
|
||||
self._clear_button = clear_button
|
||||
self._label_offset = label_offset
|
||||
self._all_clear()
|
||||
|
||||
def _calculate(self, number_one, operator, number_two):
|
||||
result = eval(number_one + operator + number_two)
|
||||
if int(result) == result:
|
||||
result = int(result)
|
||||
return str(result)
|
||||
|
||||
def _all_clear(self):
|
||||
self._accumulator = "0"
|
||||
self._operator = None
|
||||
self._equal_pressed = False
|
||||
self._clear_entry()
|
||||
|
||||
def _clear_entry(self):
|
||||
self._operand = None
|
||||
self._set_button_ce(False)
|
||||
self._set_text("0")
|
||||
|
||||
def _set_button_ce(self, entry_only):
|
||||
if entry_only:
|
||||
self._clear_button.label = "CE"
|
||||
else:
|
||||
self._clear_button.label = "AC"
|
||||
|
||||
def _set_text(self, text):
|
||||
self._calc_display.text = text
|
||||
_, _, screen_w, _ = self._calc_display.bounding_box
|
||||
self._calc_display.x = self._label_offset - screen_w
|
||||
|
||||
def _get_text(self):
|
||||
return self._calc_display.text
|
||||
|
||||
def add_input(self, input):
|
||||
try:
|
||||
if input == "AC":
|
||||
self._all_clear()
|
||||
elif input == "CE":
|
||||
self._clear_entry()
|
||||
elif self._operator is None and input == "0":
|
||||
pass
|
||||
elif len(input) == 1 and 48 <= ord(input) <= 57:
|
||||
display_text = self._get_text()
|
||||
if self._operand is None and self._operator is not None:
|
||||
display_text = ""
|
||||
elif self._operand is not None and self._operator is not None and self._equal_pressed:
|
||||
self._accumulator = self._operand
|
||||
self._operator = None
|
||||
self._operand = None
|
||||
display_text = ""
|
||||
elif display_text == "0":
|
||||
display_text = ""
|
||||
display_text += input
|
||||
self._set_text(display_text)
|
||||
if self._operator is not None:
|
||||
self._operand = display_text
|
||||
self._set_button_ce(True)
|
||||
self._equal_pressed = False
|
||||
elif input == "+" or input == "-" or input == "/" or input == "x":
|
||||
if input == "x":
|
||||
input = "*"
|
||||
if self._equal_pressed:
|
||||
self._operand = None
|
||||
if self._operator is None:
|
||||
self._operator = input
|
||||
else:
|
||||
# Perform current calculation before changing inputs
|
||||
if self._operand is not None:
|
||||
self._accumulator = self._calculate(self._accumulator, self._operator, self._operand)
|
||||
self._set_text(self._accumulator)
|
||||
self._operand = None
|
||||
self._operator = input
|
||||
self._accumulator = self._get_text()
|
||||
self._equal_pressed = False
|
||||
elif input == ".":
|
||||
if not input in self._get_text():
|
||||
self._set_text(self._get_text() + input)
|
||||
self._set_button_ce(True)
|
||||
self._equal_pressed = False
|
||||
elif input == "+/-":
|
||||
self._set_text(self._calculate(self._get_text(), "*", "-1"))
|
||||
elif input == "%":
|
||||
self._set_text(self._calculate(self._get_text(), "/", "100"))
|
||||
elif input == "=":
|
||||
if self._operator is not None:
|
||||
if self._operand is None:
|
||||
self._operand = self._get_text()
|
||||
self._accumulator = self._calculate(self._accumulator, self._operator, self._operand)
|
||||
self._set_text(self._accumulator)
|
||||
self._equal_pressed = True
|
||||
# For Debugging
|
||||
print("\n----------------")
|
||||
print("Input: {}".format(input))
|
||||
print("Accumulator: {}".format(self._accumulator))
|
||||
print("Operator: {}".format(self._operator))
|
||||
print("Operand: {}".format(self._operand))
|
||||
except (ZeroDivisionError, RuntimeError) as error:
|
||||
self._all_clear()
|
||||
self._set_text("Error")
|
||||
111
PyPortal_Calculator/code.py
Executable file
111
PyPortal_Calculator/code.py
Executable file
|
|
@ -0,0 +1,111 @@
|
|||
"""
|
||||
PyPortal Calculator Demo
|
||||
"""
|
||||
import time
|
||||
import board
|
||||
import displayio
|
||||
import os
|
||||
from collections import namedtuple
|
||||
from adafruit_display_text.label import Label
|
||||
from adafruit_bitmap_font import bitmap_font
|
||||
from adafruit_display_shapes.rect import Rect
|
||||
from adafruit_button import Button
|
||||
from calculator import Calculator
|
||||
import adafruit_touchscreen
|
||||
coords = namedtuple("Point", "x y")
|
||||
|
||||
ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR,
|
||||
board.TOUCH_YD, board.TOUCH_YU,
|
||||
calibration=((5200, 59000), (5800, 57000)),
|
||||
size=(320, 240))
|
||||
|
||||
# Settings
|
||||
BUTTON_WIDTH = 60
|
||||
BUTTON_HEIGHT = 30
|
||||
BUTTON_MARGIN = 8
|
||||
MAX_DIGITS = 29
|
||||
BLACK = 0x0
|
||||
ORANGE = 0xFF8800
|
||||
WHITE = 0xFFFFFF
|
||||
GRAY = 0x888888
|
||||
LABEL_OFFSET = 290
|
||||
|
||||
# Make the display context
|
||||
calc_group = displayio.Group(max_size=25)
|
||||
board.DISPLAY.show(calc_group)
|
||||
|
||||
# Make a background color fill
|
||||
color_bitmap = displayio.Bitmap(320, 240, 1)
|
||||
color_palette = displayio.Palette(1)
|
||||
color_palette[0] = GRAY
|
||||
bg_sprite = displayio.TileGrid(color_bitmap,
|
||||
pixel_shader=color_palette,
|
||||
x=0, y=0)
|
||||
calc_group.append(bg_sprite)
|
||||
|
||||
# Load the font
|
||||
font = bitmap_font.load_font("/fonts/Arial-12.bdf")
|
||||
buttons = []
|
||||
|
||||
# Some button placement functions
|
||||
def button_grid(row, col):
|
||||
return coords(BUTTON_MARGIN * (row + 1) + BUTTON_WIDTH * row + 20,
|
||||
BUTTON_MARGIN * (col + 1) + BUTTON_HEIGHT * col + 40)
|
||||
|
||||
def make_button(row, col, label, width=1, color=WHITE, text_color=BLACK):
|
||||
pos = button_grid(row, col)
|
||||
button = Button(x=pos.x, y=pos.y,
|
||||
width=BUTTON_WIDTH * width + BUTTON_MARGIN * (width - 1), height=BUTTON_HEIGHT,
|
||||
label=label, label_font=font, label_color=text_color, fill_color=color,
|
||||
style=Button.ROUNDRECT)
|
||||
buttons.append(button)
|
||||
return button
|
||||
|
||||
border = Rect(20, 8, 280, 35, fill=WHITE, outline=BLACK, stroke=2)
|
||||
calc_display = Label(font, text="0", color=BLACK, max_glyphs=MAX_DIGITS)
|
||||
calc_display.y = 25
|
||||
|
||||
clear_button = make_button(0, 0, "AC")
|
||||
make_button(1, 0, "+/-")
|
||||
make_button(2, 0, "%")
|
||||
make_button(3, 0, "/", 1, ORANGE, WHITE)
|
||||
make_button(0, 1, "7")
|
||||
make_button(1, 1, "8")
|
||||
make_button(2, 1, "9")
|
||||
make_button(3, 1, "x", 1, ORANGE, WHITE)
|
||||
make_button(0, 2, "4")
|
||||
make_button(1, 2, "5")
|
||||
make_button(2, 2, "6")
|
||||
make_button(3, 2, "-", 1, ORANGE, WHITE)
|
||||
make_button(0, 3, "1")
|
||||
make_button(1, 3, "2")
|
||||
make_button(2, 3, "3")
|
||||
make_button(3, 3, "+", 1, ORANGE, WHITE)
|
||||
make_button(0, 4, "0", 2)
|
||||
make_button(2, 4, ".")
|
||||
make_button(3, 4, "=", 1, ORANGE, WHITE)
|
||||
|
||||
# Add the display and buttons to the main calc group
|
||||
calc_group.append(border)
|
||||
calc_group.append(calc_display)
|
||||
for b in buttons:
|
||||
calc_group.append(b.group)
|
||||
|
||||
calculator = Calculator(calc_display, clear_button, LABEL_OFFSET)
|
||||
|
||||
button = ""
|
||||
while True:
|
||||
point = ts.touch_point
|
||||
if point is not None:
|
||||
for i, b in enumerate(buttons):
|
||||
if b.contains(point) and button == "":
|
||||
b.selected = True
|
||||
button = b.label
|
||||
time.sleep(0.1)
|
||||
b.selected = False
|
||||
break
|
||||
else:
|
||||
if button != "":
|
||||
calculator.add_input(button)
|
||||
button = ""
|
||||
time.sleep(0.05)
|
||||
6068
PyPortal_Calculator/fonts/Arial-12.bdf
Executable file
6068
PyPortal_Calculator/fonts/Arial-12.bdf
Executable file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue