Sharing a script: solve arbitrary blocks of text as math.
-
A common task I have: I want to write down some numbers or a simple formula of some kind, and then go ahead and do something with the numbers or solve a simple equation with them. Examples: writing down how much I paid for each bill in a note or drafts, then summing them; working out a simple algebra equation for something like a mildly complicated tax/tip situation and then solving it.
There are lots of calculators in the built-in Pythonista examples, but none which quite met my needs for dealing with pre-written text. There are also special-purpose apps for things like ticker-tape calculators, but I don't think any of them do algebra, and, besides, why pay for a separate app when pythonista is right there plus has the full power of sympy available?
So I wrote my own little script. Takes share sheet or clipboard input string. If it's just a list of numbers, sums them. If there are arithmetic operators, evaluates the expression. If it's a simple one-variable expression, assumes it's an equation with the other side zero and feeds it to sympy to solve. If it's a one-variable equation, back to sympy. Should handle most basic day-to-day ticker-tape math needs, in only 75-ish lines of actual code.
https://gist.github.com/paultopia/16e69f9f72ad0a5000fa5b4575ddeee2
-
@mikael said:
I made an Apple shortcut to enter the text
Why do you want to enter the numbers in a shortcut and not in Pythonista which could allow a user keyboard with only digits?
-
@cvp, actually started from the dictation, then when that was initially quite unreliable, checked out what the typing experience was like.
After checking the out of the box capabilities, I am now moving full hog to Pythonista.
First thing I noted was that iOS is really missing a native keyboard option that would be spot on for a calculator.
-
last edited by
-
@cvp, very true. Would need to add a few mathematical operations, and then it would be perfect. Does the user have to give permission if you use this?
-
@paultopia, to make sure I understand what is happening, and to add a few features like result precision and tokenization, I re-implemented your code as a class. It is here, intended to be used like this:
>>> Kalkylation("1 2\\n3") Input: 1 + 2 + 3 Symbolic result: 6 Numeric result: 6.00 >>> k = Kalkylation("1 = 2+x") >>> k Input: 1 = 2 + x Symbolic result: -1 Numeric result: -1.00 >>> k.tokens ['1', '=', '2', '+', 'x'] >>> Kalkylation.result_decimals = '.000001' >>> Kalkylation("1+23 =3+x**2") Input: 1 + 23 = 3 + x ** 2 Symbolic result: -sqrt(21), sqrt(21) Numeric result: -4.582576, 4.582576
-
@mikael said:
Does the user have to give permission if you use this?
Sorry if I don't understand your question but my code is available here
-
@cvp, I meant that this looks like an in-app keyboard, which is excellent, as cross-app custom keyboards need to ask for permission.
-
@mikael ok, sorry, in-app
-
@mikael error
NameError: name 'ROUND_HALF_EVEN' is not defined
from decimal import Decimal, ROUND_HALF_EVEN
-
@cvp, curious, works for me. Restart Pythonista?
-
@mikael As this is a "from decimal", it seems normal to import it, isn't it?
from decimal import Decimal, ROUND_HALF_EVEN
Has solved
-
Copy my SetTextFieldPad from GitHub and place this code after @mikael 's module
import ui from SetTextFieldPad import SetTextFieldPad def my_action(sender): sender.TextField.close() tf = ui.TextField() #pad = [{'key':'','title'=:'','icon':''}] pad = [{'key':'1'},{'key':'2'},{'key':'3'}, {'key':'back space','icon':'typb:Delete'}, {'key':'new row'}, {'key':'4'},{'key':'5'},{'key':'6'}, {'key':'delete','icon':'emj:Multiplication_X'}, {'key':'new row'}, {'key':'7'},{'key':'8'},{'key':'9'}, {'key':'x'}, {'key':'new row'}, {'key':'+'},{'key':'='}, {'key':'⏎', 'action':my_action}, {'key':'new row'}, {'key':'nul'},{'key':'0'}] SetTextFieldPad(tf,pad=pad) tf.text = '' tf.width = 400 tf.present('sheet') tf.begin_editing() tf.wait_modal() k = Kalkylation(tf.text) print(k)
And you will get
-
@cvp said:
from decimal import Decimal, ROUND_HALF_EVEN
My turn to misunderstand, sorry. I thought you had already added this, and it still wasn’t finding it.