Household accounts C# Exercise - C# Programming Course

 Exercise

Household accounts

 Objetive

Write a C# program in C# that can store up to 10000 costs and revenues, to create a small domestic accounting system. For each expense (or income), should be allowed to save the following information:

• Date (8 characters: YYYYMMDD format)
• Description of expenditure or revenue
• Category
• Amount (if positive income, negative if an expense)

The program should allow the user to perform the following operations:

1 - Add a new expense (the date should "look right": day 01 to 31 months from 01 to 12 years between 1000 and 3000). The description must not be empty. Needless to validate the other data.

2 - Show all expenses of a certain category (eg, "studies") between two certain dates (eg between "20110101" and "20111231"). Number is displayed, date (format DD / MM / YYYY), description, category in parentheses, and amount to two decimal places, all in the same line, separated by hyphens. At the end of all data show the total amount of data displayed.

3 - Search costs containing a certain text (in the description or category without distinguishing case sensitive). Number is displayed, the date and description (the description is displayed in the sixth truncated blank, if any spaces six or more).

4 - Modify a tab (tab number prompt the user, it will show the previous value of each field and press Enter to not be able to modify any of the data). Should be advised (but not re-order) if the user enters a wrong card number. Needless to validate any data.

5 - Delete some data, from the number that you enter. Should be advised (but not re-order) if you enter an incorrect number. It should show the card to be clear and prompt prior to deletion.

6 - Sort data alphabetically, by date and (if matched) description.

7 - Normalize descriptions: remove trailing spaces, spaces and mirror sites. If a description is all uppercase, will be converted to lowercase (except for the first letter, kept in uppercase).

T-End the use of the application (as we store the information, the data will be lost).

 Example Code

using System;
using System.Collections.Generic;
using System.Linq;

namespace HouseholdAccounts
{
    class Program
    {
        // Create a structure to store cost/revenue information
        struct AccountEntry
        {
            public string Date;         // Date in YYYYMMDD format
            public string Description;  // Description of the expense or income
            public string Category;     // Category of the expense or income
            public decimal Amount;      // Amount (positive for income, negative for expense)
        }

        static List accountEntries = new List(); // List to store all account entries

