简体   繁体   中英

How to print and sort list of sellers based on Bonus Tier in C#

Description

I am really new in C#, please don't hate me for this.

I'm trying to print a list of sellers.
The list is based on 4 bonus tier/levels , depending on how many articles those sellers sold.
Level1: under 50 articles
Level2: 50-99 articles
Level3: 100-199 articles
Level4: for over 199 articles.

When printing, you should count which level they reached , based on how many articles they sold .
The program should also write the output to a file .

My problem and what i need help with

I've created below program that does the job, but i am stuck in the part where the sorting/printing happens.

The code

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace BonusCounter
{
    class Program
    {
        /*  
     * Main method of the consoleprogram.   
     * Creates a program and runs "SalesObject" not more than 6 times.  
     */
        public static void Main(string[] args)
        {
            StringBuilder LogString = new StringBuilder();
            List<SalesObject> salesList = new List<SalesObject>();

            // Test data
            /*salesList.Add(new SalesObject("Kalle Anka", "000", "Ankeborg", 39));
            salesList.Add(new SalesObject("Joakim von Anka", "000", "Ankeborg", 198));
            salesList.Add(new SalesObject("Alexander Lukas", "000", "Ankeborg", 201));*/
            salesList.Add(new SalesObject("Seller 1", "000", "London", 77));
            salesList.Add(new SalesObject("Seller 2", "000", "Edinburg", 44));
            salesList.Add(new SalesObject("Seller 3", "000", "Manchester", 33));

            // Add a seller
            Console.WriteLine("How many sellers to you want to register?");
            Console.Write("Max 6 seller at a time: ");
            int j = Convert.ToInt32(Console.ReadLine());
            // Loops through the lines. 
            for (int i = 0; i < j; i++)
            {
                salesList.Add(SalesObject.GetSeller());
            }

            // Count
            salesList.Sort();
            int currentLevel = Tier.Levels.Length;
            int sellersInCurrentGroup = 0;
            foreach (SalesObject seller in salesList)
            {
                int bonusGroup = Tier.BonusGroup(seller);

                if (bonusGroup < currentLevel)
                {
                    PrintBonusLevelSummary(sellersInCurrentGroup, currentLevel);
                    currentLevel -= 1;
                    sellersInCurrentGroup = 0;
                }
                Logger.Out(seller.ToString());
                sellersInCurrentGroup += 1;
            }
            PrintBonusLevelSummary(sellersInCurrentGroup, currentLevel);

            /* Print the result to a file
             * Filepath for write operation is relative to the project, file is situated in "\bin\Debug\netcoreapp{version}"
             * The file is named "Inl2.txt" */
            string logFile = Environment.CurrentDirectory + @"\Inl2.txt";
            File.WriteAllText(logFile, Logger.LogString.ToString());
            Console.WriteLine("\n");
            Console.WriteLine($"The result has been saved in: {logFile}");
            Console.WriteLine("Press ENTER to exit...");
            ConsoleKeyInfo keyInfo = Console.ReadKey();
            while (keyInfo.Key != ConsoleKey.Enter)
                keyInfo = Console.ReadKey();
        }

        // Print to console and handle the Teir sort. 
        public static void PrintBonusLevelSummary(int sellersInCurrentGroup, int currentLevel)
        {
            if (currentLevel == 0)
                Logger.Out("No one have reached any level");
            if (currentLevel == Tier.Levels.Length)
            {
                // Level 4
                Logger.Out(
                    $"{sellersInCurrentGroup} seller have reached level {currentLevel}: {Tier.Levels[Tier.Levels.Length - 1]}+ articles");
                Logger.Out("-------------------------------------------");
                Logger.Out("");
            }
            else
            {
                // Rest of the levels
                Logger.Out(
                    //WriteToConsoleAndFile($"{agents.ToList().Count} har nått nivå {GetSalesLevel(agents)}\n");
                    $"{sellersInCurrentGroup} seller have reached level {currentLevel}: {Tier.Levels[currentLevel - 1]}-{Tier.Levels[currentLevel]} articles");
                Logger.Out("-------------------------------------------");
                Logger.Out("");
            }
        }
    }

    /*  
     *  Main class of the consoleprogram.
     * Object to keep track of the variables of a seller for easier handling of the data.   
     * Contains methods for getting all variables. Variables can be set when object is created. 
     */
    public class SalesObject : IComparable<SalesObject>
    {
        // Variables
        private readonly string _name;

        private readonly string _personnr;
        private readonly string _district;
        public readonly int _articles;

        // Array of above variables, create an object with constructor 
        public SalesObject(string name, string personnr, string district, int articles)
        {
            _name = name;
            _personnr = personnr;
            _district = district;
            _articles = articles;
        }

        // Methods, take in sellers.
        public static SalesObject GetSeller()
        {
            Logger.Out("Name:");
            string name = Console.ReadLine();

            Logger.Out("Personal number:");
            string personnr = Console.ReadLine();

            Logger.Out("District:");
            string district = Console.ReadLine();

            Logger.Out("Amount of articles sold:");
            int articles = Convert.ToInt32(Console.ReadLine());

            return new SalesObject(name, personnr, district, articles);
        }

        public int CompareTo(SalesObject seller)
        {
            return -_articles.CompareTo(seller._articles);
        }

        public string ToString()
        {
            return _name + "\t" + _personnr + "\t" + _district + "\t" + _articles;
        }
    }

    // Class that handles the tiers.
    public class Tier
    {
        public static readonly int[] Levels = { 1, 50, 100, 200 }; // change tiers here

        public static int BonusGroup(SalesObject seller)
        {
            int articles = seller._articles;

            if (articles < 1) // Return 0 if seller didn't sell anything
                return 0;

            int bonusLevel = 1;


            for (int i = 0; i < Levels.Length; i++)
            {
                if (bonusLevel == Levels.Length) // Return the hights tier. 
                    return bonusLevel;

                if (Levels[i] <= articles && articles < Levels[i + 1]
                    )
                    // Checks if the current object is the last in its tier.
                    return bonusLevel;
                bonusLevel += 1;
            }
            return 0; //default
        }
    }

    // The class that handles the file output
    public static class Logger
    {
        public static StringBuilder LogString = new StringBuilder();

        public static void Out(string str)
        {
            Console.WriteLine(str);
            LogString.Append(str).Append(Environment.NewLine);
        }
    }
}

