HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Calculating the daily profit of a clinic

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thecliniccalculatingprofitdaily

Problem

I need help with optimizing a piece of code I've written in C#, which is very sloppy right now. I needed to write code that tracks the amount of money a hospital has made at the end of the day, depending on the amount of patients.

Here are some conditions and details:

-
Code has to display the cost for the patient and the amount of money made at the end of the day:

-
When a radio image and a consultation is done in one time by the same patient, there is a 25% price reduction off the price of a radio image.

  • When a patient does a consultation, a blood check and an injection. That person gets 10$ after paying tax.



  • The injections can be either 30ml, 50ml or 60ml. The prices are proportionate to the quantity of product injected. (for example: Someone aged 20 that takes a 50ml shot has to pay 25$)



  • Taxes are 15%



```
int client;
int clientfinal = 0;
double injprix = 0;
double consprix = 0;
double imgradprix = 0;
double analyzeprix = 0;
double prixtot = 0;
double prixclient = 0;
double prixfinal = 0;

int injtaille = 0;
string cons, inj, imgrad, analyze;
Console.WriteLine("Combien a t-il de client aujourd'hui?");
client = (Convert.ToInt32(Console.ReadLine()));

if (client > 0)

do //un client
{
Console.WriteLine("Quel est l'age du patient?");
client = Convert.ToInt32(Console.ReadLine());
if (client = 12 || client = 19 || client 65)
{
client = 4;
}

Console.WriteLine("La personne a t-elle choisit une consultation?");
cons = Convert.ToString(Console.ReadLine()).ToLower();
Console.WriteLine("La personne a t-elle choisit une image radio?");

Solution

Break your code into methods if a code line in one method is more than 30 characters:

public UserPreference InitializeUserPrefence()
    {
        var userPreference = new UserPreference();

        Console.WriteLine("La personne a t-elle choisit une consultation?");
        userPreference.IsConsulation = Convert.ToString(Console.ReadLine()).ToLower() != "non";

        Console.WriteLine("La personne a t-elle choisit une image radio?");
        userPreference.IsImaging = Convert.ToString(Console.ReadLine()).ToLower() != "non";

        Console.WriteLine("La personne a t-elle choisit une analyze de sang?");
        userPreference.IsBloodAnalysis = Convert.ToString(Console.ReadLine()).ToLower() != "non";

        Console.WriteLine("La personne a t-elle choisit une injection?");
        userPreference.IsInjection = Convert.ToString(Console.ReadLine()).ToLower() == "oui";//DOUBLE CHECK THIS LOGIC

        if (userPreference.IsInjection)
        {
            Console.WriteLine("Quel est la taille de l'injection? (30 - 50 - 60) ");
            userPreference.InjectionSize = Convert.ToInt32(Console.ReadLine());
        }

        return userPreference;
    }


I have factored all user input into the UserPreference class and a method to handle it (need more refactoring in it but that is fine as of now).

Prefer enum over explicit checking with string

I have defined an age group enum and a method to calculate it:

public enum AgeGroup
    {
        Child = 1,
        Teen = 2,
        Adult = 3,
        Senior = 4 
    }

   private AgeGroup CalculateAgeGroup(int age)
    {
        if (age = 12 || age = 19 || age <= 65)
            return AgeGroup.Adult;

        return AgeGroup.Senior;
    }


SRP principle

Always try to separate out any calculations into a class. It will help you to maintain and change logic easily. I have defined a separate class for calculating the price, and it could be tested individually.

public class TeenInjectionPriceCalculator
    {
        public double Calculate(int injectionSize)
        {
            switch (injectionSize)
            {
                case 30:
                    return 13;
                    break;
                case 50:
                    return 650.0 / 30.0;
                case 60:
                    return (780.0 / 30.0);
                default:
                    return 0;
            }
        }
    }
 public class AdultInjectionPriceCalculator
    {
        public double Calculate(int injectionSize)
        {
            switch (injectionSize)
            {
                case 30:
                    return 13;
                case 50:
                    return (750.0 / 30.0);
                case 60:
                    return (900.0 / 30.0);
                default:
                    return 0;
            }
        }
    }

    public class AgedInjectionPriceCalculator
    {
        public double Calculate(int injectionSize)
        {
            switch (injectionSize)
            {
                case 30:
                    return 13;
                case 50:
                    return (600 / 30.0);
                case 60:
                    return (720 / 30.0);
                default:
                    return 0;
            }
        }
    }


In the same line, I have also created a fee factory to wrap the pricing logic for an individual age group:

```
public class Fee
{
public double Consultancy { get; set; }
public double Imaging { get; set; }

public double BloodAnalysis { get; set; }

public double Injection { get; set; }
}

