1
\$\begingroup\$

I recently appeared for interview for code-pairing round and I was asked following question: Electricity Billing System for home. The corresponding power usage of home appliances (Fan, AC, Fridge, Light) was given:

Appliance | Per hour unit consumption
Fan 4
Light 2
AC 10
Fridge 8

The slab chart was given as:

Slab 1 - 0 to 1000 unit: INR Rs 20 per unit
Slab 2 - 1001 to 3000 unit: INR Rs 30 per unit
Slab 1 - 3001 to 6000 unit: INR Rs 40 per unit
Slab 1 - 6001 and above unit: INR Rs 50 per unit

Input:

Appliance | CountOfAppliance | TotalUasgePerDayInHours
Fan 2 4
Light 1 4
AC 1 12
Fridge 1 5

Output:

200000 INR
Units Per Day : (2*4*4 + 1*4*2 +1*12*10 + 1*5*8) = 200
unitsPerMonth = 6000
totalBill = 1000*20 + 2000*30 + 3000*30 + 3000*50 = 200000

I had modeled the code using "Factory Design Pattern" for appliance. But my Code for Price Slab was something the interviewer was not happy with the hardcoding. Though I modified it by using Constants file for slabs but the interviewer was still expecting something better. Kindly let me know how it can be improved.

IElectricComponent

public interface IElectricComponent {
    public enum Unit{
           FAN(4), LIGHT(2), AC(10) , FRIDGE(8);
           private int value;
           private Unit(int value) {
                this.value = value;
           }
           public int getValue(){
            return value;
           }
       }
    public int claculateUnitForSingleDay();
}

Fan

public class Fan implements IElectricComponent{

    private int noOfComponents;
    private int perDayUsage;
    public Fan(int noOfComponents, int perDayUsage){
        this.noOfComponents=noOfComponents;
        this.perDayUsage=perDayUsage;               
    }

    public int claculateUnitForSingleDay(){
        return noOfComponents*perDayUsage*Unit.FAN.getValue();      
    }   
}

The same way for Fridge, Light and AC

Factory: ApplianceFactory

public class ApplianceFactory {

        public static IElectricComponent getInstance(String appliance, int countOfAppliance ,int perDayUsage ){

            switch(appliance){

                case ApplianceConstants.FAN:
                    return new Fan(countOfAppliance,perDayUsage);

                case ApplianceConstants.LIGHT:
                    return new Light(countOfAppliance,perDayUsage);

                case ApplianceConstants.AC:
                    return new AC(countOfAppliance,perDayUsage);

                case ApplianceConstants.FRIDGE:
                    return new Fridge(countOfAppliance,perDayUsage) ;

                default :
                    return new IElectricComponent() {

                        @Override
                        public int claculateUnitForSingleDay() {
                            // TODO Auto-generated method stub
                            return countOfAppliance*perDayUsage;
                        }
                    };
            }

        }
    }

Constants:

public interface ApplianceConstants {

    public String FAN = "Fan";
    public String LIGHT = "Light";
    public String AC = "AC";
    public String FRIDGE = "Fridge";

    public int Slab1 = 20;
    public int Slab2 = 30;
    public int Slab3 = 40;
    public int Slab4 = 50;
}

PriceSlab:

public class PriceSlab {

    HashMap<String,Integer> slabs = new HashMap<>();

    public int calculateBill(int units){

        slabs.put("A", ApplianceConstants.Slab1);
        slabs.put("B", ApplianceConstants.Slab2);
        slabs.put("C", ApplianceConstants.Slab3);
        slabs.put("D", ApplianceConstants.Slab4);

        return calculateBillTotal(units);
    }

    private int calculateBillTotal(int units) {

        int total = 0;
        if(units <= 1000){
            total = units*slabs.get("A") ;
        }
        else if (units <= 3000){
            total = 1000*slabs.get("A") + (units-1000)*slabs.get("B");
        }
        else if (units <= 6000){
            total = 1000*slabs.get("A") + 2000*slabs.get("B") +(units-3000)*slabs.get("C");
        }
        else{
            total = 1000*slabs.get("A") + 2000*slabs.get("B") + 3000*slabs.get("D")
                +(units-6000)*slabs.get("C");
        }
        return total;
    }
}

Main class:

public class BillGenerator {

    public static void main(String[] args) {

        Scanner scn = new Scanner(System.in);
        ApplianceFactory factory = new ApplianceFactory();
        int inputOfAppliance = scn.nextInt();
        String appliance="";
        int countOfAppliance;
        int perDayUsage;
        int unitsPerDay=0;
        for(int t=0 ; t<inputOfAppliance ;t ++){
            appliance = scn.next();
            countOfAppliance = scn.nextInt();
            perDayUsage = scn.nextInt();
            IElectricComponent electricComponent = factory.getInstance(appliance, countOfAppliance, perDayUsage);
            unitsPerDay += electricComponent.claculateUnitForSingleDay();
        }
        System.out.println("unitsPerDay = "+unitsPerDay);
        int unitsPerMonth = unitsPerDay * 30;
        System.out.println("unitsPerMonth = "+unitsPerMonth);

        PriceSlab slab= new PriceSlab();
        int totalBill = slab.calculateBill(unitsPerMonth);
        System.out.println("totalBill = "+totalBill);
    }

}

Please review my code and let me know if anything could be improved.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.