Skip to content

Commit

Permalink
Merge pull request #26 from tsadarsh/dev
Browse files Browse the repository at this point in the history
v2.0 of Pymanujan
  • Loading branch information
tsadarsh authored Mar 14, 2021
2 parents f99cb07 + 57e0b04 commit 0476d02
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 70 deletions.
109 changes: 67 additions & 42 deletions Pymanujan/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
from tkinter import ttk
from tkinter import StringVar

from pyperclip import copy as to_clipboard
try:
from pyperclip import copy as to_clipboard
except ModuleNotFoundError:
print("Install pyperclip library to use Copy function")
pass

from .storage import Storage
from .core_logic import Calculate
Expand All @@ -15,14 +19,19 @@ class GUI(Tk):
def __init__(self):
super().__init__()
# Main window properties
self.title("Pymanujan (v2.0-alpha)")
self.title("Pymanujan (v2.0)")
self.resizable(False, False)
self.styler = ttk.Style()
self._layout = ['*', '/', 'C', 'AC',
'9', '8', '7', '-',
'6', '5', '4', '+',
'3', '2', '1', '+/-',
'.', '0', 'Copy', '=']
self._old_layout = ['*', '/', 'C', 'AC',
'9', '8', '7', '-',
'6', '5', '4', '+',
'3', '2', '1', '+/-',
'.', '0', 'Copy', '=']
self._layout = ['AC', 'C', '+/-', '/',
'7', '8', '9', '*',
'4', '5', '6', '-',
'1', '2', '3', '+',
'0', '.', 'copy', '=']
self._adv_layout = ['(', ')', '^', 'C',
'*', 'sin', 'cos', 'tan',
'/', 'asin', 'acos', 'atan',
Expand All @@ -37,10 +46,11 @@ def __init__(self):
padding=(0, 0, 0, 0),
style='Outliner.TFrame')
self.mainframe = ttk.Frame(self.content,
relief='flat')
relief='flat',
padding=(0, 0, 0, 0))
self.mainframe2 = ttk.Frame(self.content)
self.content.add(self.mainframe, text='Basic')
self.content.add(self.mainframe2, text='Advanced')
self.content.add(self.mainframe, text=' Basic ')
self.content.add(self.mainframe2, text=' Advanced ')
self.content.grid()
self.label_text = StringVar()

Expand All @@ -51,21 +61,30 @@ def default_style_settings(self):
could be set using a YAML file.
"""

self.styler.configure("TFrame",
foreground='snow',
background='grey17')
self.styler.configure("TLabel",
font='Times 20')
padding=(0, 10, 0, 10),
foreground='snow',
background='grey17',
font='Times 25')
self.styler.configure("TButton",
font='Times 16 italic bold',
relief='flat',
width='5',
padding='10',
background='bisque')
width='4',
padding=(10, 10, 10, 10),
foreground='grey21',
background='snow3')
self.styler.configure("Numerals.TButton",
font='Times 16',
relief='flat',
foreground='snow2',
background='grey21')
self.styler.configure("EqualButton.TButton",
relief='falt',
background='SeaGreen2',
foreground='green4')
self.styler.configure("EqualButton2.TButton",
relief='flat',
background='firebrick1',
foreground='green4')
foreground='snow2',
background='SpringGreen3')
self.styler.configure("Outliner.TFrame",
background='snow2')

Expand Down Expand Up @@ -96,6 +115,14 @@ def create_basic_buttons(self):
button_objects['+/-']['command'] = lambda: self._button_invoke('i')
button_objects['=']['style'] = 'EqualButton.TButton'

for button_char in self._layout:
if button_char.isnumeric():
button_objects[button_char]['style'] = "Numerals.TButton"
elif button_char == '.':
button_objects[button_char]['style'] = "Numerals.TButton"
elif button_char == 'copy':
button_objects[button_char]['style'] = "Numerals.TButton"

keypad.grid()
row, column = 0, 0
for button in button_objects.values():
Expand Down Expand Up @@ -125,7 +152,7 @@ def create_advanced_buttons(self):
)
for button in self._adv_layout
}
button_objects['=']['style'] = 'EqualButton2.TButton'
button_objects['=']['style'] = 'EqualButton.TButton'

keypad.grid()
row, column = 0, 0
Expand All @@ -147,42 +174,40 @@ def _button_invoke(self, bt: str) -> None:
bt : str
character corresponding to the invoked button
"""
to_display = self.logic.show_storage()
if bt == '=':
get_storage = self.logic.show_storage_as_list()
to_display = 'Ans: '+self._calculate_answer(get_storage)
self._adjust_and_set_TLabel_font(to_display)
elif bt == 'Copy':
self._copy_to_clipboard(self.logic.show_storage_as_list())
elif bt == 'x!':
self.logic.into_storage('!')
self._adjust_and_set_TLabel_font(to_display)
to_display = self.logic.show_storage()
else:
self.logic.into_storage(bt)
to_display = self.logic.show_storage()
self._adjust_and_set_TLabel_font(to_display)
self._adjust_and_set_TLabel_font(to_display)

def keyboard_event_binding(self):
self.bind("<Key>", self._callback)

