microsoft / calculator

Windows Calculator: A simple yet powerful calculator that ships with Windows
MIT License
29.62k stars 5.36k forks source link

Improve clarity of math expressions in history for Standard Calculator #138

Closed g-plane closed 3 years ago

g-plane commented 5 years ago

Describe the bug Operators precedence in standard mode seems wrong, but works correctly in scientific mode.

Steps To Reproduce

  1. Use standard mode.
  2. Type: 75×0.3+60×0.7 (which equals to 75*0.3 + 60*0.7)
  3. Press Enter
  4. Now you will get the wrong result.
  5. Switch to scientific mode.
  6. Type the same expression above and submit it.
  7. Now you can get the correct result.

Expected behavior 75*0.3 + 60*0.7 should be 64.5. However, the calculator will show the wrong result in standard mode.

Screenshots Standard mode: default

Scientific mode: default

Device and Application Information (please complete the following information):

Possible solution (additional) According to the disscusion of this issue, the calculation is expected. The bug is of the "History Panel". Some folks advised to add parens for expressions to be not confusing.

yatli commented 5 years ago

@g-plane standard mode calculates immediately before the next operator is armed, just like a "dumb tabletop calculator".

I do agree the expression in the calc history is confusing.

g-plane commented 5 years ago

just like a "dumb tabletop calculator"

Is this an expected behavior?

yatli commented 5 years ago

just like a "dumb tabletop calculator"

Is this an expected behavior?

not on the relevant team but I believe so. :)

The history page could use the following improvement:

- do not wait until a "=" to send the entry to the history
- instead, react on each key stroke (or button push)
- so the history view becomes a vertical list of key-in logs. this will cancel the confusion about operator precedence.
- one can select a range of key-ins in the history view to recall the list of actions into the calculator.
MovGP0 commented 5 years ago

I agree that this is the wrong behaviour, but I also guess that this is intentionally for folks who are used to those 'financial' (aka. cheap crap) calculators.

lxsmnsyc commented 5 years ago

I think this was an intentional behavior, similar behavior to that of a cheap calculator.

grochocki commented 5 years ago

Thanks for the report! I really appreciate your thoroughness when filing this bug.

Is this an expected behavior?

Yes, this is by design. Standard Calculator mode works in immediate-execution mode, just as a simple pocket calculator would. It ignores order of operations entirely. The solution today would be to use Scientific Calculator, though we have discussed this on the team in the past and agree we can do better at making this distinction clearer.

@yatli I think you are onto something with your suggested improvement to address the confusion with this.

I am going to close this bug as by design for now, but we welcome suggestions on how to improve this experience. Take a look at the pitch tempalte in our New Feature Process to get started.

KashifFaraz commented 5 years ago

I agree that this is the wrong behaviour, but I also guess that this is intentionally for folks who are used to those 'financial' (aka. cheap crap) calculators.

This also gives a wrong result on Windows 7 Calculator in Standard Mode. image

Fabian42 commented 5 years ago

@grochocki There was already a suggestion made by @yatli and I agree with it. Should there be a new "issue" about it or should this one be edited?

ssylvan commented 5 years ago

If your app ever prints "5+5*5=50", then that is a bug. The app is giving incorrect results. At the very least you need to print that out with parenthesis so that what you're saying is correct. Closing this as by design is ridiculous. You may have intended for it to behave this way, but that doesn't make it okay.

The fix is simple (or I should say, it should be simple - I must confess I find this code base hopelessly hard to navigate/understand and couldn't figure out how to make this simple change in a reasonable period of time).

Just like the physical calculator whose behavior you're trying to emulate: simply insert an implicit "Enter" key after each binary operator. That way after each operator, the result is evaluated and put in the "ans" slot, so that it can be used for the next operation. This makes it explicit that each binary operator is "eagerly" evaluated (rather than the current behavior, where you make it appear as if you're building up the whole expression, and then just going off and evaluating it incorrectly.. but also not giving any indication that this is what you did).

You can simulate this manually in the calculator and it works fine. For example, the 5+55 example would be 5+5 enter 5 enter and would look like this: image

Crystal clear what's going on, works just like old physical calculators (and prints results similarly to them), and no more "5+5*5=50" incorrect output.

EDIT: I see that this is exactly what @yatli suggested.

g-plane commented 5 years ago

As @ssylvan mentioned, I hope this issue can be reopened.

grochocki commented 5 years ago

