Search code examples
python-3.xobjectglobal-variables

Unable to access parent class' global variable with Child class' object


I want to update the counter of available cars whenever someone rents the car. When I try to access this variable through child class, it shows an error as "UnboundLocalError: local variable 'available_cars' referenced before assignment"

PS: Still working on it, that's why I haven't completed all the method codes.

Parent Class

available_cars = 1000

class Car_rental():

def __init__(self):
    pass

def display_available_cars(self):
    print("Total avaialable cars for renting is:", available_cars)

def rent_hourly(self, cars_rented):
    print("Our hourly rate is $100/hr.")

    if cars_rented > available_cars:
        print("Sorry! We currently do not have the number of cars requested. You can have {} cars for now if you want.".format(
            available_cars))
    elif cars_rented < available_cars:
        print("Thank you for renting {} cars from Swift car renting portal. Enjoy you ride.".format(
            cars_rented))

    elif cars_rented < 0:
        print ("Please provide a valid number of cars.")

def rent_weekly(self):
    pass

def rent_monthly(self):
    pass

def bill(self):
    pass

def update_invetory(self, cars_rented):
    available_cars = available_cars - cars_rented

Child Class

from carRental import *

class Customer(Car_rental): def init(self): Car_rental.init(self)

def rent_cars(self):

    mode = int(input(
        "Please select the mode of renting the car:\n1. Hourly\n2. Weekly\n3. Monthly\n"))
    if mode == 1 or mode == 'hourly' or mode == 'Hourly':
        cars_rented = int(input("How many cars do you wish to rent?"))
        self.rent_hourly(cars_rented)
        self.update_invetory(cars_rented)

    elif mode == 2 or mode == 'weekly' or mode == 'Weekly':
        self.rent_weekly()
    elif mode == 3 or mode == 'monthly' or mode == 'Monthly':
        self.rent_monthly()
    else:
        print("Please provide appropriate input.")

def return_cars(self):
    pass

Solution

  • So if I follow your question correctly, you seem to have objectives with your code.

    1. You want to define a Car_Rental class with a class-level variable available_cars which is initially set to 1000, and then as customers rent vehicles decrement the number of available cars.

    2. You also want a second Customer class which inherits the Car_Rental class which implements the billing functionality.

    3. While I am unsure of this, it seems that you would also like each of these class definitions to reside in their own separate python script file.

    This is how I would address these issues.

    # If desired could be placed in separate file Car_Rental.py
    class Car_Rental():
        available_cars = 1000
    
        def display_available_cars(self):
            print("Total avaialable cars for renting is:", Car_Rental.available_cars)
    
        def isOkayToRent(self, nmbr):
            return nmbr <= Car_Rental.available_cars
        
        def rent_hourly(self, cars_rented):
            print("Our hourly rate is $100/hr.")
    
            if cars_rented < 0:
                print ("Please provide a valid number of cars.")
                
            else:
                if self.isOkayToRent(cars_rented):
                    print("Thank you for renting {} cars from Swift car renting portal. Enjoy you ride.".format(
                    cars_rented))
                else:
                    print("Sorry! We currently do not have the number of cars requested. You can have {} cars for now if you want.".format(
                    Car_Rental.available_cars))
                    
        def rent_weekly(self):
            pass
    
        def rent_monthly(self):
            pass
    
        def bill(self):
            pass
    
        def update_inventory(self, nmbr):                       
            assert nmbr > 0
            Car_Rental.available_cars -= nmbr
            
        @property
        def cars(self):
            return Car_Rental.available_cars
    
    # Can be placed in  second file. 
    
    #Note include this next line if classes are stored in separate files 
    #from Car_rental import Car_Rental 
    
    
    class Customer(Car_Rental): 
        def __init__(self):
            Car_Rental.__init__(self)
    
        def rent_cars(self):
    
            mode = int(input(
                "Please select the mode of renting the car:\n1. Hourly\n2. Weekly\n3. Monthly\n"))
            if mode == 1:
                cars_rented = int(input("How many cars do you wish to rent?"))
                self.rent_hourly(cars_rented)
                self.update_inventory(cars_rented)
    
            elif mode == 2:
                self.rent_weekly()
            elif mode == 3:
                self.rent_monthly()
            else:
                print("Please provide appropriate input.")
    
        def return_cars(self):
            pass  
    

    To use:

    c1 = Customer()
    c1.cars  
    

    1000

    c1.rent_cars()  
    Please select the mode of renting the car:
    1. Hourly
    2. Weekly
    3. Monthly
    How many cars do you wish to rent? 2
    Our hourly rate is $100/hr.
    Thank you for renting 2 cars from Swift car renting portal. Enjoy you ride.  
    

    To illustrate proper inventory reduction: c1.cars yields 998