#๐Ÿ”’ how to clean up

174 messages ยท Page 1 of 1 (latest)

steady thorn
#

could someone help me clean this thing up?

proud locustBOT
#

@steady thorn

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

steady thorn
#
import math

def sqrt_approx(number, guess = 1):
    if number < 0:
        return False
    elif number in [0,1]:
        return number
    else:
        while not math.isclose(pow(guess,2), number):
            guess = (guess + number/guess)/2
        return guess

try:
   number = int(input('Enter a valid number: '))
   print(float('{:,.3f}'.format(sqrt_approx(number))))
except ValueError:
   print('Invalid number')
#

in the user input section if the user inputs a number less than 0 then how do i put them at "invalid number"

#

I could do this:

import math

def sqrt_approx(number, guess = 1):
    if number < 0:
        return "Invalid Number"
    elif number in [0,1]:
        return number
    else:
        while not math.isclose(pow(guess,2), number):
            guess = (guess + number/guess)/2
        return guess

try:
   number = int(input('Enter a valid number: '))
   print(float('{:,.3f}'.format(sqrt_approx(number))))
except ValueError:
   print('Invalid number')
neon coral
#

put only the code you really need inside the try

steady thorn
#

But idk if this is readable lol because return "Invalid Number" could've been anything

dense ocean
#
  print(float('{:,.3f}'.format(sqrt_approx(number))))
