Drop links or images here to add them to the editor.

Formatting rainfall data.

Rainfall collector

Try

Watch this video to learn about the new concepts shown in the program:

Knowledge organiser

string[,] w = new string[z, y];

In this example, w is declared as a 2D array of z rows and y columns. Columns and rows don’t really exist in the computer’s memory; they are an abstraction that makes the table easier for us to understand. Elements are initialised to null; assign "" to each cell if you want empty strings.

In C#, the multidimensional array shape is fixed when you allocate it. If you don’t know how many rows you’ll need, use List<string[]> (a list of row arrays) and .Add(...) as you read.

Data can be stored in comma separated file (CSV) format, where each row (record) has data separated into columns (fields) by commas.

If the number of rows and columns is known, you can use a 2D array initialised in advance as shown above. If the number of rows is not known, a List<string[]> will be needed with new rows added to the list as they are read from the file.

This is a common operation when using files and 2D lists. Here is some boilerplate code that can be used to read data from a file and return it in a 2D list called database.

// Read data from filename and return a list of row arrays
static List<string[]> read_file(string filename)
{
    List<string[]> database = new List<string[]>();
    StreamReader file = new StreamReader(filename);
    string line;
    while ((line = file.ReadLine()) != null)
    {
        string[] fields = line.Trim().Split(',');
        database.Add(fields);
    }
    file.Close();
    return database;
}

Investigate

Questions to think about with this program to check your understanding:

Item question

Identify the line where a 2D array is initialised.

Reveal answer

The declaration:

string[,] data = new string[num_regions, 2];
Structure question

Explain what the numbers num_regions and 2 represent in the array declaration.

Reveal answer

The number of rows and columns when the two-dimension structure is visualised as a table. Seven rows and two columns.

As the structure is zero-indexed, the first index is 0, so the indexes for seven rows are 0-6, and the columns 0-1.

Index 0 1
0 data[0, 0] data[0, 1]
1 data[1, 0] data[1, 1]
2 data[2, 0] data[2, 1]
3 data[3, 0] data[3, 1]
4 data[4, 0] data[4, 1]
5 data[5, 0] data[5, 1]
6 data[6, 0] data[6, 1]

Make

Change the program so that it:

  1. Includes a function called short_label that takes a parameter label and returns the first character from each word in label. E.g. South West would be SW.

    Hint

    Splitting the label into an array of words separated by a space and using a foreach loop to iterate and take the first character is the easiest way to solve this problem.

  2. Includes a subprogram called, output_short_table that outputs the data in the format shown below.
  3. Calls the output_short_table subprogram after output_table in the main program.

The program reads its data from a file called data.txt, which contains:

North West,30
North East,31
Central,13
East,10
South East,17
South West,18
Isle of Wight,16

Typical inputs and outputs from the program would be:

NW  | 30
NE  | 31
C   | 13
E   | 10
SE  | 17
SW  | 18
IoW | 16
🆘 If you're really stuck, use this Parsons code sorting exercise
read_data
// Read the data from the file into a 2D array
static string[,] read_data(string filename)
{
---
    int num_regions = 7;
    string[,] data = new string[num_regions, 2];
    StreamReader file = new StreamReader(filename);
---
    // Read each line of data from the file
    for (int region = 0; region < num_regions; region++)
    {
---
        string data_row = file.ReadLine();
        data_row = data_row.Trim();
        // Split the row of data by the comma separator into fields
        string[] data_list = data_row.Split(',');
        // Populate the data table with the fields
        data[region, 0] = data_list[0];
        data[region, 1] = data_list[1];
---
    }
---
    file.Close();
    return data;
}
padded_label, output_table
// Pad data with spaces to achieve a chars string length
static string padded_label(string label, int characters)
{
---
    return label + new string(' ', characters - label.Length);
---
}


---
// Output the table of data
static void output_table(string[,] data)
{
---
    int num_regions = 7;
    int characters = 0;
---
    for (int region = 0; region < num_regions; region++)
    {
---
        if (data[region, 0].Length > characters)
        {
---
            characters = data[region, 0].Length;
---
        }
---
    }
---
    for (int region = 0; region < num_regions; region++)
    {
---
        string table_row = padded_label(data[region, 0], characters);
        table_row += " | " + data[region, 1];
        Console.WriteLine(table_row);
---
    }
---
    Console.WriteLine();
}
short_label
// Convert the name of a region into initials
static string short_label(string label)
{
---
    // Split label by spaces into a list
    string[] region_label_list = label.Split(' ');
    string region_label = "";
---
    // Take the first letter from each item in the list
    foreach (string word in region_label_list)
    {
---
        region_label += word[0];
---
    }
---
    return region_label;
}
output_short_table
// Output the table of data with short region names
static void output_short_table(string[,] data)
{
---
    int num_regions = 7;
    int characters = 0;
---
    // Calculate the maximum size of the short region label
    for (int region = 0; region < num_regions; region++)
    {
---
        string region_label = short_label(data[region, 0]);
        // Record new maximum
        if (region_label.Length > characters)
        {
---
            characters = region_label.Length;
---
        }
---
    }
---
    // Output the formatted table
    for (int region = 0; region < num_regions; region++)
    {
---
        string region_label = short_label(data[region, 0]);
        string table_row = region_label + new string(' ', characters - region_label.Length);
        table_row += " | " + data[region, 1];
        Console.WriteLine(table_row);
---
    }
}