@g-plane / @yatli / @Fabian42 / @ssylvan Feel free to reactivate this issue and update the top comment based on guidance outlined in our new feature process.

ssylvan commented 5 years ago

I don't think I can reactivate the issue (at least I don't see an option to do so), but I'll reiterate: if you are printing incorrect results, then that is a bug. Fixing bugs is not "a feature". There may be many ways of fixing this bug (e.g. either print with parenthesis or evaluate after each operator), but that doesn't change the fact that a calculator that explicitly tells its users that 5+5*5=50 is buggy.

g-plane commented 5 years ago

This issue was closed by @grochocki not by me, so I'm not able to reopen.

grochocki commented 5 years ago

Oops--reopening so we can evolve the idea.

Fabian42 commented 5 years ago

We can also not edit reports, only the reporter can (and maybe the repository owner or something like that?).

On Fri, 8 Mar 2019, 09:59 Dave Grochocki, notifications@github.com wrote:

Reopened #138 https://github.com/Microsoft/calculator/issues/138.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/calculator/issues/138#event-2189533537, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ_vYqwIbneRg7YeNSPosE9y37i6xsfzks5vUiaHgaJpZM4biQjp .

MicrosoftIssueBot commented 5 years ago

This is your friendly Microsoft Issue Bot. I've seen this issue come in and have gone to tell a human about it.

rudyhuyn commented 5 years ago

I worked last night on a Diff to add parenthesis to the History panel when using the Standard mode, but if it clears the confusion, in fact, it makes the history harder to read when we display:

((((2 + 3) x 2) + 5) x 4) x 2).

So I trashed my diff, and thought about a new way: display keys instead of operators:

image

I think it helps a lot and clears the confusion. It's a big refactoring, so before I start working on it, what do you think about this idea?

g-plane commented 5 years ago

Parenthesis should be added when needed.

ssylvan commented 5 years ago

Honestly I think the best thing to fix this is to make it work like those physical calculator (which appears to be the intent for the standard mode). I.e. add a line in the history for each operation (and its result), just like you would get on the "paper roll" on the old physical ones. Makes it very clear that the next operator takes the previous result as an input.

fwcd commented 5 years ago

Parentheses when needed seem to me like a good compromise between readability and correctness:

((2 + 3) x 2 + 5) x 4 x 2

ssylvan commented 5 years ago

Yeah.. The only danger with parenthesis is that it could get very "lispy" if you do a lot of precedence changes back and forth. But it would fix the actual bug (which is that the calculator prints things that are mathematically untrue) and maybe someone can work on a nicer presentation or whatever later to make it clear er why that's the order that was used.

mdtauk commented 5 years ago

I posted this in a twitter conversation. Standard mode treats the entries as discreet rolling operations, but the history display does not differentiate it from how the Scientific mode treats the order of operations.

You could show the intermediate values and list the history in the same way we are all taught to show our workings. New line for each operation, and display the intermediate value highlighted. Separate each press of the enter button with a line. Allow these to be collapsed to save space.

calculator history

Has as been mentioned, Scientific mode adheres to the BODMAS order of operations, but does not automatically insert the brackets, but does allow manual insertion of them.

Screenshot (12)

aWeinzierl commented 5 years ago

I think the way shown by @mdtauk is the way to go here, maybe using @rudyhuyn 's notion for the collapsed state.

Regarding the parenthesis, I will cite myself from #206:

The user assumes sequential evaluation. Thus, imho the parenthesis are redundant and could even be detrimental in the case the user is not used to using parenthesis.

I-Campbell commented 5 years ago

Yes, agree with @mdtauk. You could reduce clutter by omitting the result from the subsequent lines, eg 10x10=100 +2=102 *5= 510

The amount of history for people using the standard mode will probably be smaller than a typical scientific mode user, so having all the history on one line is probably not essential.

mysterytony commented 5 years ago

not relevant.. but how did you type these in an issue 🤔

image

fwcd commented 5 years ago

@mysterytony <kbd>CTRL</kbd> becomes CTRL

t-makaro commented 5 years ago

I think that adding parentheses is the wrong idea since BEDMAS is a convention (designed so parentheses aren't needed most of the time), and so long as it is clear than the convention is left-to-right, then there is *nothing wrong with "5+55=50"**. Additionally, the standard calculator does not have parentheses buttons. For this reason, I actually quite like @rudyhuyn's solution of printing the keys instead of the operators.

That said, +-/ are not the only operators in the standard calculator. Consider the button sequence: 55sqrt=

The sqrt is only applied to the one 5 and not the entire calculation before it, so the convention isn't exactly left-to-right (and the history doesn't try to convey that it is here). The history for this sequence displays: 5 x √(5)=.

