Instead of isinstance, use of try and except in Python 3.7 - python

I wrote a code to catch my error message using try and except (I want to write it without using isinstance) and I am getting the error message when the input is not an integer. The problem is, the program is giving me error message even if the input is valid integer. Please give me some suggestions to make it run. My code is given below:
I tried using exception clause but that did not work.
class Hotel:
def __init__(self,room,catagory):
if room != int:
raise TypeError ()
self.room = room
self.catagory = catagory
self.catagories = {"A":"Elite","B":"Economy","C":"Regular"}
self.rooms = ["0","1","2","3","4","5"]
def getRoom(self):
return self.room
def getCatagory(self):
return self.catagory
return self.catagories.get(self.catagory)
def __str__(self):
return "%s and %s"%(self.rooms[self.room],self.catagories.get(self.catagory))
try:
room1 = Hotel(a,"A")
room2 = Hotel(1,"A")
print(room1.getRoom())
except:
print("there's an error")
I am expecting:
there's an error
1 and Elite
A

You are checking if room != int . It will give you error always.
You have to check type(room)!= int .
I have corrected the code below
class Hotel:
def __init__(self,room,catagory):
if type(room) != int:
raise TypeError ()
self.room = room
self.catagory = catagory
self.catagories = {"A":"Elite","B":"Economy","C":"Regular"}
self.rooms = ["0","1","2","3","4","5"]

Related

Pass a keyword variable to a function as an argument

I'm doing a project that is requiring a lot of input validation. I currently have a function defined as follows:
def get_valid_float(inputMessage,errorMessage):
while True:
variableInput = input(inputMessage)
try:
variableInput = float(variableInput)
return variableInput
except ValueError:
print(errorMessage)
This function allows me to choose a custom message to prompt the user. It will then validate that the user input is indeed a float, and will print a custom error message in the event that it is not. It will loop until the user gives a valid input.
However, I would rather not create a function to validate each and every data type. It seems like it would be best to combine these into one get_valid_input() function, and pass a third argument allowing me to choose what data type I am attempting to verify. For example, get_valid_input(complex,inputMessage,errorMessage).
I am obviously unable to pass a keyword as an argument. This makes me think the only way to do this would to be to do something like this:
def get_valid_float(dataType,inputMessage,errorMessage):
if dataType == "float"
while True:
variableInput = input(inputMessage)
try:
variableInput = float(variableInput)
return variableInput
except ValueError:
print(errorMessage)
elif dataType == "integer"
while True:
variableInput = input(inputMessage)
try:
variableInput = int(variableInput)
return variableInput
except ValueError:
print(errorMessage)
And so on, with an elif for every data type. Surely there is an easier way to do this, that somehow allows me to execute the line variableInput = {dataType}(variableInput) to confirm that they input a value of data type "dataType". Any ideas?
Just pass as an argument the actual data type, rather than the name of the data type. E.g:
def get_valid_input(dataType, inputMessage, errorMessage):
while True:
value = input(inputMessage)
try:
value = dataType(value)
break
except ValueError:
print(errorMessage)
You would call it like this:
floatvalue = get_valid_input(float, "enter a float value: ", "that is an invalid float")
intvalue = get_valid_input(int, "enter an integer value: ", "that is an invalid integer")
I am obviously unable to pass a keyword as an argument.
Not sure why you're saying that, but you can! :)
Also no need for error message, just catch all Exceptions (Not recommended but since you are just printing out the error it seems fine here)
The message strings aren't really needed, try using the name of the dataType and the exception's message like this:
def get_valid_data(dataType):
while True:
variableInput = input(f"Put in data of type {dataType.__name__}: ")
try:
variableInput = dataType(variableInput)
return variableInput
except Exception as e:
print(e)
get_valid_data(int)
>>> Put in data of type int: "hi"
>>> invalid literal for int() with base 10: '"hi"'

How show val er

Need some help with the if statements and Vaidation errors.
Right now I have this function:
def validate(self, validated_data):
if self.partial:
validated_data = self.fill_data(self.instance, validated_data)
if not validated_data['brand'].sunny_account.first():
raise ValidationError('This brand not Sunny')
validated_data['calculate'] = Account.NEW
return validated_data
Need to add another if statement:
if not validated_data['brand'].moon_account.first():
raise ValidationError('This brand not Moon')
If I add another if not statement in this function it's not going to the second one if not and raising the first Validation error.
I would like that this function checking all if's and raising Validation error for the each case.
From what I understand, you want both the Moon and Sunny errors to be raised. However, this cannot happen: if the first is raised, then the second will never be reached. If the first is not raised, only then can the second be raised. But both can't be raised at the same time.
One solution, do it in a loop:
def validate(self, validated_data):
if self.partial:
validated_data = self.fill_data(self.instance, validated_data)
validations = [
(
validated_data['brand'].sunny_account.first(),
'This brand does not have Sunny enabled'
),
(
validated_data['brand'].moon_account.first(),
'This brand does not have Moon enabled'
),
]
# Validate
err_msg = ""
for cond, msg in validations:
if not cond:
# Has error, add the error message
err_msg = err_msg + msg
if err_msg:
# Error message is not empty --> there is an error
raise ValidationError(err_msg)
validated_data['calculate'] = Account.NEW
return validated_data
It is unusual to want to do this, and handling your exceptions elsewhere might be tricky, but you could raise an Exception of Exceptions something like this:
def my_test(thing):
errors = []
if thing != 1:
errors.append(ValidationError('thing 1'))
if thing != 2:
errors.append(ValidationError('thing 2'))
if errors:
Raise(ValidationError(errors))
You can't raise two exceptions at once, but you can define your own Exception subclass that incorporates arbitrary data. For example, you could store a list of multiple error messages:
class ValidationError(Exception):
def __init__(self):
super().__init__()
self._why: list[str] = []
def __bool__(self) -> bool:
return bool(self._why)
def __str__(self) -> str:
return "\n".join(self._why)
def add(self, why: str) -> None:
self._why.append(why)
and then accumulate multiple messages before deciding to raise:
err = ValidationError()
if not validated_data['brand'].sunny_account.first():
err.add('This brand does not have Sunny enabled')
if not validated_data['brand'].moon_account.first():
err.add('This brand does not have Moon enabled')
if err:
raise err