        static void Main(string[] args)
        {
            bool running = true; // Variable to control the main loop

            while (running) // Main loop to keep the program running
            {
                Console.WriteLine("\nChoose an option:"); // Display menu options
                Console.WriteLine("1 - Add new expense");
                Console.WriteLine("2 - Show expenses by category");
                Console.WriteLine("3 - Search costs by text");
                Console.WriteLine("4 - Modify record");
                Console.WriteLine("5 - Delete data");
                Console.WriteLine("6 - Sort data");
                Console.WriteLine("7 - Normalize descriptions");
                Console.WriteLine("T - End application");

                string choice = Console.ReadLine().ToUpper(); // Read user input and convert it to uppercase

                switch (choice) // Switch based on user choice
                {
                    case "1": // Add a new entry
                        // Ask user for date, description, category, and amount
                        Console.WriteLine("Enter the date (YYYYMMDD):");
                        string date = Console.ReadLine();

                        // Validate the date format (it should be YYYYMMDD, a valid date)
                        DateTime validDate;
                        while (!DateTime.TryParseExact(date, "yyyyMMdd", null, System.Globalization.DateTimeStyles.None, out validDate))
                        {
                            Console.WriteLine("Invalid date. Please enter in the format YYYYMMDD:");
                            date = Console.ReadLine();
                        }

                        // Ask for description
                        Console.WriteLine("Enter description:");
                        string description = Console.ReadLine();
                        while (string.IsNullOrEmpty(description))
                        {
                            Console.WriteLine("Description cannot be empty. Please enter a description:");
                            description = Console.ReadLine();
                        }

                        // Ask for category
                        Console.WriteLine("Enter category:");
                        string category = Console.ReadLine();

                        // Ask for amount
                        Console.WriteLine("Enter amount (positive for income, negative for expense):");
                        decimal amount = Convert.ToDecimal(Console.ReadLine());

                        // Create a new account entry and add it to the list
                        AccountEntry entry = new AccountEntry
                        {
                            Date = date,
                            Description = description,
                            Category = category,
                            Amount = amount
                        };
                        accountEntries.Add(entry); // Add the entry to the list
                        break;

                    case "2": // Show expenses by category
                        Console.WriteLine("Enter start date (YYYYMMDD):");
                        string startDate = Console.ReadLine();

                        Console.WriteLine("Enter end date (YYYYMMDD):");
                        string endDate = Console.ReadLine();

                        // Filter the list by date range
                        var filteredEntries = accountEntries.Where(e =>
                            string.Compare(e.Date, startDate) >= 0 && string.Compare(e.Date, endDate) <= 0).ToList();

                        Console.WriteLine("Enter category:");
                        string categoryFilter = Console.ReadLine();

                        // Filter by category
                        filteredEntries = filteredEntries.Where(e => e.Category.Equals(categoryFilter, StringComparison.OrdinalIgnoreCase)).ToList();

                        // Display the filtered records
                        decimal totalAmount = 0;
                        int count = 1;
                        foreach (var entryInList in filteredEntries) // Changed variable name to avoid conflict
                        {
                            // Format and display each entry
                            Console.WriteLine($"{count} - {entryInList.Date.Substring(6, 2)}/{entryInList.Date.Substring(4, 2)}/{entryInList.Date.Substring(0, 4)} - {entryInList.Description} - ({entryInList.Category}) - {entryInList.Amount:F2}");
                            totalAmount += entryInList.Amount;
                            count++;
                        }
                        Console.WriteLine($"Total amount: {totalAmount:F2}");
                        break;

                    case "3": // Search costs by text
                        Console.WriteLine("Enter text to search:");
                        string searchText = Console.ReadLine().ToLower();

                        // Find entries that match the search text in either description or category (case insensitive)
                        var searchResults = accountEntries.Where(e =>
                            e.Description.ToLower().Contains(searchText) || e.Category.ToLower().Contains(searchText)).ToList();

                        if (searchResults.Count == 0)
                        {
                            Console.WriteLine("No records found.");
                        }
                        else
                        {
                            int searchCount = 1;
                            foreach (var entryInList in searchResults) // Changed variable name to avoid conflict
                            {
                                // Display the result with description truncated if necessary
                                string descriptionSearch = entryInList.Description.Length > 50 ? entryInList.Description.Substring(0, 50) + "..." : entryInList.Description;
                                Console.WriteLine($"{searchCount} - {entryInList.Date.Substring(6, 2)}/{entryInList.Date.Substring(4, 2)}/{entryInList.Date.Substring(0, 4)} - {descriptionSearch}");
                                searchCount++;
                            }
                        }
                        break;

                    case "4": // Modify a record
                        Console.WriteLine("Enter the record number to modify:");
                        int recordNumber = Convert.ToInt32(Console.ReadLine()) - 1;

                        if (recordNumber < 0 || recordNumber >= accountEntries.Count)
                        {
                            Console.WriteLine("Invalid record number.");
                            break;
                        }

                        // Show current values for modification
                        AccountEntry modifyEntry = accountEntries[recordNumber];
                        Console.WriteLine($"Current values: Date: {modifyEntry.Date}, Description: {modifyEntry.Description}, Category: {modifyEntry.Category}, Amount: {modifyEntry.Amount}");

                        // Modify each field
                        Console.WriteLine("Enter new date (or press Enter to keep current):");
                        string newDate = Console.ReadLine();
                        if (!string.IsNullOrEmpty(newDate)) modifyEntry.Date = newDate;

                        Console.WriteLine("Enter new description (or press Enter to keep current):");
                        string newDescription = Console.ReadLine();
                        if (!string.IsNullOrEmpty(newDescription)) modifyEntry.Description = newDescription;

                        Console.WriteLine("Enter new category (or press Enter to keep current):");
                        string newCategory = Console.ReadLine();
                        if (!string.IsNullOrEmpty(newCategory)) modifyEntry.Category = newCategory;

                        Console.WriteLine("Enter new amount (or press Enter to keep current):");
                        string newAmount = Console.ReadLine();
                        if (!string.IsNullOrEmpty(newAmount)) modifyEntry.Amount = Convert.ToDecimal(newAmount);

                        // Save the modified entry
                        accountEntries[recordNumber] = modifyEntry;
                        break;

                    case "5": // Delete data
                        Console.WriteLine("Enter start record number to delete:");
                        int startRecord = Convert.ToInt32(Console.ReadLine()) - 1;

                        Console.WriteLine("Enter end record number to delete:");
                        int endRecord = Convert.ToInt32(Console.ReadLine()) - 1;

                        if (startRecord < 0 || endRecord >= accountEntries.Count || startRecord > endRecord)
                        {
                            Console.WriteLine("Invalid record numbers.");
                            break;
                        }

                        // Confirm deletion of records
                        for (int i = startRecord; i <= endRecord; i++)
                        {
                            Console.WriteLine($"Are you sure you want to delete record {i + 1}? (Y/N)");
                            string confirmation = Console.ReadLine().ToUpper();
                            if (confirmation == "Y")
                            {
                                accountEntries.RemoveAt(i);
                                i--; // Adjust for removed entry
                            }
                        }
                        break;

                    case "6": // Sort data
                        var sortedEntries = accountEntries.OrderBy(e => e.Date).ThenBy(e => e.Description).ToList();

                        // Display sorted entries
                        int sortedCount = 1;
                        foreach (var entryInList in sortedEntries) // Changed variable name to avoid conflict
                        {
                            Console.WriteLine($"{sortedCount} - {entryInList.Date.Substring(6, 2)}/{entryInList.Date.Substring(4, 2)}/{entryInList.Date.Substring(0, 4)} - {entryInList.Description} - ({entryInList.Category}) - {entryInList.Amount:F2}");
                            sortedCount++;
                        }
                        break;

                    case "7": // Normalize descriptions
                        for (int i = 0; i < accountEntries.Count; i++) // Use a for loop to modify the list directly
                        {
                            var entryInList = accountEntries[i]; // Get the entry at index i

                            string normalizedDescription = entryInList.Description.Trim();
                            if (normalizedDescription.ToUpper() == normalizedDescription)  // If the description is all uppercase
                            {
                                normalizedDescription = char.ToUpper(normalizedDescription[0]) + normalizedDescription.Substring(1).ToLower();
                            }

                            // Update the description in the entry
                            accountEntries[i] = new AccountEntry
                            {
                                Date = entryInList.Date,
                                Description = normalizedDescription,
                                Category = entryInList.Category,
                                Amount = entryInList.Amount
                            };
                        }
                        break;

                    case "T": // End application
                        running = false;
                        break;

                    default:
                        Console.WriteLine("Invalid option."); // Handle invalid input
                        break;
                }
            }
        }
    }
}