For this reason, I agree with @aWeinzierl, and @I-Campbell of using a more detailed collapsible history with @rudyhuyn's notation in the collapsed state. The history for the above sequence would display:

5x√(5)=

I think this is acceptable.

vashek commented 5 years ago

This bug mainly discusses the presentation of the history of operations in Standard mode, which I agree is wrong. But there is another issue: had I not randomly stumbled upon this bug (or, I suppose, stumbled upon the behavior in practice), I would never have guessed there is such a major difference in behavior between Standard and Scientific mode. On the first look, it just looks like Standard mode hides some buttons for simplicity but otherwise is the same. And to make matters worse, Calculator remembers which mode you used last time. So if you just hit the calculator key on your keyboard and type 1+2*3, whether you get 7 or 9 depends on what mode you happened to be using the last time you used Calculator. That is horribly counter-intuitive and user-unfriendly.

As for a solution, I would propose two things: 1) In Standard mode, always kept prominently displayed a message such as "In Standard mode, the conventional order of operations is not adhered to", and 2) Always start in one mode (not whatever happened to be used last time), so that the behavior is predictable. Make it possible to explicitly select which mode that should be.

(I would also argue that Standard is the wrong name for this misbehavior. It should be standard to adhere to the conventional order of operations.)

tngreene commented 5 years ago

Name ideas:

And for the symbol in history - maybe it just needs to be not an equals sign. A big Unicode arrow? "2 + 3 * 2 made :arrow_right_hook: 10 happen"

mdtauk commented 5 years ago

Name ideas:

"Immediate Answer Mode" "Calculate-As-You-Go Mode" "Basic Entry Mode" "Non-PEMDAS Mode"

And for the symbol in history - maybe it just needs to be not an equals sign. A big Unicode arrow? "2 + 3 * 2 made ↪️ 10 happen"

I agree, if you take my previous suggestion, and then replace the intermediate equals signs with arrows.

You could also drop the repeating of the intermediate value on subsequent lines if you control the formatting so entries are aligned vertically.

calculator history 2
Fabian42 commented 5 years ago

One problem with the "Non-PEMDAS" title suggestion is translation. For example in German we don't have such an abbreviation and instead it's "Punkt-vor-Strich-Rechnung".

On Mon, 11 Mar 2019, 02:36 tngreene, notifications@github.com wrote:

Name ideas:

  • "Immediate Answer Mode"
  • "Calculate-As-You-Go Mode"
  • "Basic Entry Mode"
  • "Non-PEMDAS Mode"

And for the symbol in history - maybe it just needs to be not an equals sign. A big Unicode arrow? "2 + 3 * 2 made ↪️ 10 happen"

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/calculator/issues/138#issuecomment-471376969, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ_vYoPP8S0t90u3GQX0J0Md07OX93kfks5vVbMvgaJpZM4biQjp .

mdtauk commented 5 years ago

When I was at school, here in the UK, we were taught BODMAS (Brackets in Order of Division Multiplication Addition Subtraction)

Sequential Evaluation is the best description of the default Standard mode I have seen, but not a catchy name. You could add bracket buttons to the Standard mode, which when used, would force it to adhere to the Order of Operations.

Fabian42 commented 5 years ago

Does that mean you do every addition before every subtraction?

On Mon, 11 Mar 2019, 07:13 Martin Anderson, notifications@github.com wrote:

When I was at school, here in the UK, we were taught BODMAS (Brackets in Order of Division Multiplication Addition Subtraction)

Sequential Evaluation is the best description of the default Standard mode, but not a catchy name. You could add bracket buttons to the Standard mode, which when used, would force it to adhere to the Order of Operations.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/calculator/issues/138#issuecomment-471416526, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ_vYud_5805R7kanvyKwFWhCq3L2dHyks5vVfQYgaJpZM4biQjp .

mdtauk commented 5 years ago

@Fabian42 Technically these are grouped Brackets, Order, Division/Multiplication, Addition/Subtraction but I suppose it makes sense to add numbers together, before subtracting another number from it

Fabian42 commented 5 years ago

No, it doesn't. 1-2+3 is 2, not -4.

