Divide 0 and similar logical issues

122 views
Skip to first unread message

Jonty Small

unread,
May 26, 2022, 5:32:44 AM5/26/22
to Blockly
Hi All,

Am i correct in assuming the default generator for the math_arithmetic in python doesn't account for divide by 0 causing issues in generated code?

Has anyone tried to build a safety net around this? If so how did you do it?
Is there anyway to stop a user doing something like:
    a=2
    a/(a-a)
or even harder:
    a=2
    b=2
    a/(a-b)

It may be something we have to handle post generation. But if anyone has neat solutions it'd be great to hear them!

Furthermore are there any other standard Blockly blocks that open up issues like this?

best,
Jonty


Jason Schanker

unread,
May 26, 2022, 12:08:04 PM5/26/22
to Blockly
Hi Jonty,

This problem will also come from a math_number_property block with a DIVISIBLE_BY PROPERTY value.  A runtime error can also be thrown from the generated code from Python if you give a math_single block with a ROOT OP an input that produces a negative number (i.e., evaluating a square root of a negative number).  

Solving this problem in general would provably require you to reject programs that would never result in division by 0 errors.  But even if we were to reject programs like this, there's an illustrative example from a Wikipedia page that I remember seeing along the lines of:

if some difficult true/false question to answer: x = 1
else: x = 0

So should we reject a division by x here?  Or what about the difference of two randomly generated integers from 1 to 10, which might or might not cause a division by 0 error like x = randint(1, 10) - randint(1, 10)?

You could certainly handle specific cases like the first one you mentioned, but I think you might find it more trouble than it's worth to protect against these types of errors.  For instance, you could use Blockly.Python.blockToCode to check if two blocks in a subtraction block that's the divisor in some division block produced the same code.  But then you'd also need to check to make sure that the generated code only involved pure functions to avoid potentially false positives for division by 0.  And this wouldn't handle cases where you would definitively be dividing by 0 when the two blocks produced say, 1 * 2 and 2 * 1.

Best,
Jason

Neil Fraser

unread,
May 26, 2022, 1:59:25 PM5/26/22
to blo...@googlegroups.com
This is a really tricky problem to solve.  As Jason points out with his randint example, it is impossible to statically analyze code to see if there will be a divide by zero error.  The only solution would be to create a function:

def divide(a, b):
  if b == 0:
    return float("inf")
  return a / b

Then change the generators for "/" and "is divisible" to call divide.  The downside of this approach is that the generated code would be less readable, which is poor for some educational experiences where students are expected to see and eventually edit the code.  But it is an approach that we could consider for Python (JavaScript's native divide handles zero without throwing).

There is a similar issue with the "change x by y" block.
Screen Shot 2022-05-26 at 10.55.01.png
One would think that it would just generate "x += 1", but actually it generates "x = (x if isinstance(x, Number) else 0) + 1".  That's so that if x hasn't been initialized to zero, it can still be used.  But it generates ugly code.

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/e7e4589b-e6ba-4856-88dc-8823ecd8c772n%40googlegroups.com.


--

Gregory Dyke

unread,
May 26, 2022, 3:20:45 PM5/26/22
to blo...@googlegroups.com
Are there any exception handling blocks yet? Most languages would trigger a runtime exception for divide by 0. The question then becomes whether the exception is recoverable from - and at what level. For example is it's user input, that whole "user operation" would need cancelling, but a new user operation could then be triggered. And that would mean handling the exception at some higher level?
Greg

Jonty Small

unread,
May 30, 2022, 8:26:41 AM5/30/22
to Blockly
Hi all,

Thanks for the feedback on this post,
It all makes a lot of sense.

I think Neils point about educational is very interesting here. We're focused on using Blockly for commercial applications. As such, readability is less of a concern. Error handling blocks are a very good idea for educational tools again but for commercial it adds a new layer of complexity that may be off putting to users. I

Personally I think the best solution would be defining each output of blocks as a function rather than direct to code. We'd begun doing that for our custom blocks as it allows better version control without having to rerun the block to code conversion. For educational focused projects I think having 2 conversions: the first that is shown to the user showing 1/0 and a second that actually executes Neils function would be the best overall solution. It doesn't teach error handling but at least allows the user to progress. With a function you can also then throw alerts to the user teaching them at run time. Obviously if incorporating error handling blocks that changes it a bit but there is probably a way to tie these two solutions together.

I think this also opens a longer open discussion on the difference between education focused and commercial focused applications and how they handle various issues.
General code readability is probably one of the biggest differences that I see.
There are specific challenges that commercial sees more often:
for example much larger drop down menus. But here the solution can be directly ported over to educational as well.

I'm not sure if there are other challenges that have a divergent solution for educational/commercial?

best,
Jonty

Mark Friedman

unread,
Jun 6, 2022, 4:15:10 PM6/6/22
to blo...@googlegroups.com
Thanks for the provocative questions, Jonty!  I made some comments inline.

On Mon, May 30, 2022 at 5:26 AM Jonty Small <smal...@gmail.com> wrote:

I think Neils point about educational is very interesting here. We're focused on using Blockly for commercial applications. As such, readability is less of a concern.

It kind of depends on the specific type of commercial or educational application, but I think you are mostly right. For commercial applications, though, sometimes the commercial user wants to export the code to some other environment or IDE where they can continue work on the textual code.  In that situation (which I understand is not your situation) readability might be important.  On the flip side, an educational use of Blockly might be more concerned with ease of use and/or safety of the code and not care much about readable code at all.  App Inventor is a good example of a tool which uses Blockly but doesn't care about the readability of the code.  Though I must say that some of the educators using it would like that as an option.

Error handling blocks are a very good idea for educational tools again but for commercial it adds a new layer of complexity that may be off putting to users. 

Of course that depends on what exactly the tool is trying to teach!
 

...

I'm not sure if there are other challenges that have a divergent solution for educational/commercial?

I think it really has a lot to do with the specifics of the educational or commercial applications.

-Mark

Neil Fraser

unread,
Jun 7, 2022, 6:34:46 AM6/7/22
to blo...@googlegroups.com
Yes Mark, I couldn't agree more.  Some educational apps need to generate clean code (Blockly Games), others no not (Scratch).  Some commercial apps do, others do not.

At the latest developer's summit we talked about some of the differences between Blockly in educational vs commercial settings.  To date I've never seen a single attribute or feature (existant or desired) that divides the two.

ewpa...@gmail.com

unread,
Jun 8, 2022, 5:18:19 PM6/8/22
to Blockly
I'd like add my support in emphasizing that it really depends on what you're trying to do.

In App Inventor, our philosophy is that the blocks are the code. Why is text code somehow superior to blocks? Why not insist that people translate it to punch cards, platform specific assembly, or use electron microscopes to look at the transistor states on the SOC? Presumably if you think text is closer to what the machine is doing than the blocks, then there are certainly other representations even closer to what the machine is doing than text.

In regards to the divide by zero approach, we use a technique similar to what Neil proposed in Python (App Inventor uses Scheme) where we have a macro to handle the case where the denominator is 0 and raise an error accordingly.

Cheers,
Evan

Reply all
Reply to author
Forward
0 new messages