1
\$\begingroup\$

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)
mdfst13
22.4k6 gold badges34 silver badges70 bronze badges
asked Sep 6, 2021 at 2:52
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

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.

answered Sep 6, 2021 at 9:34
\$\endgroup\$
2
\$\begingroup\$

Building on what @riskypenguin suggests:

  • TermEva is a slightly awkward name, and is simpler and clearer as Term.
  • 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 using join 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()
answered Sep 6, 2021 at 14:22
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.