def _callback(self, e):
key_map = {'c': 'Copy',
'a': 'A',
'i': 'i',
'!': 'x!',
'\r': '=',
'\x08': 'C',
'b': 'C',
'!': 'x!'}
if e.char.lower() in self._layout:
self._button_invoke(e.char)
elif e.char.lower() == 'c':
self._button_invoke('Copy')
elif e.char.lower() == 'a':
self._button_invoke('A')
elif e.char.lower() == 'i':
self._button_invoke('i')
elif e.char == '\r':
self._button_invoke('=')
elif e.char.lower() in ('\x08', 'b'):
self._button_invoke('C')
self._button_invoke(e.char.lower())
elif e.char.lower() in self._adv_layout:
self._button_invoke(e.char.lower())
elif e.char.lower() in key_map:
self._button_invoke(key_map[e.char.lower()])
elif e.char.lower() == 'q':
self.destroy()
elif e.char == '(':
self._button_invoke('(')
elif e.char == ')':
self._button_invoke(')')

def _calculate_answer(self, inputs_as_list):
calculate_instance = Calculate(inputs_as_list)
Expand All @@ -194,10 +219,10 @@ def _copy_to_clipboard(self, inputs_as_list):

def _adjust_and_set_TLabel_font(self, to_display):
"""Dynamic font size setting for display label widget."""
if(len(to_display) > 17):
font_size = 20*17//len(to_display)
if(len(to_display) >= 14):
font_size = int(14/len(to_display) * 25)
else:
font_size = 20
font_size = 25
FONT = 'Times '+str(font_size)
self.styler.configure("TLabel", font=FONT)
self.label_text.set(to_display)
57 changes: 29 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
# Pymanujan :sparkles:
### Python powered Calculator. As simple as that.
#### Introduction
Whole code is written in pure Python :snake:. Moreover, as a beginner myself, new developers and contribtors can easily go through the code to understand the logic behind the program. I tried to include as much as comments and documentations within the code itself. Feel free to ping me for any updates. This program has a lot of scope for improvement :sparkles:. Development best-suited for new developers and programmers, this simple program provides a stage for immense develpoment of one's skill, expertise and familiarity of Python programming language :snake:.
# Pymanujan ♾️
#### Python powered calculator; but without `eval()`.

Currently the program supports 'Addition :heavy_plus_sign:', 'Subtraction :heavy_minus_sign:', 'Multiplication :heavy_multiplication_x:' and 'Division :heavy_division_sign:'. Check **Tasks List** issues pending on *feature-requests*. Check **Contribution** for more details to get started on developing the program.
### Introduction
Whole code is written in Python. New developers and contribtors can easily go through the code to understand the logic behind the program. I tried to include as much comments and documentations within the code itself. Feel free to ping me for any queries. Best-suited for new developers this simple program provides a stage for develpoment of one's skill, expertise and familiarity of Python programming language.

#### User interface of Pymanujan *v2.0-alpha* :desktop_computer:
Pymanujan can do these now:
- ➕ Addition
- ➖ Subtraction
- ✖️ Multiplication
- ➗ Division
- ⭐ Exponentiation
- 🔺 Trigonometric functions
- 🔻 Inverse trigonometric functions
- ❗ Factorial
- 🌲 Logarithms

![As of v2.0-alpha](https://github.com/maddypie/Pymanujan/blob/master/Pymanujan-v2.0-alpha.png)

#### Tasks List :writing_hand:
- [x] **Refactor ~~source.py~~ source code.**
- [x] Add 'Copy' functionality, to copy the result. Currently 'Copy' button does not do anything.
- [x] Dynamic font size in result label.
- [x] Bind 'Number-pad' keys to enter input.
- [x] Option to switch between 'Simple' to 'Advanced' mode. Advanced mode should have more funtionalities.
### User interface of Pymanujan (v2.0) :desktop_computer:

#### Developer Installation:
![Pymanujan (v2 0)](https://user-images.githubusercontent.com/66778010/110975666-081e6c80-8386-11eb-9495-cf6b94204813.png)


### Build Pymanujan yourself:
Clone this repository from Github. Then create a virtual-environment and install the dependencies.
```bash
git clone https://github.com/maddypie/Pymanujan.git
git checkout dev
git clone https://github.com/tsadarsh/Pymanujan.git
cd ./Pymanujan
python3 -m venv env
source env/bin/activate
python -m pip install -r requirements.txt
python main.py
```

#### Contribution :nerd_face:
All are welcome :pray: to contribute to this project. Start from going through the ```source.py``` which has good amount comments and documentation along the code. Currently the focus is on improving the GUI. Create an *Issue* and start a discussion before working on a seperate *Fork*, collabaration always results in better ideas!
### Contribution :nerd_face:
All are welcome to contribute to this project.
Create new Issue for feature-request or bug reports.
Implemented a new feature? Awesome give a PR.

Goal :soccer: towards your contribution should always be to improve expertise on Python :snake:.
> Though a calculator app is no path-breaking project to work on, it gives confidence to a new-devloper the abilty to build something from scratch.

#### Note for Linux users:
For 'Copy' button to work as intended, make sure ```xclip``` is installed.
Distribution | Installation command
-------------|---------------------
Debian | `sudo apt install xclip`
Fedora based distro | `dnf install xclip`
CentOS based distro | `yum install xclip`
OpenSUSE based distro | `zypper install xclip`
Goal is to improve expertise on Python :snake:.
> "Though a calculator app is no path-breaking project to work on, it gives confidence to a new-devloper the abilty to build something from scratch"
> -maddypie

0 comments on commit 0476d02

Please sign in to comment.