I'm making a program that can add 2 terms that the user types.
I think I've got identifying or evaluating the terms down. I used classes because I just recently learned it and I also heard it was good practice in order to make your programs shorter. But, when it comes to adding 2 terms together (which is the code under the else
and elif
statements) I tried using classes but I have no idea how that would work, so I just sort of brute forced it. Is there a shorter or otherwise better way to code the adding part? Surely there is, and I would appreciate it if someone could show me what to learn or focus on or pretty much just any good advice so that I can code it cleaner.
class TermEva:
def __init__(self, Variable, Coefficient):
self.Variable = Variable
self.Coefficient = Coefficient
self.ExVariable = Variable
if self.Coefficient < 0:
self.ExVariable = "-" + self.Variable
def SimTerm(self):
return "{}{}".format(self.Coefficient, self.Variable)
def Expanded_Form(self):
ExpandedForm = []
for n in range(abs(self.Coefficient)):
ExpandedForm.append(self.ExVariable)
return ExpandedForm
Term1 = TermEva(input("Enter Variable 1: "), int(input("Enter its Coefficient: ")))
Term2 = TermEva(input("Enter Variable 2: "), int(input("Enter it's Coefficient: ")))
print(Term1.SimTerm())
print(Term2.SimTerm())
if Term1.Variable == Term2.Variable:
VariableSum = Term1.Variable
CoefficientSum = Term1.Coefficient + Term2.Coefficient
ExVariableSum = VariableSum
if CoefficientSum < 0:
ExVariableSum = "-" + VariableSum
ExpandedFormSum = []
for num in range(abs(CoefficientSum)):
ExpandedFormSum.append(ExVariableSum)
TermSum = str(CoefficientSum) + str(VariableSum)
elif Term1.Variable != Term2.Variable:
ExTerm1_Variable = Term1.Variable
ExTerm2_Variable = Term2.Variable
if Term1.Coefficient < 0:
ExTerm1_Variable = "-" + Term1.Variable
if Term2.Coefficient < 0:
ExTerm2_Variable = "-" + Term2.Variable
ExpandedFormSum = []
for num in range(abs(Term1.Coefficient)):
ExpandedFormSum.append(ExTerm1_Variable)
for num in range(abs(Term2.Coefficient)):
ExpandedFormSum.append(ExTerm2_Variable)
if Term2.Coefficient < 0:
TermSum =(Term1.SimTerm() + Term2.SimTerm())
elif Term2.Coefficient >= 0:
TermSum =(Term1.SimTerm() + "+" + Term2.SimTerm())
print(TermSum)
2 Answers 2
General
Attributes, variable names, function names and function arguments should be lowercase / snake_case
.
You should wrap your main procedure in a main function, as well as a if __name__ == '__main__'
guard. More info.
Documentation makes your code easier to read and understand. Use docstrings and comments to explain why and how your code is doing what it's doing.
Type hints make your code easier to read and understand, use them. PEP 484 | Python Docs
TermEva.__init__
self.ex_variable = ex_variable
if self.coefficient < 0:
self.ex_variable = "-" + self.variable
Depending on the value of self.coefficient
, self.ex_variable
will either be a number or a string. Sticking to the number representation seems more intuitive here:
self.ex_variable = ex_variable
if self.coefficient < 0:
self.ex_variable = self.variable * -1
On closer inspection, your main
functionality always passes strings to the constructor of TermEva
. I don't think this is intended, as your implementation of TermEva
implies the arguments are numbers. You should generally check user input for correctness and then convert it to the desired type.
TermEva.sim_term
f-strings are a great tool for string formatting:
def sim_term(self):
return f"{self.coefficient}{self.variable}"
TermEva.expanded_form
This pattern of list creation
expanded_form = []
for num in range(abs(self.Coefficient)):
ExpandedForm.append(self.ExVariable)
can (and often should) be replaced by a more functional approach:
return [self.ex_variable for _ in range(abs(self.coefficient))]
return [self.ex_variable] * abs(self.coefficient)
Note that it's convention to use _
as a variable name for loop variables you don't actually use. This makes it immediately clear to the reader that the value of num
is not needed.
Building on what @riskypenguin suggests:
TermEva
is a slightly awkward name, and is simpler and clearer asTerm
.- Replace your
SimTerm
with a standard implementation of__str__
. Expanded_Form
is not used, so you can just delete it; or if you want to keep it, you should be usingjoin
if it's only for print.- This is a clear application for a frozen
dataclass
that enforces immutability and writes your constructor for you. You can then include a@classmethod
pseudoconstructor to centralize your input capture routine. - Consider implementing
__add__
on the class. - An implementation that can generalize the "expanded form sum" as well as the basic two-term sum would separate the concept of a term and an equation, with the latter having its own class and holding references to terms in a list. I haven't shown this below.
Suggested
from dataclasses import dataclass
from numbers import Real
@dataclass(frozen=True)
class Term:
variable: str
coefficient: Real
def __str__(self) -> str:
return f'{self.coefficient:g}{self.variable}'
@classmethod
def from_stdin(cls, sequence: int) -> 'Term':
return cls(
input(f'Enter variable {sequence}: '),
float(input('Enter its coefficient: ')),
)
@property
def expanded_form(self) -> str:
if not self.coefficient.is_integer():
raise ValueError(f'Expanded form cannot be represented for {self}')
n = int(abs(self.coefficient))
if self.coefficient >= 0:
return ' + '.join((self.variable,) * n)
return ' - '.join((
f'-{self.variable}',
*((self.variable,) * (n - 1))
))
def __add__(self, other: 'Term') -> str:
if self.variable == other.variable:
return str(Term(self.variable, self.coefficient + other.coefficient))
if other.coefficient < 0:
return f'{self} - {-other.coefficient}{other.variable}'
return f'{self} + {other}'
def main() -> None:
x = Term.from_stdin(1)
y = Term.from_stdin(2)
print(x + y)
if __name__ == '__main__':
main()
Explore related questions
See similar questions with these tags.