How to run

You can run the code and it will ask how many sellers you want to register there are 3 test sellers in the code for testing porpuse.

Expected output

it should print like this:

Name           Persnr   District    articles
0 seller have reached level 4: 200+ articles
------------------------------------------

0 seller have reached level 3: 100-200 articles
------------------------------------------

Seller 1        000     London         77
1 seller have reached level 2: 50-100 articles
-------------------------------------------

Seller 2        000     Edinburg       44
Seller 3        000     Manchester     33
2 seller have reached level 1: 1-50 articles
-------------------------------------------

But it's printing like below, which is wrong

0 seller have reached level 4: 200+ articles
------------------------------------------

Seller 1     000     London            77
1 seller have reached level 3: 100-200 articles
------------------------------------------

Seller 2     000     Edinburg          44
1 seller have reached level 2: 50-100 articles
-------------------------------------------

Seller 3     000     Manchester        33
1 seller have reached level 1: 1-50 articles
-------------------------------------------
int currentLevel = Tier.Levels.Length; int sellersInCurrentGroup = 0; foreach (SalesObject seller in salesList) { int bonusGroup = Tier.BonusGroup(seller); if (bonusGroup < currentLevel) { PrintBonusLevelSummary(sellersInCurrentGroup, currentLevel); currentLevel -= 1; sellersInCurrentGroup = 0; } Logger.Out(seller.ToString()); sellersInCurrentGroup += 1; } PrintBonusLevelSummary(sellersInCurrentGroup, currentLevel);

Let's break down how you're sorting the sellers by bonus tier.

With the code block above you're basically saying "Go to each seller, check what it's bonusGroup is. Then if it's bonus group is less than the currentLevel we should, print the group summary, decrement currentLevel by 1 and reset sellersInCurrentGroup back to 0 . Then print the seller and increase the sellersInCurrentGroup by 1 .

All of these things make sense individually, but in the order you have them the actual effect is that "When I encounter ANY seller with a tier less than currentLevel give up and move to the next tier, but also print them and add them to the next tier." That isn't exactly what we're going for.

We should instead write something that says "Go to each tier, check each seller to see if they're in the tier, if they are we should print them and add one to sellersInCurrentGroup , after that print the summary for the group." We should find that falls more in-line with what we want for your expected output.

Here's a short example of what that implementation might look like.

int sellersInCurrentGroup;

// go to each tier
for (int currentLevel = Tier.Levels.Length; currentLevel-- > 1;)
{
    // reset the people in this tier
    sellersInCurrentGroup = 0;

    // go to each seller and see if they're in this tier
    foreach (SalesObject seller in salesList)
    {
        // get the seller's tier
        int bonusGroup = Tier.BonusGroup(seller);

        // check to see if it's this tier
        if (bonusGroup == currentLevel)
        {
            // since they were in this tier, increase the number of
            // sellers in this tier by 1
            sellersInCurrentGroup += 1;

            // print their name
            Logger.Out(seller.ToString());
        }
    }

    // now that we have counted all the sellers in this tier
    // print the tier summary
    PrintBonusLevelSummary(sellersInCurrentGroup, currentLevel);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM