9
\$\begingroup\$

Very simple square root calculator. I am sure it's terrible and can be made much better.

I feel it's way too many lines.

import random

## ask user for a number to find sq root for
num1 = input("Please enter number for which we'll find sq root:\n")

## generate a random number and test it
randomNum1 = random.randint(1,9)
print("Random number is " + str(randomNum1))

ranMul1 = 0

while True:
  if float(ranMul1) == float(num1):
    print("square root of " + str(num1) + " is " + str(randomNum1))
    break
  else:
    randomNum1 = round((float(randomNum1) + (float(num1)/float(randomNum1))) / 2, 4)
    ranMul1 = round(randomNum1 * randomNum1,4)
    print("Trying number " + str(randomNum1))
    continue

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Search for "Newton's method for square roots". \$\endgroup\$
    – waltinator
    Jul 18, 2020 at 7:54

2 Answers 2

8
\$\begingroup\$

Welcome to the community :). A few pointers:

  1. The code does not follow PEP-8 style guide. You should follow the snake_case naming convention for variables.
  2. Split code into separate functions.
  3. Instead of the code running as is, the execution condition should be placed inside an if __name__ block.
  4. If you're on python 3.6+, make use of f-strings over concatenating separate variables and casting them to strings over and over.
  5. Cast the input from user as float as soon as it is read.
  6. I don't think you need to round the random variable calculated to 4 digits. For print purpose, you can use the precision specifier.
  7. Again, if using python 3.6+, you can also provide type hinting.

The above mentioned points, and a few more changes, your code would be:

from math import isclose
from random import randint


def calculate_sq_root(num: float) -> float:
    "generate a random number and manipulate it until we calculate square root of input number"
    random_num = randint(1, 9)
    print(f"Random number is {random_num}.")
    while not isclose(num, random_num * random_num):
        random_num = (random_num ** 2 + num) / (random_num * 2)
        print(f"Trying number {random_num:.4f}")
    return random_num


def get_input() -> float:
    "ask user for a number to find sq root for"
    return float(input("Please enter number for which we'll find sq root:\n"))


def main():
    user_num = get_input()
    sq_root = calculate_sq_root(user_num)
    print(f"Square root of {user_num} is {sq_root}.")


if __name__ == "__main__":
    main()
\$\endgroup\$
3
  • 3
    \$\begingroup\$ Your docstring for calculate_sq_root should use triple-quotes, not quotes. \$\endgroup\$
    – Reinderien
    Jul 17, 2020 at 2:10
  • 1
    \$\begingroup\$ Also, the cast to float is redundant here: float(num / random_num) - Python will do type promotion. \$\endgroup\$
    – Reinderien
    Jul 17, 2020 at 2:10
  • \$\begingroup\$ @Reinderien yes. those points are mentioned in pep 8. I edited the code in tio.run page itself, so not much formatting could be done. \$\endgroup\$
    – hjpotter92
    Jul 17, 2020 at 2:30
12
\$\begingroup\$

The great input from @hjpotter92 gets you 99% of the way there. The only additional comment I have is about this:

while num != random_num * random_num:

Exact comparison of floating-point numbers is problematic. You're going to want to pick some (very small) number, usually called epsilon, below which the error is insignificant and call that "close enough".

Read https://docs.python.org/3/library/math.html#math.isclose for more details.

\$\endgroup\$
1
  • \$\begingroup\$ updated this in my reply too. thanks \$\endgroup\$
    – hjpotter92
    Jul 17, 2020 at 2:34

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.