Forum Archive

Calculator

Sebastian

Hey guys! I made this calculator, which I think works pretty good.
It's a simple graphical calculator with the usual like addition, subtraction, multiplication, division, percentage, square root and some other stuff. It should work on iPad and iPhone.
Let me know what you think, and if there are any bugs!

omz

Very nice! I like how this has less than 100 lines of code. :)

Perhaps you could add some sort of feedback for invalid input, for example like this (makes the text red and plays an 'error' sound):

https://gist.github.com/omz/572fe9f33a37988ebc63

Sebastian

Thanks! That's a great idea :) I'm glad I found the Button class, but I haven't found it in the docs. I found it kinda by accident as I created a Button class myself, and then I removed the class but the script still worked XD

I've fixed one bug though, if you pressed the "%" button, and then typed a number, like for instance 25, it would suddenly change to 0.025. I fixed it by switching from "continue" to "pass".

omz

Oh, I didn't even notice you used the Button class – sneaky! ;)

It's not documented because it's somewhat incomplete, but if you're curious how it works, you could try this in the console:

import inspect
import scene
print inspect.getsource(scene.Button)

(this can also come in handy for other things)

You'll notice that it has an action attribute. That's actually a function that gets called when the button is tapped, and you could use it to get rid of all your manual touch handling code. Here's another modified version that takes advantage of this:

https://gist.github.com/omz/e1ea63513f458578f144

Sebastian

Awesome! That shortened it a lot :)
Thanks for the great info @omz!
Also, the inspect module was really handy ;)

jose3f23

@omz and Sebastian, nice code. Thanks.

Please, @omz: how to change text size in TextLayer class in your undocumented Button class ?

And how about button pads text changing with context ?

omz

@jose3f Neither TextLayer nor Button (which uses a TextLayer internally) support changing the text after initialization.

When you look at the source code for TextLayer with the inspect module, you'll see that it's a very simple class (under 10 lines of code) that basically just renders the given text as an image (using render_text()) and sets the result as the Layer's image attribute, adjusting the size of the layer accordingly. If you wanted to create a TextLayer subclass that allows changing the text, a simple implementation could look like this:

class MutableTextLayer (TextLayer):
  def set_text(self, text, font, font_size):
    img, size = render_text(text, font, font_size)
    self.image = img
    self.frame = Rect(self.frame.x, self.frame.y, size.w, size.h)
jose3f23

@omz: The problem subclassing TextLayer is that Button class calls at init TextLayer not MutableTextLayer. So imho subclassing Button is also required.
Thanks.

eliskan175

@Sebastion - Very awesome. I never knew about how to use eval.

Did some research and I wish I had known this sooner. I had written genetic algorithms and probably should have used eval to calculate their strings. Ended up basically writing a function to do the same thing :(

The more you know.

Sebastian

@eliskan Thanks :)
The eval function makes a lot of things much easier :)

eliskan175

Yeah my function ended up being a 20 line function that created a NEW function at runtime.. it was a solution I found that had worked for my problem, but really a short eval would have done the trick.

This program you wrote here was very elegant. I wish I could program that cleanly