I swear, those things are like shurikens in these masses...
I'm trying to make a loan calculator in python, as part of an assignment. I'm basing it off of two things.
1: This website, which contains 3 different calculators.
2: The link from the second calculator (my current pain)
I'm going to have a panic attack, I swear... So many parentheses.
I had to manually derive for the Newton-Raphson portion... and of course, now I have so many frekaing parentheses that I can't tell what the heck I'm doing... I mean, sure, I might be a little parenthesis-happy, but I'm new to this and I want to make sure my groupings are all correct...

``````def findInterestRate():
loanAmount = raw_input("Please enter the loan amount: ")
monthlyPayment = raw_input("Please enter the monthly payment: ")
numberMonths = raw_input("Please enter the number of months: ")
# YAY complications.
finderGuess = (2((numberMonths*monthlyPayment)-loanAmount))/(numberMonths*monthlyPayment)
while zeroFindings != 0:
zeroFindings = ((finderGuess*((1+finderGuess)^numberMonths))/(((1+finderGuess)^numberMonths)-1))-(monthlyPayment/loanAmount)
if ziggy == 1 and zeroFindings != 0:
# now to show off the x~k+1 = x~k - f(x~k)/f`(x~k)
# Yes, the ~ denotes the subscript with the k.
finderGuess = finderGuess - ((((finderGuess*((1+finderGuess)^numberMonths))/(((1+finderGuess)^numberMonths)-1))-
(monthlyPayment/loanAmount))/(((((1+finderGuess)^numberMonths)-1)
(finderguess*(numberMonths*((1+finderGuess)^(numberMonths-1)))+
(1+finderGuess)^((finderGuess*(1+finderGuess)^numberMonths)*
(numberMonths*((1+finderGuess)^(numberMonths-1)))))/
((((1+finderGuess)^numberMonths)-1)^2))))
ziggy = 1

Rabblerousers I hate this whole enters thing with parentheses... only way I can see it all in the window...
Takes up a whole freaking lot...
Does little to soothe my pains...
...
Can I get at least one person to help me double-check this, I feel like I'm missing things.
Especially after realizing that I had accidentally hit control+backspace at one point and it erased a small portion at one spot... which means I might have done it multiple times...

And of course, I'm hoping and praying that I get this fixed as I know this will bite my rear in the end if I messed this part up of all things.

Edit: It would be nice if the GUI had color-coded parentheses, to show groupings... or better yet, shading of a similar method...

## All 8 Replies

Buddy you are not using enough functions, if you need everything in one function(sometimes teachers require this) you can declare functions within a function but it gets pretty messy.

It would be nice if the GUI had color-coded parentheses, to show groupings... or better yet, shading of a similar method...

Why not use one that does then?

I use Notepad++, but I know that even python-specific IDEs like PyScripter have parenthesis highlighting, etc. In fact, PyScripter will have a red underline on any unmatched parenthesis similar to a "spelling error" in a word processing application.

I think you should learn Lisp to get familiar with parenthesis.
Yes, you are using too many of those in your Python code. You can study up in the precedence of mathematical operations to remove a fair number of them.

http://xkcd.com/297/
Sorry, i dont usually link things. But this feels appropriate :)

I would also say that your code suffers from excessively long variable names. Try to keep each code line's total length somewhat less then 70.

Then there is ziggy and a 2 caught between (( etc. etc.

IMHO, the title of this thread should be:
Ack... drowning... in... bad coding style...

I ran pylint on this code. Here is the result (note that this depends on my personal configuration of pylint, it may give a different result on your system)

``````\$ pylint --disable-msg W0311 bad.py
C:  6: Line too long (93/80)
C:  8: Line too long (132/80)
C: 12: Line too long (124/80)
C: 13: Line too long (107/80)
C: 14: Line too long (136/80)
C: 15: Line too long (138/80)
C: 16: Line too long (147/80)
C: 17: Line too long (84/80)
C:  1: Missing docstring
C:  1:findInterestRate: Invalid name "findInterestRate" (should match [a-z_][a-z0-9_]{2,30}\$)
C:  1:findInterestRate: Missing docstring
C:  2:findInterestRate: Invalid name "loanAmount" (should match (?:(?:[a-k]|[m-z])|[a-z_][a-z_0-9]{2, 30}))
E:  6:findInterestRate: 2 is not callable
E:  7:findInterestRate: Using variable 'zeroFindings' before assignment
E:  9:findInterestRate: Using variable 'ziggy' before assignment
Exception RuntimeError: 'maximum recursion depth exceeded while calling a Python object' in <type 'exceptions.RuntimeError'> ignored
E: 14:findInterestRate: Undefined variable 'finderguess'

Report
======
12 statements analysed.

Duplication
-----------

+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |0        |=          |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000    |=          |
+-------------------------+------+---------+-----------+

Raw metrics
-----------

+----------+-------+------+---------+-----------+
|type      |number |%     |previous |difference |
+==========+=======+======+=========+===========+
|code      |16     |76.19 |16       |=          |
+----------+-------+------+---------+-----------+
|docstring |1      |4.76  |1        |=          |
+----------+-------+------+---------+-----------+
|comment   |1      |4.76  |1        |=          |
+----------+-------+------+---------+-----------+
|empty     |3      |14.29 |3        |=          |
+----------+-------+------+---------+-----------+

Statistics by type
------------------

+---------+-------+-----------+-----------+------------+---------+
|type     |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module   |1      |1          |=          |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|class    |0      |0          |=          |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|method   |0      |0          |=          |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|function |1      |1          |=          |0.00        |100.00   |
+---------+-------+-----------+-----------+------------+---------+

Messages by category
--------------------

+-----------+-------+---------+-----------+
|type       |number |previous |difference |
+===========+=======+=========+===========+
|convention |12     |12       |=          |
+-----------+-------+---------+-----------+
|refactor   |0      |0        |=          |
+-----------+-------+---------+-----------+
|warning    |0      |0        |=          |
+-----------+-------+---------+-----------+
|error      |4      |4        |=          |
+-----------+-------+---------+-----------+

Messages
--------

+-----------+-----------+
|message id |occurences |
+===========+===========+
|C0301      |8          |
+-----------+-----------+
|E0601      |2          |
+-----------+-----------+
|C0111      |2          |
+-----------+-----------+
|C0103      |2          |
+-----------+-----------+
|E1102      |1          |
+-----------+-----------+
|E0602      |1          |
+-----------+-----------+

Global evaluation
-----------------
Your code has been rated at -16.67/10 (previous run: -16.67/10)``````

commented: Nice :) +2

Thanks for making people aware of the pylint tool. It's been a while since I used it on my own code. :)

``````finderGuess = finderGuess - ((((finderGuess*((1+finderGuess)^numberMonths))/(((1+finderGuess)^numberMonths)-1))-
(monthlyPayment/loanAmount))/(((((1+finderGuess)^numberMonths)-1)
(finderguess*(numberMonths*((1+finderGuess)^(numberMonths-1)))+
(1+finderGuess)^((finderGuess*(1+finderGuess)^numberMonths)*
(numberMonths*((1+finderGuess)^(numberMonths-1)))))/
((((1+finderGuess)^numberMonths)-1)^2))))``````

I hope you are the only one who has to deal with this code. It may help to remember that the compiler can only do one thing at a time, unless you have a multi-core machine and an OS that is multi-core aware, which is very unlikely. So, for most of us there is little between one long calculation and several shorter ones, from the compiler's viewpoint. But there is a big difference in terms of readability.

Note the lack of a mathematical symbol between two lines of code as pointed out below. Also, all of your calculations are done as integers. You may or may not want floats instead.

``````## a calculation common to several other calcs
## increase the guess by one and raise it to the power of the number of months
interim divisor = (1+finderGuess)^numberMonths

## this is the do-hickey which is calculated by
## subtractng one from the thing-ma-bob and raising it to
## the power of 2
last_divisor = interim_divisor - 1
last_divisor = last_divisor^2

"""  note that there is no mathematical symbol between the first and
second lines in this block of code
(((((1+finderGuess)^numberMonths)-1)
(finderguess*(numberMonths*((1+finderGuess)^(numberMonths-1)))+
(1+finderGuess)^((finderGuess*(1+finderGuess)^numberMonths)*
(numberMonths*((1+finderGuess)^(numberMonths-1)))))
"""

## so the code becomes something like this, making sure that the number are floats, or are converted in the calculations.
finderGuess = finderGuess - descriptive_name_for_numerator /
descriptive_name_for_first_divisor /
descriptive_name_for_second_divisor /
descriptive_name_for_third_divisor /
last_divisor``````
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.