-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d90911e
Showing
14 changed files
with
1,001 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from Libraries.ProblemManipulator import ProblemManipulator | ||
from Libraries.DoMath import DoMath | ||
from Libraries.FileHandler import FileHandler | ||
import os | ||
|
||
def read_file(): | ||
"""Function to open the file to get the problem to be calculated""" | ||
open_file = FileHandler("r") # calls the file handler class | ||
problem_string = open_file.mod_string() | ||
open_file.close_file() | ||
return problem_string | ||
|
||
def manipulate_problem(problem_string): | ||
"""Function that manipulates the lists of string to be used for the calculations""" | ||
math_problem = ProblemManipulator(problem_string) # calls problem manipulator class | ||
math_problem.check_operators() | ||
math_problem.ensure_single_ops() | ||
outputs = math_problem.prob_manip() | ||
return outputs[0], outputs[1], outputs[2] | ||
|
||
def do_calculations(problem_numbers, problem_operators, op_start): | ||
"""Function to do the main calculation""" | ||
do_the_math = DoMath(problem_numbers, problem_operators, op_start) # calls the do math class | ||
do_the_math.calculation() | ||
answer = do_the_math.answer() | ||
return answer | ||
|
||
def write_file(answer): | ||
"""Function to write answer back to file""" | ||
open_file_to_write = FileHandler("w") # calls the file handler class again in a different file mode | ||
open_file_to_write.write_answer(answer) | ||
open_file_to_write.close_file() | ||
|
||
def main(): | ||
"""Main Running Function""" | ||
os.chdir(os.path.abspath("TextFiles")) | ||
# calls function to read the text file to get the problem | ||
problem_string = read_file() | ||
# checks whether a problem was actually entered | ||
if len(problem_string) != 0: | ||
# calls function to sort and manipulate the problem so it can be calculated | ||
problem_numbers, problem_operators, op_start = manipulate_problem(problem_string) | ||
# calls function to calcualte the answer to the problem provided | ||
answer = do_calculations(problem_numbers, problem_operators, op_start) | ||
# calls function to write the calculated answer back to the file | ||
write_file(answer) | ||
else: # if there wasn't one entered then the answer is set to error so that can be sent back | ||
answer = "Error" | ||
write_file(answer) | ||
# deletes the nul file created in the autohotkey script, so the while loop can be broken | ||
os.remove("Nulfile.txt") | ||
os.chdir("..") | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
; Perliminary | ||
DetectHiddenWindows, On ; needed to control a hidden window | ||
; ------------ Hotstring Used ----------- | ||
::domath:: | ||
|
||
; ------------- Autohotkey Front End Initial ------------ | ||
; takes user problem, creates the file, puts problem in the file, creates nul file | ||
FileDelete, TextFiles\ProblemAndAnswer.txt | ||
Input, OutputVariable, IV *, {esc}, eq ; asks the user to enter their problem | ||
LengthOfCalculation:= StrLen(OutputVariable) + 1 ; checks the string length | ||
Send {ShiftDown} {Left %LengthOfCalculation%}{ShiftUp} {Backspace} | ||
Sleep 5 | ||
Send Calculating ; just show the script is working | ||
; adds the problem to the output file | ||
FileAppend, %OutputVariable% , TextFiles\ProblemAndAnswer.txt | ||
; adds a nul file to be deleted later in the python file (important) | ||
FileAppend, , TextFiles\Nulfile.txt | ||
|
||
; ---------- Python Back End --------- | ||
; runs python script in hidden command prompt, modifies output file with answer | ||
Run, cmd.exe, , Hide, pid2 ; opens a hidden comand prompt | ||
Sleep 5 ; makes sure that the command prompt has come up | ||
; While loop so as long as the nulfile exists the python command can run its entiriety | ||
; without having to use sleep commands | ||
While, FileExist("TextFiles\Nulfile.txt") | ||
{ | ||
ControlSend, , python DoCalculations.py {enter}, ahk_pid %pid2% ; sends python command to hidden cmd | ||
} ; only broken when the python command has run all the way through to the end | ||
Process, Close, %pid2% ; closes the command prompt | ||
Process, WaitClose, %pid2% ; waits for the command prompt to close | ||
|
||
; ---------- Autohotkey Front End Final --------- | ||
; reads the file with answer, and posts it in window | ||
FileRead, OutputCalculation, TextFiles\ProblemAndAnswer.txt | ||
Send {ShiftDown} {Left 12}{ShiftUp} {Backspace} ; deletes the calculating string | ||
Sleep 5 | ||
Send, %OutputCalculation% ; Send the aswer of the problem back to the user | ||
return |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import math | ||
|
||
class DoMath(object): | ||
"""Class that does the mathematics calculations""" | ||
def __init__(self, numbers, operators, op_position): | ||
self.numbers = numbers | ||
self.operators = operators | ||
self.op_position = op_position | ||
|
||
def float_convert(self): | ||
"""Method that converts the numbers strings to floats""" | ||
for i in range(0, len(self.numbers)): | ||
self.numbers[i] = float(self.numbers[i]) # maps all numbers to their float value | ||
|
||
def check_first_op_position(self): | ||
"""Method to check if the first position in the problem is an operation""" | ||
if self.op_position == True: # operator was first in the calculation | ||
mod_numb = float("{}{}".format(self.operators[0], self.numbers[0])) # add the operator to its number | ||
self.numbers[0] = mod_numb # modify the number | ||
del self.operators[0] # delete operator from list | ||
else: | ||
None | ||
|
||
def check_special_chars(self): | ||
"""Method for taking into account special constants""" | ||
for i in range(0, len(self.numbers)): | ||
if self.numbers[i].lower() == "e": | ||
self.numbers[i] = math.e # converts e to its numerical value | ||
elif self.numbers[i].lower() == "pi": | ||
self.numbers[i] == math.pi # converts pi to its numerical value | ||
else: | ||
None | ||
|
||
def calculation(self): | ||
"Method loop used to calculate the problem""" | ||
self.check_special_chars() # check for the constants | ||
self.float_convert() # converts all the nunbers to floats | ||
self.check_first_op_position() # - check method - | ||
while len(self.operators) != 0: # loops calculation method over the amount of operators | ||
self.idmas_procedure() | ||
|
||
def idmas_procedure(self): | ||
"""Method that uses idmas order for calculations""" | ||
i = 0 | ||
while i < len(self.operators): # checks indices | ||
if self.operators[i] == "**" or self.operators[i] == "^": | ||
calculation = self.det_calc(self.numbers[i], self.numbers[i + 1], "ind") | ||
self.remapper(i, calculation) | ||
i += 1 | ||
else: | ||
break | ||
i = 0 | ||
while i < len(self.operators): # checks division | ||
if self.operators[i] == "/": | ||
calculation = self.det_calc(self.numbers[i], self.numbers[i + 1], "div") | ||
self.remapper(i, calculation) | ||
i += 1 | ||
else: | ||
break | ||
i = 0 | ||
while i < len(self.operators): # checks multiplication | ||
if self.operators[i] == "x" or self.operators[i]=="*": | ||
calculation = self.det_calc(self.numbers[i], self.numbers[i + 1], "mult") | ||
self.remapper(i, calculation) | ||
i += 1 | ||
else: | ||
break | ||
i = 0 | ||
while i < len(self.operators): # checks addition | ||
if self.operators[i] == "+": | ||
calculation = self.det_calc(self.numbers[i], self.numbers[i + 1], "add") | ||
self.remapper(i, calculation) | ||
i += 1 | ||
else: | ||
break | ||
i = 0 | ||
while i < len(self.operators): # checks subtraction | ||
if self.operators[i] == "-": | ||
calculation = self.det_calc(self.numbers[i], self.numbers[i + 1], "sub") | ||
self.remapper(i, calculation) | ||
i += 1 | ||
else: | ||
break | ||
|
||
def remapper(self, i, calculation): | ||
"""Method used to modify the different lists for further calculations""" | ||
del self.numbers[i +1] | ||
del self.numbers[i] | ||
del self.operators[i] | ||
self.numbers.insert(i, calculation) # replaces both values with the new calcualted value | ||
|
||
def answer(self): | ||
"""Method to print final answer""" | ||
check_for_integer = self.numbers[0].is_integer() # check if answer is an integer float | ||
if check_for_integer == True: | ||
self.numbers[0] = int(self.numbers[0]) # make it an integer i.e get rid of the decimal place | ||
else: | ||
None | ||
return self.numbers[0] | ||
|
||
def det_calc(self, A, B, operation_to_do): | ||
"""Method to do the calculations between two of the numbers""" | ||
if operation_to_do == "add": # adds two values | ||
sub_calc = A + B | ||
if operation_to_do == "sub": # subtracts two values | ||
sub_calc = A - B | ||
if operation_to_do == "mult": # multiplies two values | ||
sub_calc = A * B | ||
if operation_to_do == "div": # divides two values | ||
sub_calc = A / B | ||
if operation_to_do == "ind": # puts one value to the power of the other | ||
sub_calc = A ** B | ||
return sub_calc |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import os | ||
|
||
class FileHandler(object): | ||
"""Class that handles reading and writing to file""" | ||
def __init__(self, mode): | ||
self.file_name = "ProblemAndAnswer.txt" | ||
self.mode = mode # defines what mode the file should be opened in | ||
self.file_object = open(self.file_name, self.mode) | ||
|
||
def mod_string(self): | ||
"""Method used to read string from file and make it usable | ||
byt the rest of the programme""" | ||
defined_string = self.file_object.read() | ||
defined_string = defined_string.split(" ") #gets rid of the spaces in between numbers and operators | ||
del defined_string[-1] # deletes the "eq" that was used to show that the user was done entering the problem | ||
return defined_string | ||
|
||
def write_answer(self, answer): | ||
"""Method to overwrite the file with the answer to the calculation""" | ||
self.file_object.write(str(answer)) # converts the answer to a string to be written to the file | ||
|
||
def close_file(self): | ||
"""Method to close the file after use""" | ||
self.file_object.close() | ||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
class ProblemManipulator(object): | ||
"""Class for doing the first manipulations of the problem object""" | ||
def __init__(self, problem): | ||
self.problem = problem | ||
self.numbers = [] | ||
self.operations = [] | ||
|
||
def check_operators(self): | ||
"""Method for working out whether the signs should change e.g. | ||
if there is a number subtracted from a negative - - becomes +""" | ||
for i in range(0, len(self.problem) - 1): | ||
if self.problem[i] == "-" and self.problem[i + 1] == "+": # a - and + become - | ||
del self.problem[i] | ||
elif self.problem[i] == "+" and self.problem[i + 1] == "-": # a + and - become - | ||
del self.problem[i] | ||
elif self.problem[i] == "-" and self.problem[i + 1] == "-": # a - and - become + | ||
del self.problem[i] | ||
self.problem[i+1] = "+" | ||
else: | ||
continue | ||
|
||
def ensure_single_ops(self): | ||
"""Method to ensure that no two operations are next to eachother so | ||
they can be sorted into numbers and operators very easily""" | ||
for i in range(0, len(self.problem) - 1): | ||
if self.problem[i] == "*" and self.problem[i + 1] == "-": # checks if there is a multiply and subtract sign next to eachother | ||
mod_number = "{}{}".format(self.problem[i + 1], self.problem[i + 2]) | ||
self.problem[i + 1] = mod_number | ||
del self.problem[i + 2] | ||
elif self.problem[i] == "x" and self.problem[i + 1] == "-": # alternate multuplication sign | ||
mod_number = "{}{}".format(self.problem[i + 1], self.problem[i + 2]) | ||
self.problem[i + 1] = mod_number | ||
del self.problem[i + 2] | ||
elif self.problem[i] == "/" and self.problem[i + 1] == "-": # checks if there is a division and subtract sign next to eachother | ||
mod_number = "{}{}".format(self.problem[i + 1], self.problem[i + 2]) | ||
self.problem[i + 1] = mod_number | ||
del self.problem[i + 2] | ||
else: | ||
continue | ||
|
||
def prob_manip(self): | ||
"""Method that sorts the problem into two different lists, one for the numbers | ||
and one for the operators to be used on them""" | ||
if self.problem[0] == "-" or self.problem[0] == "+": | ||
self.operations.append(self.problem[0]) | ||
for i in range(1, len(self.problem), 2): | ||
self.numbers.append(self.problem[i]) | ||
for i in range(2, len(self.problem), 2): | ||
self.operations.append(self.problem[i]) | ||
op_postion = True # this determines whether an operator is first in the problem | ||
else: | ||
for i in range(0, len(self.problem), 2): | ||
self.numbers.append(self.problem[i]) | ||
for i in range(1, len(self.problem), 2): | ||
self.operations.append(self.problem[i]) | ||
op_postion = False # false means that a number is first in the problem. | ||
return self.numbers, self.operations, op_postion |
Binary file not shown.
Empty file.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# SolveIt | ||
This project allows you to do quick inline calculations while writing. By using autohotkey to look for a hostring and python to calculate it. | ||
|
||
## Getting Started | ||
These instructions will get you a copy of the project up and running on your local machine for development and testing puposes. | ||
|
||
### Prerequisites | ||
* The latest version of autohotkey if you are planning to just run the raw script. | ||
* The lastest distribution of Python 2.7 whether you are running the Autohotkey executable or the raw script. | ||
|
||
### Installation and Use | ||
1. Place the folder whether you like and either run the executable file or run the raw .ahk script for the script to run. | ||
2. Type the hotsring "domath" to activate the input process. | ||
3. Type your mathematics problem with spaces between each number and operation. | ||
4. When you are finished entering your desired problem leave a space and type "eq" (for equals). | ||
5. And your problem will be calculate and outputted back to your window/ | ||
6. Enjoy | ||
|
||
### Supported Operations | ||
The operations follow BIDMAS order of calculation without the B as brackets are not supported yet (IDMAS) | ||
* Indices can be calculated with inputting either a " ^ " or " ** " between two numbers. | ||
* Division can be calculated by inputting a " / " between two numbers | ||
* Multiplication can be calculated with inputting either a " x " or " * " between two numbers | ||
* Addition can be calculated by inputting a " + " between two numbers | ||
* Subtraction can be calculated by inputting a "-" between two numbers | ||
You are able to put two operations next to eachother, the program will resolve to one operation upon calculation | ||
e.g if you input "11 - - 11 eq" the program will resolve the two negatives to "11 + 11 eq" | ||
|
||
## Built With | ||
* Autohotkey | ||
* Python 2.7 | ||
|
||
### Things To Improve | ||
Other than optimisations to the python code, I want to find an easier way for Autohotkey and python to communicate with eachother | ||
effectively. Right now i am using a Run command for the cmd and sending the python command to it for them to communicate with | ||
eachother. It works surpringly well but it is not ideal. This process is outlined in DoMath.ahk file. | ||
|
||
Also I want to find a way to make the calculation happen in real-time. So the programme will recognize without the use of a hotkey or hotstring | ||
that you are typing a problem and automatically solve it for you. | ||
|
||
### License | ||
This project is licensed under the GNU General Public License v3.0 - see the LICENSE.md file for details |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Error |