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 builtin Pythonista examples, but none which quite met my needs for dealing with prewritten text. There are also specialpurpose apps for things like tickertape 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 onevariable expression, assumes it's an equation with the other side zero and feeds it to sympy to solve. If it's a onevariable equation, back to sympy. Should handle most basic daytoday tickertape math needs, in only 75ish lines of actual code.
https://gist.github.com/paultopia/16e69f9f72ad0a5000fa5b4575ddeee2

@paultopia, this is really fun! And useful. I am tempted to build a little machinery around this, maybe a scroll view that shows the latest calculations, an entry field and two buttons, one that calculates with what’s given, and another that starts from the previous result... Or something like that.

@mikael That would be cool! I can stick this into a proper repo if you want ...

@paultopia, as a first thing, I made an Apple shortcut to enter the text, but that is not ideal as there does not seem to be a way to force the keyboard to numbers mode in Shortcuts.
Then I made Siri take dictation. This needed a lot of languagespecific tweaking to convert the operations (e.g. Siri likes to use '×' and '÷') and small numbers (Siri prefers ”four” to ”4” in many cases). And all of these in Finnish, of course.
But now the kids are astonished when I solve equations by speaking to Siri. 👍🏻😁

@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 reimplemented 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 inapp keyboard, which is excellent, as crossapp custom keyboards need to ask for permission.

@mikael ok, sorry, inapp

@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.