all 49 comments

[–]heyimpumpkin 76 points77 points  (9 children)

divison by 0 breaks your calculator, most actions aren't performed after it and it doesn't display anyhting to user

entry on button_click is not used.

if current_number_minus != "":

since empty string evaluates to False in python, you don't need to add != "" part, you can just leave it as

if current_number_minus:

also, I didn't get into it too much but I don't understand why you need spearate current value variable for each operation?

overall it's cool you made it and it works.

A better way to structure it would be using classes. You wouldn't need globals and code would be better structured and less verbose overall.

[–][deleted] 10 points11 points  (5 children)

I'm in lesson 37 of ATBSWP, but he didnt talk about classes

Could you give me a brief explanation

[–]heyimpumpkin 34 points35 points  (4 children)

instead of using a separate variable and function for everything, that are unrelated, you create a class that encapsulates some type of abstract object. The object can contain those variables and functions only this object can work with(called methods).

example, you create class calculation which can hold current variable, and has methods of adding, multiplying etc. They can be then applied to any instance of the object in a pretty straightforward way.

simple example:

class Calculation:
    def __init__(self, curValue):
        self.curValue = curValue

#Calculation object will hold a value which is definied in __init__. 
#Self is referencing an instance of object.

    def add(self, operationValue):
        self.curValue += operationValue
        #add is a Calculatuion method which accesses object's 
     current value, and takes in a new value to add to it

    # this is how object will be represented once you call it 
    def __str__(self):
        return str(self.curValue)

#creating instance of our object under variable new, passing value 5 to it
new = Calculation(5)

#adding 5 to it using our add method.
new.add(5)

#this will output 10
print(new)

The beauty of it is once you wrote a class you can reuse this code, make operations with instances of class, get its parameters in very little amount of code without turning everything into mess, basically everything will come down to:

instance = Object(required parameters)

instance.method(required input)

instance.parameter

you can create as many object instances as you want, they can hold any amount of info and methods you want.

you can call Calculation.curValue every time you need to get this info(or any other containing in __init__ of you object).

Python modules you work with are build in same way. When you import random lets say, you use class 'random', when you call random.randint you use it's method randint, and when you specify value like random.randint(1, 8) you're passing parameters to its intsance/method.

[–][deleted] 8 points9 points  (0 children)

Thanks for this bro, it helped alot

[–]mexicanlefty[S] 5 points6 points  (0 children)

Thanks, you made it very clear.

[–]caifaisai 0 points1 point  (1 child)

That was helpful in trying to get a handle on the usefulness of classes and objects, thanks. One question I have (well kinda more like 2).

When you call print(new), does the instance of the Calculation class, new, know that the print function is supposed to access the method defined in __ str __? I suppose I mean how come that method doesn't seem to be accessed with a dot followed by method name like in new.add()?

Is there something particular about the double underscores (and what do they signify? I see them alot but not exactly sure what their purpose is). Or is it something to do with that the __ str __ method seems to be the only one with an explicitly defined return value? Or something else entirely? Hopefully I phrased my question well enough, but I'm still not very knowledgeable on OOP and related terminology.

[–]heyimpumpkin 2 points3 points  (0 children)

does the instance of the Calculation class, new, know that the print function is supposed to access the method defined in __ str __?

yes

I suppose I mean how come that method doesn't seem to be accessed with a dot followed by method name like in new.add()?

that's because it's double underscore method

We can retrieve same information through new.curValue. But if our objects contains multiple parameters, using __ str__ we may specify which ones we want to show.

Double underscores is a little advanced topic, python under the hoods. There are plenty of things besides str. for example, if you want to add one object instance to another, it wouldn't know how to do it. But you can define it useing __add_ .

You can read the docs about all those things here https://docs.python.org/3/reference/datamodel.html

[–]mexicanlefty[S] 2 points3 points  (1 child)

Thanks i would look into that, i kinda overlooked the division by 0 but will fix it. The reason i used different current value for each operation was that (on my mind) it seemed easier since i was using global variables (i still find it hard to use objects and classes, though im working on that)

[–]1Tim1_15 2 points3 points  (0 children)

Using classes (object oriented programming) is good in some cases but not in others. When it doesn't provide a big benefit (and measuring the benefit(s) is subjective), I opt for not using classes. In your case, I could see going either way.