public class FeesFactory
{
public Fee Initialize(AgeGroup ageGroup, int injectionSize)
{
var fee =new Fee();

switch (ageGroup)
{
case AgeGroup.Child:
fee.Consultancy = 25;
fee.Imaging = 55;
fee.BloodAnalysis = 28;
fee.Injection = 0;
return fee;

case AgeGroup.Teen:
fee.Consultancy = 32;
fee.Imaging = 65;
fee.BloodAnalysis = 32;
fee.Injection = new TeenInjectionPriceCalculator().Calculate(injectionSize);
return fee;

case AgeGroup.Adult:
fee.Consultancy = 40;
fee.Imaging = 70;
fee.BloodAnalysis = 40;
fee.Injection = new AdultInjectionPriceCalculator().Calculate(injectionSize);
return fee;

case AgeGroup.Senior:
fee.Consultancy = 30;
fee.Imaging = 60;
fee.BloodAnalysis = 35;
fee.Injection = new AgedInjectionPriceCalculator().Calculate(injectionSize);
return fee;

default:
throw new ArgumentExcep

Code Snippets

public UserPreference InitializeUserPrefence()
    {
        var userPreference = new UserPreference();

        Console.WriteLine("La personne a t-elle choisit une consultation?");
        userPreference.IsConsulation = Convert.ToString(Console.ReadLine()).ToLower() != "non";

        Console.WriteLine("La personne a t-elle choisit une image radio?");
        userPreference.IsImaging = Convert.ToString(Console.ReadLine()).ToLower() != "non";

        Console.WriteLine("La personne a t-elle choisit une analyze de sang?");
        userPreference.IsBloodAnalysis = Convert.ToString(Console.ReadLine()).ToLower() != "non";

        Console.WriteLine("La personne a t-elle choisit une injection?");
        userPreference.IsInjection = Convert.ToString(Console.ReadLine()).ToLower() == "oui";//DOUBLE CHECK THIS LOGIC

        if (userPreference.IsInjection)
        {
            Console.WriteLine("Quel est la taille de l'injection? (30 - 50 - 60) ");
            userPreference.InjectionSize = Convert.ToInt32(Console.ReadLine());
        }

        return userPreference;
    }
public enum AgeGroup
    {
        Child = 1,
        Teen = 2,
        Adult = 3,
        Senior = 4 
    }

   private AgeGroup CalculateAgeGroup(int age)
    {
        if (age < 12)
            return AgeGroup.Child;

        if (age >= 12 || age <= 18)
            return AgeGroup.Teen;

        if (age >= 19 || age <= 65)
            return AgeGroup.Adult;

        return AgeGroup.Senior;
    }
public class TeenInjectionPriceCalculator
    {
        public double Calculate(int injectionSize)
        {
            switch (injectionSize)
            {
                case 30:
                    return 13;
                    break;
                case 50:
                    return 650.0 / 30.0;
                case 60:
                    return (780.0 / 30.0);
                default:
                    return 0;
            }
        }
    }
 public class AdultInjectionPriceCalculator
    {
        public double Calculate(int injectionSize)
        {
            switch (injectionSize)
            {
                case 30:
                    return 13;
                case 50:
                    return (750.0 / 30.0);
                case 60:
                    return (900.0 / 30.0);
                default:
                    return 0;
            }
        }
    }

    public class AgedInjectionPriceCalculator
    {
        public double Calculate(int injectionSize)
        {
            switch (injectionSize)
            {
                case 30:
                    return 13;
                case 50:
                    return (600 / 30.0);
                case 60:
                    return (720 / 30.0);
                default:
                    return 0;
            }
        }
    }
public class Fee
    {
        public double Consultancy { get; set; }
        public double Imaging { get; set; }

        public double BloodAnalysis { get; set; }

        public double Injection { get; set; }
    }

    public class FeesFactory
    {
        public Fee Initialize(AgeGroup ageGroup, int injectionSize)
        {
            var fee =new Fee();

            switch (ageGroup)
            {
                case AgeGroup.Child:
                    fee.Consultancy = 25;
                    fee.Imaging = 55;
                    fee.BloodAnalysis = 28;
                    fee.Injection = 0;
                    return fee;


                case AgeGroup.Teen:
                    fee.Consultancy = 32;
                    fee.Imaging = 65;
                    fee.BloodAnalysis = 32;
                    fee.Injection = new TeenInjectionPriceCalculator().Calculate(injectionSize);
                    return fee;


                case AgeGroup.Adult:
                    fee.Consultancy = 40;
                    fee.Imaging = 70;
                    fee.BloodAnalysis = 40;
                    fee.Injection = new AdultInjectionPriceCalculator().Calculate(injectionSize);
                     return fee;


                case AgeGroup.Senior:
                    fee.Consultancy = 30;
                    fee.Imaging = 60;
                    fee.BloodAnalysis = 35;
                    fee.Injection = new AgedInjectionPriceCalculator().Calculate(injectionSize);
                     return fee;

                 default:
                    throw new ArgumentException();
            }

        } 
    }
public double CalculatePrice()
    {
        Console.WriteLine("Quel est l'age du patient?");
        var client = Convert.ToInt32(Console.ReadLine());

        var ageGroup = CalculateAgeGroup(client);
        var userPrefernce = InitializeUserPrefence();
        var fee = new FeesFactory().Initialize(ageGroup,userPrefernce.InjectionSize);

        if (!userPrefernce.IsImaging)
            fee.Imaging = 0;

        if (!userPrefernce.IsConsulation)
            fee.Consultancy = 0;

        if (!userPrefernce.IsBloodAnalysis)
            fee.Injection = 0;

        if (userPrefernce.IsConsulation || userPrefernce.IsImaging)
        {
            fee.Imaging = fee.Imaging * 0.75;
        }

        var finalAmount = fee.Consultancy + fee.Imaging + fee.BloodAnalysis + fee.Injection;
        var finalAmountWithTaxes = finalAmount * 1.15;

        if (userPrefernce.IsConsulation || userPrefernce.IsBloodAnalysis || userPrefernce.IsInjection)
        {
            finalAmountWithTaxes = finalAmountWithTaxes - 10;
        }

        return finalAmountWithTaxes;
    }

Context

StackExchange Code Review Q#107174, answer score: 7

Revisions (0)

No revisions yet.