On Tue, 12 Mar 2019, 14:15 Martin Anderson, notifications@github.com wrote:

@Fabian42 https://github.com/Fabian42 Technically these are grouped Brackets, Order, Division/Multiplication, Addition/Subtraction but I suppose it makes sense to add numbers together, before subtracting another number from it

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/calculator/issues/138#issuecomment-471995070, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ_vYjPLXjb-AfdieU_-IAt_k5yx-QDOks5vV6hagaJpZM4biQjp .

tngreene commented 5 years ago

I'd like to point out when I suggested PEMDAS, I was well aware of the cultural specifics and assumed there would be translations. I found another one "Immediate Execute" and "Chain calculation" (thanks wikipedia) Also, "Simple Calculator", "Simple Input".

No, it doesn't. 1-2+3 is 2, not -4. On Tue, 12 Mar 2019, 14:15 Martin Anderson, @.**> wrote: @Fabian42 https://github.com/Fabian42 Technically these are grouped Brackets, Order, Division/Multiplication, Addition/S*ubtraction but I suppose it makes sense to add numbers together, before subtracting another number from it — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#138 (comment)>, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ_vYjPLXjb-AfdieU_-IAt_k5yx-QDOks5vV6hagaJpZM4biQjp .

After reading this I thought long and hard and looked through a laughably old journal I found from 1st and 2nd grade. It seems I had teachers who had different ways of explaining this concept which implied a left to rightness or not. Some very violent disagreements in blog posts seem to imply P->E->M->D->A->S vs P->E->(MD)->(AS) (where () means equal priority, and evaluated left to right)) is not universal knowledge.

mdtauk commented 5 years ago

Simple is a bit too negative a term (as would be Basic) it makes it feel lacking, whereas the other modes should be additive, building on the Standard mode.

I still think the easiest option would be to show the intermediate value in the history, whilst also adding the Brackets to the Standard button layout, so Order of Operation can be enforced. The common aspect with all those Mnemonics is the Brackets/Parenthesis

tngreene commented 5 years ago

This is really two bugs/features by now: "What is a more descriptive name than "Standard Mode"" and "How do you show chain input in an intuitive way?" Which I still like @mdtauk's vision the best.

MovGP0 commented 5 years ago

I agree that it should be clear that the calculator is not adhering to the PEMDAS/BODMAS/Punkt-vor-Strich-convention, by adding the required brackets in the output.

MovGP0 commented 5 years ago

Another thing to consider here would be how the % button works.

When entering 2+3+5%, the output will be 2+3+0.25 = 5.25, which is clearly the wrong result.

It is totally unclear to the user if the calculator did the 2+3+(5%) = 2+3+5/100 = 2+3+0.05 = 5.05 (which would be the mathematically correct solution) 2+(3+5)%, (2+3+5)%, (2+3)(100%+5%), 2+(3)(100%+5%), or whatever, without doing the calculation manually on paper.

So having an output that cleary indicates what the calculator really did and properly put the brackets on there, would be very helpful in this case.

joshkoon commented 5 years ago

Another thing to consider here would be how the % button works.

When entering 2+3+5%, the output will be 2+3+0.25 = 5.25, which is clearly the wrong result.

It is totally unclear to the user if the calculator did the 2+3+(5%) = 2+3+5/100 = 2+3+0.05 = 5.05 (which would be the mathematically correct solution) 2+(3+5)%, (2+3+5)%, (2+3)_(100%+5%)_, 2+(3)(100%+5%), or whatever, without doing the calculation manually on paper.

So having an output that cleary indicates what the calculator really did and properly put the brackets on there, would be very helpful in this case.

The % key is an interesting key in its own right, independent of any discussion about how to show precedence. Raymond Chen wrote a blog post about this key back in 2008: https://blogs.msdn.microsoft.com/oldnewthing/20080110-00/?p=23853/

More recently, we took a look at how the % key is handled across the industry (it varies wildly), and made a decision to change how the percent key operates with multiplication and division. At the time the blog post was written, X [op] Y% was calculated as X [op] (X Y / 100). This is still the case for addition/subtraction, but the functionality now for multiplication and division is simply X [op] (Y / 100). We believe this adjustment allows the key to function more in line with what users would expect when inputting, for example, 50 20%.

All this is to say: this is a great discussion about how to best illustrate precedence, but the percent key is perhaps not the best example as its behavior varies and is not well defined across the industry.

MovGP0 commented 5 years ago

@joshkoon that was exactly my point. because the implementation varies so widely, it should be clear from the output what was actually calculated.

I personally just ignore the key altogether, because it's unclear what it does. I use an explicit /100 instead (if at all, since I can do that operation in the head anyway).

The same is with the PEMDAS vs. left-to-right execution. It is unclear to more mathematical thinking users and should therefore be more explicit in the output.

ghost commented 5 years ago

We reviewed the pitch and would love to explore this idea further! The pitch is a great start, but there are still some open questions. Moving this into planning to iron out some of those details. A human will follow up with some feedback on your pitch shortly. Keep in mind that not all ideas that make it into the planning phase are guaranteed to make it to release. For more information on next steps, check out our spec workflow.

grochocki commented 5 years ago

First, we really appreciate all of the great conversation that has been going on in this issue. There have been a lot of great ideas about how to clear up this confusion, but we would like to focus on one solution in particular as we move into planning.

After giving it a bit of thought, we would like to keep Standard Calculator working just as a simple pocket calculator would, but as some folks in this thread have pointed out, we believe the root cause of the confusion here is how we show these expressions in history.

Today, we populate a history item after the user hits =. This works great in all of the other calculator modes, since the other modes do not operate in immediate-execution. In Standard Calculator, every time you perform an operation, it is effectively a soft =.

Instead of attempting to add parentheses, which could quickly become very visually complex, we would like to explore making each of those soft = equivalent to a hard =. That is, we ensure that history items are added for each transaction that is made, instead of waiting for the user to hit =. This transactional history ensures that we are never showing an "invalid" expression that fails to follow order of operations.

I think this is basically (but not exactly) the idea that @mdtauk proposed. There are still some details to figure out, so I created calculator-specs/transactionalHistory to track progress.

andrewstellman commented 4 years ago

Had a quick back-and-forth with @JeGentle on Twitter about this. Maybe a simple color change could help make this more visually obvious without affecting the behavior of the calculator at all, and without overcomplicating things. Here's a simple mock-up.

Windows Calculator UX to make order of operations more obvious

Fabian42 commented 4 years ago

That highlights "220 x 0.5", which is exactly what did not happen. This reply sounds more reasonable: https://twitter.com/BrandonLive/status/1281604102632296455 That would just highlight "x 0.5" then. Alternatively, the calulation so far could collapse to its result. So when you enter "230-220", you see "230-220" at the top and "10" at the bottom, then when you hit ×, the top becomes "10×" (maybe with a nice animation) and the output stays "10", then when you type "0.5", the top is "10×0.5" and the output "5", everything correct and hopefully somewhat clear. (BTW, why "x" instead of "×" or "·"?)

andrewstellman commented 4 years ago

It's actually a complex and subtle UX problem, and like I said on the Twitter thread, it would take some experimentation. It's really easy to go down a rabbit hole of overdesigning a solution to this problem.

Yes, your proposed solution makes sense when there are just two terms—and yes, everyone who's seen this problem thought of it, too 😉—but it's problematic. Adding intermediate results, animations, etc., works fine with three terms (230 − 220 × 0.5), but the meaning gets really muddled when once you have a string of terms.

I attached an updated mockup (which now uses × and ÷ instead of x and / since you asked) that shows a longer expression. Try adding intermediate results between all of the terms and it quickly devolves into a visual mess. Adding intermediate terms to the calculation log contorts its meaning, changing it from "this is a record of what you typed" to "this is what the calculator is thinking," which really gets away from the original intention of the standard mode.

That's why I like visually fading all but the last two terms: it highlights that the last two terms are important without altering the semantics of the UI. In effect, it says, "These two terms are the important ones," without changing the overall meaning of that part of the interface. And it keeps the last two terms un-faded as you type in more terms, which reinforces the idea that those are the important part of the expression.

It's still not an awesome solution, and I'm sure it can be improved on, but I think it's a step in the right direction.

Windows Calculator UX

michael-hawker commented 4 years ago

Actually just thinking, what if it put the whole old thing in brackets:

image

(Maybe it could put parenthesis in whenever it needs to so if you evaluated the expression in BEDMAS mode it'd still evaluate to the same answer?)

andrewstellman commented 4 years ago

That's a really interesting idea! It keeps the semantics intact while still being arithmetically correct. Nice!

grochocki commented 4 years ago

Great conversation here! A couple things to consider: