-1

I am currently learning Python and have hit a wall. The assignment says to take our previous week's library and convert it to a class making all functions into methods I just can't seem to make it work for me, and the instruction in the course doesn't relate to the task.

PyCharm is giving me 8 errors of a variable being unfilled when I believe I have it defined and filled. I will attach all the code I have so far (Class and main project code). Thank you in advance for your advice!

Class/Library

class Calculator:
    p1 = ""
    lr: float = 0
    hr: float = 0
    num1: float = 0
    num2: float = 0

    def __init__(self, p1: str, lr: float, hr: float, num1: float, num2: float):
        self.p1 = p1
        self.lr = lr
        self.hr = hr
        self.num1 = num1
        self.num2 = num2

    def IsInRange1(self, lr, hr, num1):
        self.lr = lr
        self.hr = hr
        self.num1 = num1
        if float(num1) > hr or float(num1) < lr:
            num1 = float(input('Re-Enter your first number within your set range ' + str(lr) + ', ' + str(hr) + ': '))
            return num1
        else:
            pass
    def IsInRange2(self, lr, hr, num2):
        self.lr = lr
        self.hr = hr
        self.num1 = num2
        if float(num2) > hr or float(num2) < lr:
            num2 = float(input('Re-Enter your first number within your set range ' + str(lr) + ', ' + str(hr) + ': '))
            return num2
        else:
            pass

    def __add__(self, num1: float, num2: float):
        AddAnswer = self.__add__(num1, num2)
        return AddAnswer

    def __sub__(self, num1, num2):
        SubAnswer = self.__sub__(num1, num2)
        return SubAnswer

    def __truediv__(self, num1, num2):
        try:
            DivAnswer = self.__truediv__(num1, num2)
            return DivAnswer
        except ZeroDivisionError:
            print("Cannot divide by zero.")

    def __mul__(self, num1, num2):
        MultAnswer = self.__mul__(num1, num2)
        return MultAnswer

    def scalc(self, p1):
        answer = a_string = p1.split(",")
        num1 = float(a_string[0])
        num2 = float(a_string[1])
        if a_string[2] == "+":
            return Calculator.__add__(num1, num2)
        elif a_string[2] == "-":
            return Calculator.__sub__(num1, num1)
        elif a_string[2] == "*":
            return Calculator.__mul__(num1, num1)
        elif a_string[2] == "/":
            return Calculator.__truediv__(num1, num1)
        else:
            return num1, num1

    def allInOne(self, num1, num2):
        dict1 = {1: Calculator.__add__(num1, num2),
                 2: Calculator.__sub__(num1, num2),
                 3: Calculator.__mul__(num1, num2),
                 4: Calculator.__truediv__(num1, num2)}
        return dict1

Main project code:

import Week7_Lib
from Week7_Lib import Calculator
print("Welcome to the calculator loop!")
first_range = range(-80, 90)
print("This calculator's range is: -80, 90")

while True:
    # Get min range
    try:
        lr = int(input('Enter your Lower range: '))
    except ValueError:
        print("Please restart the program and enter a valid number for your low range.")
        exit()
    # Get max range
    hr = int(input('Enter your Higher range: '))
    # if statement to test ranges.
    # noinspection PyUnboundLocalVariable
    if hr < lr and lr > hr:
        lr = float(input('Re-Enter your Lower range: '))
        hr = float(input('Re-Enter your Higher range: '))
    else:
        print("Your range is: " + str(lr) + "," + str(hr))
        pass

    # Prompts user for first number.
    num1 = float(input('Enter first number for validation: '))
    first_number = Calculator(lr, hr, num1)
    first_number.IsInRange1()

    num2 = float(input('Enter second number for validation: '))
    second_number = Calculator()
    second_number.IsInRange2(lr, hr, num2)


   # num2 = IsInRange1(lr, hr, num2)

    print("\nPlease select a function below with the corresponding number.")
    menuList = {"1) Add": 1, "2) Subtract": 2, "3) Multiply": 3, "4) Divide": 4, "5) All In One": 5, "6) Scalc": 6}
    # menuSelect = input("Your selected function: ")
    for x in menuList:
        print(x)
    Choices = input("\nChoose a function: ")
    res = {}
    if Choices == '1':
        # res['add'] = wk6_gillespie_myLib.addition(num1, num2)
        print("The sum of ", num1, " + ", num2, " = ",
              Calculator.__add__(num1, num2))
    elif Choices == '2':
        # res["subtract"] = wk6_gillespie_myLib.subtraction(num1, num2)
        print("The difference of ", num1, " - ", num2, " = ",
              Calculator.__sub__(num1, num2))
    elif Choices == '3':
        # res["multiply"] = wk6_gillespie_myLib.multiplication(num1, num2)
        print("The multiplication of ", num1, " * ", num2, " = ",
              Calculator.__mul__(num1, num2))
    elif Choices == '4':
        # res["divide"] = wk6_gillespie_myLib.division(num1, num2)
        print("The division of ", num1, " / ", num2, " = ",
              Calculator.__truediv__(num1, num2))
    elif Choices == '5':
        # res = wk6_gillespie_myLib.allInOne(num1, num2)
        print("All functions of this calculator for ", num1, " and ", num2, " is: \n",
              Week7_Lib.allInOne(num1, num2))
    elif Choices == '6':
        p1 = input("Please re-enter two numbers and the operator seperated by commas (ex 10,20,+): ")
        print(Week7_Lib.scalc(p1))
    else:
        print("Unknown choice, please try again.")

    loop = input("Do you want to run this program again? Y/N: ")
    if loop == "Y" or loop == "y":
        loop = True
    else:
        print("Thank you for using the calculator.")
        exit()
NotAName
  • 3,821
  • 2
  • 29
  • 44
  • Welcome to Stack Overflow. Please read [ask] and [mre]. This is way too much code to expect others to read through, in order to understand the problem; and there should be **one specific** problem (which you should also [look up](https://meta.stackoverflow.com/questions/261592) before posting. It is your responsibility to understand **where** there is an apparently "unfilled" variable (please keep in mind that IDE warnings are only warnings, and the only thing that really matters is `python.exe`); we can help you understand **why** a specific part of the code doesn't "fill" that spot. – Karl Knechtel Oct 25 '22 at 01:24
  • Also, please have a read through my reference question, [I'm getting a TypeError. How do I fix it?](https://stackoverflow.com/questions/73631401/). – Karl Knechtel Oct 25 '22 at 01:28

1 Answers1

0

The initialiser of the class requires that you provide 5 values to create and instance of Calculator class:

    def __init__(self, p1: str, lr: float, hr: float, num1: float, num2: float):
        self.p1 = p1
        self.lr = lr
        self.hr = hr
        self.num1 = num1
        self.num2 = num2

You are only giving it 3:

first_number = Calculator(lr, hr, num1)

Or even none at all:

second_number = Calculator()

You can't do this.

If some of the values might not be necessary in every case, you can make them optional:

from typing import Optional

class Calculator:
    def __init__(
        self, 
        p1: Optional[str] = None, 
        lr: Optional[float] = None, 
        hr: Optional[float] = None, 
        num1: Optional[float] = None, 
        num2: Optional[float] = None
        ):

Alternatively, you can give them default values without using None:

class Calculator:
    def __init__(
        self, 
        p1: str = "", 
        lr: float = 0, 
        hr: float = 0, 
        num1: float = 0, 
        num2: float = 0
        ):

I guess, your confusion comes from the fact that you think you already provided default values here:

class Calculator:
    p1 = ""
    lr: float = 0
    hr: float = 0
    num1: float = 0
    num2: float = 0

But this is wrong, these are different type of variable. Variables defined under class name are class variables and they don't affect what happens in the initialiser. All of these declarations are completely unnecessary. You can get rid of them.

You can read more about class and instance variables here: Instance variables vs. class variables in Python

So if you want to have default values for an instance variable, you must provide those in the initialiser method.

Other small things:

        else:
            pass

This is completely unnecessary and just a waste of space.

Method names are un-pythonic:

def allInOne():  # Python doesn't use camel case

def all_in_one()  # use snake_case instead

Same with variables:

Choices = input()  # variables should also be in snake_case, so "choices" instead
NotAName
  • 3,821
  • 2
  • 29
  • 44