User defined exception error using try and except

I am trying to create a user defined exception in the below quadratic roots program (using classes).
The intention is to throw and error back if the input list length is not 3 (need 3 inputs for the 3 coefficients). Additionally, I would want the code to stop executing if there is an input error.
However, this code isn't working, it doesn't throw an exception and the code continues to execute.
Would greatly appreciate if you could guide me.
class quadRoots():
def __init__(self,coeff):
self.A = coeff[0]/coeff[0]
self.B = coeff[1]/coeff[0]
self.C = coeff[2]/coeff[0]
self.Z = 0
self.R_1 = 0
self.R_2 = 0
self.coeff = len(coeff)
try:
self.coeff == 3
except:
print("Input size is not valid")
def roots(self):
import cmath
self.Z = cmath.sqrt((self.B**2)/4 - (self.C))
self.R_1 = ((-(self.B)/2) + self.Z)
self.R_2 = ((-(self.B)/2) - self.Z)
return [self.R_1,self.R_2]
def mult(self):
return quadRoots.roots(self)[0] * quadRoots.roots(self)[1]
def sumRoots(self):
return [complex(-(self.B))]
def prodRoots(self):
return [complex(self.C)]
quadroots([1,-9,14,15]).roots()
try:
self.coeff == 3
except:
print("Input size is not valid")
A Try-Except Chain doesn't work like this. It works when there is an error. But here, there is no error. I suggest you use assert self.coeff == 3, "Input size is not valid". instead, it raises an error, and exits the program, if self.coeff is not equal to 3.
so then the whole try except chain can be replaced by one line. assert self.coeff == 3, "Input size is not valid"

Design my own Error in Python

I want to design an error in python.
Here is my code
class TwitchException(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return "The input ", self.value ," is not a valid reaction."
valid_reactions = ["Poggers", "4Head","SMOrc", "TheIlluminati"]
def react(reaction):
"""
>>> react("Poggers")
Poggers
>>> react("Hello")
Traceback (most recent call last):
...
TwitchException: The input Hello is not a valid reaction.
>>> react("SMOrc")
SMOrc
"""
try:
if reaction in valid_reactions:
print(reaction)
except TwitchException:
raise TwitchException(reaction)
Help!!! I am not sure how to fulfill the second doctest.
You want to raise the exception in the else clause of the if statement; there is no need for a try statement here.
def react(reaction):
if reaction in valid_reactions:
print(reaction)
else:
raise TwitchException(reaction)
This is, however, typically written as
def react(reaction):
if reaction not in valid_reactions:
raise TwitchException(reaction)
print(reaction)
Method __str__ must return a string. Yours returns a tuple:
def __str__(self):
return "The input ", self.value ," is not a valid reaction."
It should be:
def __str__(self):
return "The input {} is not a valid reaction.".format(self.value)

Storing SMS messages

I realize this is a problem for which multiple solutions have been suggested on this forum, but I wrote a code and got an error that I don't understand, so that's mostly what I'm asking about here.
Here is my code:
from datetime import datetime
class SMSstore:
store = []
read = []
unread =[]
def addNewArrival(number,time,text):
SMSstore.store.append(("From: {}, Recieved: {}, Msg: {}".format(number,time,text)))
def messageCount():
return print("Number of Messages in Inbox: {}".format(len(SMSstore.store)))
def viewall():
print(SMSstore.store)
def getUnreadIndexes():
for message in SMSstore.store:
if message[0] == False:
unread.append(self.__inbox.index(message))
return unread
def getMessage(i):
SMSstore.read.append(len(SMSstore.store))
print(SMSstore.store[i])
def delete(i):
try:
del SMSstore.store[i]
except IndexError:
print("Index is out of range. Cannot delete")
def clear():
del SMSstore.store
time = datetime.now().strftime('%H:%M:%S')
myInbox = SMSstore()
myInbox.addNewArrival("1234567890",time,"What is your name?")
myInbox.addNewArrival("0987654321",time,"What is your quest?")
myInbox.viewall()
myInbox.msgcount()
myInbox.delete(i)
myInbox.clear()
The error I get is:
line 37, in <module>
TypeError: addNewArrival() takes exactly 3 arguments (4 given)
You need to put self as the first arg in all the methods in a class.
Example:
def addNewArrival(self, number, time, text):
def messageCount(self):
def viewall(self):
More info here

Categories