```you can just
```py
  print(f'{sqrt_approx(number):.3f}'
steady thorn
#

idk what you mean

#

I followed both of what you said

#
import math

def sqrt_approx(number, guess = 1):
    if number < 0:
        return "Invalid Number"
    elif number in [0,1]:
        return number
    else:
        while not math.isclose(pow(guess,2), number):
            guess = (guess + number/guess)/2
        return guess

try:
   number = int(input('Enter a valid number: '))
except ValueError:
   print('Invalid number')

print(f'{sqrt_approx(number):.3f}')

#

This doesn't work

flint grove
# dense ocean add an if check

you'd then have to raise a ValueError to bring execution to the same error message - what i'd do is use a flag to catch these different ways to make an invalid number and then show the message later

steady thorn
#

So how am i cleaning this up lol

#

๐Ÿ˜ญ

#

I know this fix

flint grove
#

a flag is just a fancy word for a boolean, so in the except clause you should just set failed = True

(and of course initialise it to failed = False at the start)

steady thorn
#
import math

def sqrt_approx(number, guess = 1):
    if number < 0:
        return ""
    elif number in [0,1]:
        return number
    else:
        while not math.isclose(pow(guess,2), number):
            guess = (guess + number/guess)/2
        return guess

try:
   number = int(input('Enter a valid number: '))
   print(f'{sqrt_approx(number):.3f}')
except ValueError:
   print('Invalid number')
steady thorn
#

is this okay for readability?

flint grove
#

it's quite terrible for readability

steady thorn
#

I intentionally make a value error lol

#

But why?

#

I intentionally make a value-error

#

So now i can have invalid for both cases without repeating

flint grove
#

your square root function can return a string, that's very abnormal...

#

it's a hack solution

steady thorn
#

that shouldn't be an issue?

#

my square root function could return anything i guess

flint grove
#

and it's not how python code is usually written; when functions should fail, they raise an error explicitly, they don't return a string and hope the caller knows to handle this random value

#
>>> math.sqrt(0)
0.0
>>> math.sqrt(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error```
#

you can do this in your code using the raise keyword:

def my_sqrt(n):
    if n < 0:
        raise ValueError("math domain error")
    ...
#

incidentally, this also plays nice with your current try-except construction

strange pond
steady thorn
#

I mean it feels repeated but:

#
import math
import sys

def sqrt_approx(number, guess = 1):
    if number < 0:
        return False
    elif number in [0,1]:
        return number
    else:
        while not math.isclose(pow(guess,2), number):
            guess = (guess + number/guess)/2
        return guess

try:
   number = int(input('Enter a valid number: '))
except ValueError:
   print('Invalid number')
   sys.exit(1)

if not sqrt_approx(number):
    print('Invalid number')
    sys.exit(1)
    
print(float('{:,.3f}'.format(sqrt_approx(number))))
strange pond
#

again, a sqrt approximation function should not be returning anything other than floats

#

raise is the proper thing to do here, put it into anothe try except to catch the error and then print invalid number

flint grove
steady thorn
steady thorn
#

a bool can still be int'ed

#

so it works for whatever purposes

flint grove
strange pond
#

python is very loosely typed, just about anything can be converted to anything else to a reasonable extent

steady thorn
#
import math
import sys

def sqrt_approx(number, guess = 1):
    if number < 0:
        return False
    elif number in [0,1]:
        return number
    else:
        while not math.isclose(pow(guess,2), number):
            guess = (guess + number/guess)/2
        return guess

failed = False
try:
   number = int(input('Enter a valid number: '))
except ValueError:
   failed = True
   print('Invalid number')
   
if not sqrt_approx(number):
    failed = True

if failed == True:
  sys.exit(1)

print(float('{:,.3f}'.format(sqrt_approx(number))))


#

In this case i could've just sys exited anyway

#

same thing

steady thorn
#

if number < 0, what do you want me to return?

#

U told me not to return a string nor a boolean

steady thorn
#

Oh like that

strange pond
#

raise will "raise" an Error that'll immediately stop the execution of the current function

#

and propogate through the enclosing functions until caught

#

so like you try/except ed the int(input()) try except your function

steady thorn
#
import math
import sys

def sqrt_approx(number, guess = 1):
    if number < 0:
        raise ValueError("Invalid Number")
    elif number in [0,1]:
        return number
    else:
        while not math.isclose(pow(guess,2), number):
            guess = (guess + number/guess)/2
        return guess


try:
   number = int(input('Enter a valid number: '))
except ValueError:
   print('Invalid number')

print(float('{:,.3f}'.format(sqrt_approx(number))))
sys.exit(1)

#

So like this?

#

Okay yeah this uses my idea of intentionally making a value error

#

but with better readability

#

well i don't use python so i didn't know you could make an error yourself

strange pond
#

you can in any decent language

#

you don't need to stick to the existing errors as well

#

you can make your own, subclass them from Exception

steady thorn
#

okay sure cool

steady thorn
#

try:
number = int(input('Enter a valid number: '))
except ValueError:
print('Invalid number')

print(float('{:,.3f}'.format(sqrt_approx(number))))
sys.exit(1)

proud locustBOT
#

Hey @steady thorn!

It looks like you're trying to paste code into this channel.

Discord has support for Markdown, which allows you to post code with full syntax highlighting. Please use these whenever you paste code, as this helps improve the legibility and makes it easier for us to help you.

To do this, use the following method:
```py
print('Hello, world!')
```

This will result in the following:

print('Hello, world!')```
You can **edit your original message** to correct your code block.
steady thorn
#

what does this thing not work?

#

number is not defined?

#

I thought if there's no problem with the try-except then that variable is defined for the rest of the program?

#

and it's not only in the try-except scope?

#

bro i'm going to lose my mind

#

Lol

violet pelican
#

Can you show the full error?

steady thorn
#
import math
import sys

def sqrt_approx(number, guess = 1):
    # If triggered then raise exception
    if number < 0:
        raise ValueError("Invalid Number")
    
    # If number is between 0 and 1
    elif number in [0,1]:
        return number
    else:
        # Check if number is close using default tolerance
        while not math.isclose(pow(guess,2), number):
            # Redefine guess to the new average
            guess = (guess + number/guess)/2
        # Return guess with correct tolerance
        return guess


try:
   number = int(input('Enter a valid number: '))
   # If this returns ValueError then exception is triggered otherwise it prints.
   print(float('{:,.3f}'.format(sqrt_approx(number))))
except ValueError:
   print('Invalid number')
   # Exit program
   sys.exit()
#

Readable?

#

No errors here btw

#

I think at least

violet pelican
#

You could shorten the first elif slightly... Your if statement checks if it's lower than 0... so your first elif can just check if it's lower than 2, since you already checked for lower than 0.

if number < 0:
  # error
elif number < 2:
  # return number
else:
  # do things
steady thorn
#

it says i can't use any "math operator"

#

dk what that means but i guess i'm not allowed math.isclose right?

#

even though that's not relevant to this algorithm

#

how to implement math.isclose then

#
    else:
        tolerance = 10**9
        while abs(pow(guess,2) - number) < tolerance:
            # Redefine guess to the new average
            guess = (guess + number/guess)/2
        # Return guess with correct tolerance
        return guess```
#

shouldn't work ig

violet pelican
#

Is this homework?

steady thorn
#

oh i typo'd

steady thorn
#

i think all i had to do was tolerance = pow(10, -9)

#

i wrote 10**9

steady thorn
# violet pelican Is this homework?
    else:
        tolerance = pow(10,-9)
        while abs(pow(guess,2) - number) > tolerance:
            # Redefine guess to the new average
            guess = (guess + number/guess)/2
        # Return guess with correct tolerance
        return guess
#

any pythonic fix u want to suggest?

#

i think i'm done with the logic and input testing and everything

violet pelican
#

Do you know finally and else with try blocks?

steady thorn
#

no

violet pelican
steady thorn
#

is my code so far not okay?

#
import sys

# Square root algorithm
def sqrt_approx(number, guess = 1):
    # If triggered then raise exception
    if number < 0:
        raise ValueError("Invalid Number")
    
    # If number is between 0 and 1
    elif number < 2:
        return number
    # Positive numbers
    else:
        tolerance = pow(10,-9)
        while abs(pow(guess,2) - number) > tolerance:
            # Redefine guess to the new average
            guess = (guess + number/guess)/2
        # Return guess with correct tolerance
        return guess


try:
   number = int(input('Enter a valid number: '))
   # If this returns ValueError then exception is triggered otherwise it prints.
   print(float('{:,.3f}'.format(sqrt_approx(number))))
except ValueError:
   print('Invalid number')
   # Exit program
   sys.exit()```
#

okay i see what finally is

#

it just terminates after the try

violet pelican
#

So try is the code you're trying that could error, except is the error you're catching, else executes if there was no error, and finally executes even if there was an error.

steady thorn
#

oh

#

i see

#

i think i get what you're getting at

#
# Testing for valid input
try:
   # Ask user for input
   number = int(input('Enter a valid number: '))
except ValueError:
   print('Invalid number')
   # Exit program
   sys.exit()
finally:
    print(float('{:,.3f}'.format(sqrt_approx(number))))
#

like that?

blazing spear
#

If you want to do it without using errors, i think you can do it like this : ```python
import sys

def sqrt_approx(number: int, guess: float = 1) -> float | None:
if number < 0:
return None
elif number in (0, 1):
return number

while abs(pow(guess, 2) - number) > 1e-9:
    guess = (guess + number / guess) / 2
return guess

user_input = input('Enter a valid number: ')

if not user_input.isdigit():
print("Invalid number")
sys.exit()

number = int(user_input)
approx = sqrt_approx(number)

if not approx:
print("Invalid number")
sys.exit()

print(f"{approx:,.3f}")

steady thorn
#

Mine works too right?

#
import sys

# Square root algorithm
def sqrt_approx(number, guess = 1):
    # If triggered then raise exception
    if number < 0:
        raise ValueError("Invalid Number")
    
    # If number is between 0 and 1
    elif number < 2:
        return number
    # Positive numbers
    else:
        tolerance = pow(10,-9)
        while abs(pow(guess,2) - number) > tolerance:
            # Redefine guess to the new average
            guess = (guess + number/guess)/2
        # Return guess with correct tolerance
        return guess


# Testing for valid input
try:
   # Ask user for input
   number = int(input('Enter a valid number: '))
except ValueError:
   print('Invalid number')
   # Exit program
   sys.exit()
finally:
    # Executes the program if input isn't string
    print(float('{:,.3f}'.format(sqrt_approx(number))))```
violet pelican
#

So if there is an error when you try to assign input to a variable, when the finally clause executes, the variable won't be defined.

steady thorn
#

but doesn't mine work also?

#

I just tried and it does

violet pelican
#

Try it with invalid input

steady thorn
#

i did

#

what is invalid input btw

#

strings?

#

or character?

violet pelican
#

yeah

steady thorn
#

wtf?!

#

Idk if it's my pc but it was working before

#

lmao

#

Okay now it doesn't work at all

#

for negative or strings

violet pelican
#

So the code you want to write should look like this

try:
  # code that could error
except TheError:
  # code when error
else:
  # code when no error
finally:
  # you don't NEED a finally, but code no matter what happens.
steady thorn
#

is the same function lol

violet pelican
steady thorn
#

Does this except thing exit?

#

I don't think it does

#

huh?

#

that's weird

violet pelican
steady thorn
#

i came back to this solution:

#
import sys

# Square root algorithm
def sqrt_approx(number, guess = 1):
    # If triggered then raise exception
    if number < 0:
        raise ValueError("Invalid Number")
    
    # If number is between 0 and 1
    elif number < 2:
        return number
    # Positive numbers
    else:
        tolerance = pow(10,-9)
        while abs(pow(guess,2) - number) > tolerance:
            # Redefine guess to the new average
            guess = (guess + number/guess)/2
        # Return guess with correct tolerance
        return guess


try:
   number = int(input('Enter a valid number: '))
   # If this returns ValueError then exception is triggered otherwise it prints.
   print(float('{:,.3f}'.format(sqrt_approx(number))))
except ValueError:
   print('Invalid number')
   # Exit program
   sys.exit()```
#

this thing works

#

$ python Untitled.py
Enter a valid number: -1
Invalid number

#

Okay wait this is undefined behavior

violet pelican
#

Oh, it's not giving you a NameError because you're trying to print it in the try block. But you're throwing a ValueError before the NameError happens.

steady thorn
#

No i think i found the issue

#

sqrt_approx(number) for negative numbers returns a valueerror

#

and then i try to convert to float lol

#

which is an error ig

violet pelican
#

Your if statement doesn't allow for negative numbers, which throws the error.

#

but, it is a valid int

#

so it'll pass the first check before it runs the function

steady thorn
#
import sys

# Square root algorithm
def sqrt_approx(number, guess = 1):
    # If triggered then raise exception
    if number < 0:
        # Flag variable 
        return -1
    
    # If number is between 0 and 1
    elif number < 2:
        return number
    # Positive numbers
    else:
        tolerance = pow(10,-9)
        while abs(pow(guess,2) - number) > tolerance:
            # Redefine guess to the new average
            guess = (guess + number/guess)/2
        # Return guess with correct tolerance
        return guess


try:
   number = int(input('Enter a valid number: '))
   # If this returns ValueError then exception is triggered otherwise it prints.
except ValueError:
   print('Invalid number')
   # Exit program
   sys.exit(1)

value = sqrt_approx(number)
if value >= 0:
    print(float('{:,.3f}'.format(sqrt_approx(number))))

# Flag for negative values in function
print("Square root is defined for non-negative integers")
sys.exit(1)
#

Hopefully this is readable lol and i made sure it works

#

(if you have a better way with try, else, finally then please do share (i want to have a look at it), but for now i'm tired of this so i'm going for a walk)

violet pelican
#
    else:
        tolerance = pow(10,-9)
        while abs(pow(guess,2) - number) > tolerance:
            # Redefine guess to the new average
            guess = (guess + number/guess)/2
        # Return guess with correct tolerance
        return guess

I don't think you need a while loop here.

    else:
        tolerance = pow(10,-9)
        if abs(pow(guess,2) - number) > tolerance:
            return (guess + number/guess)/2
steady thorn
#

i need it to keep running

violet pelican
#

Oh, nevermind. I read the code wrong. You're good.

proud locustBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.