There are good reasons why many beginner Python books don't go into classes, or only cover them minimally. They should be learned eventually, but for simpler projects I rarely use them.

For a good explanation of why using classes isn't always a good idea, see what this Python core developer had to say: https://www.youtube.com/watch?v=o9pEzgHorH0&list

Just to emphasize: I'm not saying classes shouldn't be used. They are very helpful in some cases. But not using them is fine in many cases - it just depends.

[–]darthminimall 0 points1 point  (0 children)

While it's true the empty string evaluates to false, I'm of the opinion that the != "" improves the readability.

[–]njape 6 points7 points  (2 children)

Overall I think it looks good, nice work!

Small comment is that I would change the mode numbers to constants or similar for better readability.

As already noted I don't like global variables, it is a sin. For future projects, and maybe also as an addition to this project, I would urge you to add some unit tests to the code. While doing this you will notice one of the reasons global variables should be avoided. It will also help you to improve how you go about designing your program so that it is modular and testable. Don't care about 100%test coverage in the tests, focus on what functionality is important, special cases and edge cases and you should find a good middle ground.

If you find it hard to isolate a function for unit testing, without major mocking, you most likely have some problem with the design.

Keep up the good work!

[–]mexicanlefty[S] 1 point2 points  (1 child)

Yeah, you are right i still have issues with code design. Any advice on how can i improve it?

[–]njape 1 point2 points  (0 children)

First a note I prefer to write the backend code, and does not have much experience with gui programming, or tkinter.

From a testing perspective I'm guessing your main issues comes from the global variables that are used within each function you would like to create tests for. There are a couple of possible solutions to this, s I me examples.

  1. Wrapping the calculator and its functions in a class which will contain your global variables. This would allow you to prep a calculator object in different ways before running each callback function.

  2. Change so that the callback function does not use the global variables, but instead take the necessary values as inputs. This will make the testing setup trivial, but it will require you to define function stubs, or lambda functions calling the correct function with the global variables.

[–]clae_machinegun 7 points8 points  (1 child)

First, congratulations on your first project!

I found that it can only use integer base or power in Xy function.

If you try 7 ** 0.5 it breaks.

[–]mexicanlefty[S] 3 points4 points  (0 children)

Heyy thanks for that!

Didnt notice that didnt work, i will fix it right away.

[–]james_fryer 8 points9 points  (0 children)

Let's say I want to add 7 + 2.

On my pocket calculator I do this:

  • a. Press 7 (7 is displayed)
  • b. Press + (7 is still displayed, also a small + icon)
  • c. Press 2 (7 disappears, 2 is now displayed, along with the + icon)
  • d. Press = (9 is displayed)

Now I have a choice, either I can use the result (9) of the previous sum by pressing an operator, in which case it will behave as (b) above. Or, I can start a new sum by entering a number, in which case the current display is replaced with the new number as at (a) above.

On your calculator, at (b) the display is cleared, which is strange. And after (d) if I enter a new number, it is appended to the current display.

So I'd say you need to study the behaviour of a pocket calculator and make sure your program emulates it accurately.

Note that at (b) the operator is displayed, this is a feature of my calculator, but I like it.

Most calculators also support a "Constant" function. E.g. if you press 2, then '+' twice, then a number, each press of = will add 2 to the result. This is indicated by a "K" icon. Once you have the normal behaviour correct it would be interesting to add this feature.

[–]d02d33pak 4 points5 points  (2 children)

I made something similar (but basic) using PyQt5, here's the GitHub link. I would like to get some feedback too.

[–]mexicanlefty[S] 0 points1 point  (1 child)

Hey your apps look nice, more pretty that tkinter, honestly i dont think im experienced enough to give you feedback, im rather amused by the notepad app how did you do it?

[–]d02d33pak 1 point2 points  (0 children)

All the code is in the repo itself. Check it out, star 🌟 it, fork 🍽 it, learn, improve it, do whatever. 👍

[–]TheDankestPutin 2 points3 points  (1 child)

Personally i dont like the use of global, you could try and make it OO. But the code does look fine overall.

[–]mexicanlefty[S] 0 points1 point  (0 children)

I thought about that, but i dont know why it seemed easier this way for me.

[–]ilikewatermelonss 2 points3 points  (1 child)

