#๐ how to clean up
174 messages ยท Page 1 of 1 (latest)
@steady thorn
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.
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')
put only the code you really need inside the try
But idk if this is readable lol because return "Invalid Number" could've been anything
print(float('{:,.3f}'.format(sqrt_approx(number))))
```you can just
```py
print(f'{sqrt_approx(number):.3f}'
add an if check
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
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
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)
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')
Yeah but i found this way
is this okay for readability?
it's quite terrible for readability
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
your square root function can return a string, that's very abnormal...
it's a hack solution
as stated, it's an issue for readability
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
just because it could, doesn't mean it should
take for example you're in charge of writing the math library in the stdlib, anyone not familiar with python would assume the sqrt function returns a float, see how this is problematic, if you return strings?
Okay, i have an alternate proposal
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))))
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
you can do this without the repetition and it would be a good solution too; use a flag
well can you show me what or where exactly am i using the flag
??? But it's returning an int regardless
a bool can still be int'ed
so it works for whatever purposes
failed = False
try:
n = ...
except:
failed = True
else: # put it in the try-else clause because then n will be assigned
if crappy_number(n):
failed = True
if failed:
fail message
else:
success message```
oh okay i see
again, could != should
python is very loosely typed, just about anything can be converted to anything else to a reasonable extent
wait lol idk where you want me to put this
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
again idk what you want me to return then lol
if number < 0, what do you want me to return?
U told me not to return a string nor a boolean
^^^
as @ Inuk said: #1218547823855927387 message
Oh like that
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
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
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
okay sure cool
wait what
try:
number = int(input('Enter a valid number: '))
except ValueError:
print('Invalid number')
print(float('{:,.3f}'.format(sqrt_approx(number))))
sys.exit(1)
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.
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
?????
Can you show the full error?
Is this code good enough?
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
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
okay one more thing
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
Is this homework?
oh i typo'd
yes
i think all i had to do was tolerance = pow(10, -9)
i wrote 10**9
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
Do you know finally and else with try blocks?
no
yeah but where exactly are u suggesting for me to implement this
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
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.
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?
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}")
Okay nice
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))))```
You would put your finally code in your else clause. Because finally will run no matter what.
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.

but doesn't mine work also?
I just tried and it does
Try it with invalid input
yeah
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
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.
yeah but the code that could error and not error
is the same function lol
What do you mean?
Using a string gave you a ValueError?
string or negative number
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
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.
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
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
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)
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
how? if u remove the while loop it'd run exactly once
i need it to keep running
Oh, nevermind. I read the code wrong. You're good.
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.