More C# Exercises of Arrays, Structures and Strings

 Reverse array
Write a C# program to ask the user for 5 numbers, store them in an array and show them in reverse order....
 Search in array
Write a C# program that says if a data belongs in a list that was previously created. The steps to take are: - Ask the user how many data will he ...
 Array of even numbers
Write a C# program to ask the user for 10 integer numbers and display the even ones....
 Array of positive and negative numbers
Write a C# program to ask the user for 10 real numbers and display the average of the positive ones and the average of the negative ones....
 Many numbers and sum
Write a C# program which asks the user for several numbers (until he enters "end" and displays their sum). When the execution is going to end, it must...
 Two dimensional array
Write a C# program to ask the user for marks for 20 pupils (2 groups of 10, using a two-dimensional array), and display the average for each group....
 Statistics V2
Write a C# statistical program which will allow the user to: - Add new data - See all data entered - Find an item, to see whether it has been en...
 Struct
Write a C# Struct to store data of 2D points. The fields for each point will be: x coordinate (short) y coordinate (short) r (red colour, byte) ...
 Array of struct
Write a C# program that expand the previous exercise (struct point), so that up to 1.000 points can be stored, using an "array of struct". Ask the use...
 Array of struct and menu
Write a C# program that expand the previous exercise (array of points), so that it displays a menu, in which the user can choose to: - Add data for...
 Books database
Create a small database, which will be used to store data about books. For a certain book, we want to keep the following information: Title Author...
 Triangle V2
Write a C# program to ask the user for his/her name and display a triangle with it, starting with 1 letter and growing until it has the full length: ...
 Rectangle V3
Write a C# program to ask the user for his/her name and a size, and display a hollow rectangle with it: Enter your name: Yo Enter size: 4 YoYoYoY...
 Centered triangle
Write a C# program that Display a centered triangle from a string entered by the user: __a__ _uan_ Juan...
 Cities database
Create a database to store information about cities. In a first approach, we will store only the name of each city and the number of inhabitants, a...
 Banner
Write a C# program to imitate the basic Unix SysV "banner" utility, able to display big texts....
 Triangle right side
Write a C# program that asks the user for a string and displays a right-aligned triangle: ____n ___an __uan Juan...
 Strings manipulation
Write a C# program that asks the user for a string and: - Replace all lowercase A by uppercase A, except if they are preceded with a space - Displ...
 Nested structs
Write a C# Struct to store two data for a person: name and date of birth. The date of birth must be another struct consisting on day, month an...
 Sort data
Write a C# program to ask the user for 10 integer numbers (from -1000 to 1000), sort them and display them sorted....
 Two dimensional array as buffer for screen
Write a C# program that declares a 70x20 two-dimensional array of characters, "draws" 80 letters (X, for example) in random positions and displays the...
 Two dimensional array 2: circunference on screen
Write a C# program that declares creates a 70x20 two-dimensional array of characters, "draws" a circumference or radius 8 inside it, and displays it o...
 Computer programs
Write a C# program that can store up to 1000 records of computer programs. For each program, you must keep the following data: * Name * Category ...
 Exercise tasks
Write a C# program that can store up to 2000 "to-do tasks". For each task, it must keep the following data: • Date (a set of 3 data: day, month and...

Juan A. Ripoll - Programming Tutorials and Courses © 2025 All rights reserved.  Legal Conditions.