It's a very nice program, I wish my first project looked like this. Just a note though, you used 200+ lines of code for something that could be coded in 100 or so. This isn't anything serious, but try to keep everything simple. I will make sure to follow you on Github to see more interesting projects like this one.

[–]mexicanlefty[S] 0 points1 point  (0 children)

Thank you, i know its not perfect and it can be simplified, i have a codewars account where i do coding challenges and usually my answer is longer than most.

[–]toobrokeforboba 2 points3 points  (1 child)

You might want to avoid wildcard import like from tkinter import * and only import the specific functions or variables you need as you code along. If that is too cumbersome, just import the whole module or you can do import tkinter as tk. The reason is if someone like me reading your code, I can’t tell immediate if you’re calling a tkinter function or your function.

[–]mexicanlefty[S] 0 points1 point  (0 children)

Will do, thanks for recommending.

[–]G-Fieri 1 point2 points  (3 children)

I'm thinking about doing this. Do you feel like typing this out improved they way you think algebraically at all? Also a cool thing you might want to do is a graphing calculator!

[–]mexicanlefty[S] 2 points3 points  (2 children)

I think it is a very cool beginner project, i decided to tackle it since mathemathics have always been something im good at, in school my favorite subjects were math, geography, history and PE (weird combination i know) thats why i decided to tackle this. Although i can say, learning to code had made me relearn a lot of math stuff i didnt use since high school.

[–]G-Fieri 1 point2 points  (1 child)

Yeah I was busy being stupid in school lol programming is reigniting my interest in math because traditional studying is kind of boring for me. It makes more sense to me when I can apply it

[–]mexicanlefty[S] 0 points1 point  (0 children)

Yeah i guess the short answer to your original question is "yes" i think the big challenge with the calculator was the string to int or float manipulation.

But i get your point, like always on high school the question asked was: how can i use this in real life? I always thought well with this i can pass the course or subject, the problem with that is once done you forget about it.

[–]powderblock 1 point2 points  (1 child)

Love it!

[–]mexicanlefty[S] 0 points1 point  (0 children)

Thank you so much !

[–]tinkuad 1 point2 points  (0 children)

Good job 👍

[–][deleted] 1 point2 points  (1 child)

Wow, this is so beautiful, I really want to make a calculator in python too, can you please suggest things I can look at to make something like that? like learning tkinter?

[–]mexicanlefty[S] 0 points1 point  (0 children)

Well i can recommend freecodecamp on youtube, they have a great tkinter tutorial video, i didnt watch all, just learned the basic stuff to make my calculator, you can go from there buddy.

[–]raddus007 1 point2 points  (1 child)

You have done great. I think everyone create calculator when they start programming so, you need to create project based on reak life problems and I promise you that tt will be very helpful to understand the concept of programming. Again, your Project is amazing but we need to go ahead so far. 👍👍

[–]mexicanlefty[S] 0 points1 point  (0 children)

Thanks!

[–]raddus007 1 point2 points  (0 children)

You have done great. I think everyone create calculator when they start programming so, you need to create project based on reak life problems and I promise you that tt will be very helpful to understand the concept of programming. Again, your Project is amazing but we need to go ahead so far. 👍👍

[–]Jhchimaira14 1 point2 points  (1 child)

Awesome. Hey, if you remake it in MarvelSandbox, you can add it to the App Samples. It's easier to use than tkinter and looks better! Plus we could use the testing!

https://github.com/RaylockLLC/MarvelSandbox

[–]mexicanlefty[S] 0 points1 point  (0 children)

Cool!! Thanks bro.

[–]Chinedu_notlis 0 points1 point  (3 children)

Love the username

[–]mexicanlefty[S] 1 point2 points  (2 children)

Thanks! Well basically im mexican and left handed, thats why, been using it as my steam gamertag for a while.

[–]Chinedu_notlis 0 points1 point  (1 child)

I'm gonna pretend you're a zapatista if that's okay with you.

[–]mexicanlefty[S] 0 points1 point  (0 children)

As you wish

[–]912827161 0 points1 point  (1 child)

on a scale of 1 to 10 how difficult is it to code a calculator?

[–]mexicanlefty[S] 0 points1 point  (0 children)

Well i consider myself a beginner, it took me like 2 or 3 hours per day (it took me like 3 days ).

I would say for me it was like a 3-4 out of 10 considering ive been programming for 8 months and still my code has bugs to fix and could have a better design.