1

When I construct a __init__() in a Car class, say, I want to check that variables make and current_gas to be string and float or integer (not negative), respectively.

Then how do I raise an appropriate error for each variable?

I tried

class Car:
    def __init__(self,make,current_gas):
        if type(make) != str:
            raise TypeError("Make should be a string")
        if not type(current_gas) == float or type(current_gas) == int:
            raise TypeError("gas amount should be float or int")
        if current_gas <=0:
            raise ValueError("gas amount should not be negative")

However, this __init__() is not working properly. How do I fix it?

Jayden Rice
  • 301
  • 1
  • 14
  • 2
    What does "not working properly" mean? What is the exact behavior? – Chase May 04 '21 at 17:05
  • Does this answer your question? [How to determine a Python variable's type?](https://stackoverflow.com/questions/402504/how-to-determine-a-python-variables-type) – Woodford May 04 '21 at 17:05
  • 1
    Note that in `not ... or ...` , the `not` only applies to the first boolean, not the whole branch – Chase May 04 '21 at 17:06
  • When I try to create a car obejct with positive current_gas, I see the error message. – Jayden Rice May 04 '21 at 17:07
  • 2
    Please **show the error message**. Also note that you have used `current_gas_level`, which does not seem to be defined anywhere. – Chase May 04 '21 at 17:08
  • 1
    ```first_car=Car('Toyota','Corolla',20)``` gives ```gas amount should be float or int``` – Jayden Rice May 04 '21 at 17:10

1 Answers1

4

Looks like your boolean logic on the second if statement is wrong (not needs to be around both checks), however, you can use isinstance to simplify checking multiple types.

You also used current_gas_level instead of current_gas. Try something like this:

class Car:
    def __init__(self, make, current_gas):
        if not isinstance(make, str):
            raise TypeError("Make should be a string")
        if not isinstance(current_gas, (int, float)):
            raise TypeError("gas amount should be float or int")
        if current_gas <= 0:
            raise ValueError("gas amount should not be negative")

        self.make = make
        self.current_gas = current_gas

To make the definition a little easier to follow, I might also suggest using a dataclass and a __post_init__ to do the validation.

from dataclasses import dataclass
from typing import Union


@dataclass
class Car:
    make: str
    current_gas: Union[int, float]

    def __post_init__(self):
        if not isinstance(self.make, str):
            raise TypeError("Make should be a string")
        if not isinstance(self.current_gas, (int, float)):
            raise TypeError("gas amount should be float or int")
        if self.current_gas <= 0:
            raise ValueError("gas amount should not be negative")
flakes
  • 21,558
  • 8
  • 41
  • 88