Contents

Kata 10 solution

How do I do it?

If you’ve managed to complete Kata 10 on your own…Well done!

If not, don’t despair - I’ll explain a way of creating each part of the program.

Maybe you were only stuck on one part - read this to unblock yourself, and try other parts by yourself.

If you want to follow along with this, it’s helpful to look at the model solution too.

Reading the file and parsing the input

public void CalculatePayroll() {
    string[] workRateFile = File.ReadAllLines("TestData/workRate-1.txt");
    double hourlyRate = Convert.ToDouble(workRateFile[0]);
    int numberOfWorkRateEntires = Convert.ToInt32(workRateFile[1]);
}

This isn’t too difficult. First we use File.ReadAllLines, passing the name of the Work-Rate file. We look at the first and second lines of the file, using array indexes 0 and 1. We can covert them from strings to int and double using C#’s built in Convert methods.

Parsing the Work-Rate entires

This is quite tricky. Using the numberOfWorkRateEntires variable, we can construct a for loop to iterate through the Work-Rate entires. However, we must start at index 2, since the entires start on the third line of the file (remember, the first line is at index 0 in the array).

We can then use IndexOf to get the index of the space character in each work rate entry. Using that, we can Substring each entry to get the employee name and hours worked. Using Convert.ToInt32 again, we can convert from string to int.

for(int i = 2; i < 2 + numberOfWorkRateEntires; i++) {
    int indexOfSpace = workRateFile[i].IndexOf(' ');
    string employeeName = workRateFile[i].Substring(0, indexOfSpace);
    int employeeWorkHours = Convert.ToInt32(workRateFile[i].Substring(indexOfSpace));
}

Creating Employee objects in an array

The Employee class is straightforwards to create - see the model answer.

newing them up into an array in the for loop is complicated by the fact that i is going to be 2 indexes ahead of your new array. Therefore you need to use i-2 for the index of your Employee array:

for(int i = 2; i < 2 + numberOfWorkRateEntires; i++) {
    int indexOfSpace = workRateFile[i].IndexOf(' ');
    string employeeName = workRateFile[i].Substring(0, indexOfSpace);
    int employeeWorkHours = Convert.ToInt32(workRateFile[i].Substring(indexOfSpace));
    employees[i - 2] = new Employee(employeeName, employeeWorkHours);
}

Calculating pay

First, let’s create a method that calculates normal pay. This is ‘hours worked’ multiplied by the ‘hourly rate’:

private double CalculatePay(double hourlyRate, int hoursWorked) {
    double pay = hourlyRate * hoursWorked;
    return pay;
}

Next, let’s think about overtime. An employee earns overtime pay for every hour over 180. Therefore, we need an if statement to check if that’s the case:

private double CalculatePay(double hourlyRate, int hoursWorked) {

    if (hoursWorked > 180) {
        // Calculate overtime...
    }

    double pay = hourlyRate * hoursWorked;
    return pay;
}

Next we need to work out the amount of overtime the employee has worked, and the overtime rate.

This is simple - overtime hours is just hours worked minus 180. The overtime hourly rate is 1.5x the normal hourly rate. The overtime pay can therefore be calculated like so:

int overtimeHours = hoursWorked - 180;
double overtimeHourlyRate = hourlyRate * 1.5;
double overtimePay = overtimeHours * overtimeHourlyRate;

Next we can just calculate the normal pay and add it to the overtime pay to get the final result.

double normalPay = 180 * hourlyRate;

double pay = normalPay + overtimePay;
return pay;

The whole thing therefore looks like this:

private double CalculatePay(double hourlyRate, int hoursWorked) {

    if (hoursWorked > 180) {
        int overtimeHours = hoursWorked - 180;
        double overtimeHourlyRate = hourlyRate * 1.5;
        double overtimePay = overtimeHours * overtimeHourlyRate;

        double normalPay = 180 * hourlyRate;

        double finalPay = normalPay + overtimePay;
        return finalPay;
    }

    double pay = hourlyRate * hoursWorked;
    return pay;
}

Notice that the number 180 - the overtime threshold - has been used a lot in the code. We can create a variable to store it. We can also use the const keyword, which means it cannot be reassigned:

private double CalculatePay(double hourlyRate, int hoursWorked) {
    const int overtimeThreshold = 180;

    if (hoursWorked > overtimeThreshold) {
        int overtimeHours = hoursWorked - overtimeThreshold;
        int overtimeHourlyRate = hourlyRate * 1.5;
        double overtimePay = overtimeHours * overtimeHourlyRate;

        double normalPay = overtimeThreshold * hourlyRate;

        double finalPay = normalPay + overtimePay;
        return finalPay;
    }

    double pay = hourlyRate * hoursWorked;
    return pay;
}

Printing the payroll isn’t too difficult also! First create a method with the correct signature, taking an Employee array, and an hourly rate:

private void PrintPayroll(Employee[] employees, double hourlyRate) {
}

Next, introduce a for loop that uses the .Length property on employees to iterate through the array. Get the hours worked from the Employee object, and calculate the pay using CalculatePay. Finally, use Console.WriteLine to print the payroll file to Standard Output!

private void PrintPayroll(Employee[] employees, double hourlyRate) {
    Console.WriteLine("Pay for employees this month:");

    for (int i = 0; i < employees.Length; i++) {
        double pay = CalculatePay(hourlyRate, employees[i].HoursWorked);

        Console.WriteLine(employees[i].Name + " " + pay);
    }
}
Copyright Mikiel Agutu 2019