Професионална програма
Loading...
+ Нов въпрос
Elena123456 avatar Elena123456 199 Точки

Military Elite - 20/100 и RunTime Error

Здравейте колеги,

моля за помощ за следната задача, тъй като вече втори ден се чудя какво не е наред в кода ми. Прегледах поне 4,5 решения на колеги, но така и не успявам да си открия проблема в моето решение. Въпреки, че ми излизат  коректни аутпути с дадените инпути, Judge е на друго мнение.

https://github.com/elipopovadev/CSharp-OOP/tree/main/InterfacesAndAbstraction-Exercise/MilitaryElite

https://judge.softuni.bg/Contests/Compete/Index/1502#7

Условие:

Create the following class hierarchy:

  • - general class for Soldiers, holding id, first name and last name.
    • - lowest base Soldier type, holding the salary(decimal).
      • - holds a set of Privates under his command.
      • - general class for all specialised Soldiers - holds the corps of the Soldier. The corps can only be one of the following: Airforces or Marines.
        • - holds a set of Repairs. A Repair holds a part name and hours worked(int).
        • - holds a set of Missions. A mission holds code name and a state (inProgress or Finished). A Mission can be finished through the method CompleteMission().
    • - holds the code number of the Spy (int).

Extract interfaces for each class. (e.g. ISoldier, IPrivate, ILieutenantGeneral, etc.) The interfaces should hold their public properties and methods (e.g. ISoldier should hold id, first name and last name). Each class should implement its respective interface. Validate the input where necessary (corps, mission state) - input should match exactly one of the required values, otherwise it should be treated as invalid. In case of invalid corps the entire line should be skipped, in case of an invalid mission state only the mission should be skipped.

You will receive from the console an unknown amount of lines containing information about soldiers until the command "End" is received. The information will be in one of the following formats:

  • : "Private <id> <firstName> <lastName> <salary>"
  • : "LieutenantGeneral <id> <firstName> <lastName> <salary> <private1Id> <private2Id> … <privateNId>" where privateXId will always be an Id of a Private already received through the input.
  • : "Engineer <id> <firstName> <lastName> <salary> <corps> <repair1Part> <repair1Hours> … <repairNPart> <repairNHours>" where repairXPart is the name of a repaired part and repairXHours the hours it took to repair it (the two parameters will always come paired).
  • : "Commando <id> <firstName> <lastName> <salary> <corps> <mission1CodeName>  <mission1state> … <missionNCodeName> <missionNstate>" a missions code name, description and state will always come together.
  • : "Spy <id> <firstName> <lastName> <codeNumber>"

Define proper constructors. Avoid code duplication through abstraction. Override ToString() in all classes to print detailed information about the object.


  • Name: <firstName> <lastName> Id: <id> Salary: <salary>

  • Name: <firstName> <lastName> Id: <id>
    Code Number: <codeNumber>

  • Name: <firstName> <lastName> Id: <id> Salary: <salary>
    Privates:
      <private1 ToString()>
      <private2 ToString()>
      …
      <privateN ToString()>

  • Name: <firstName> <lastName> Id: <id> Salary: <salary>
    Corps: <corps>
    Repairs:
      <repair1 ToString()>
      <repair2 ToString()>
      …
      <repairN ToString()>

  • Name: <firstName> <lastName> Id: <id> Salary: <salary>
    Corps: <corps>
    Missions:
      <mission1 ToString()>
      <mission2 ToString()>
      …
      <missionN ToString()>

  • Part Name: <partName> Hours Worked: <hoursWorked>

  • Code Name: <codeName> State: <state>

NOTE: Salary should be printed rounded to two decimal places after the separator.

 

Input

Private 1 Pesho Peshev 22,22
Commando 13 Stamat Stamov 13,1 Airforces

Private 222 Toncho Tonchev 80,08

LieutenantGeneral 3 Joro Jorev 100 222 1

End

Output

Name: Pesho Peshev Id: 1 Salary: 22.22

Name: Stamat Stamov Id: 13 Salary: 13.10

Corps: Airforces

Missions:

Name: Toncho Tonchev Id: 222 Salary: 80.08

Name: Joro Jorev Id: 3 Salary: 100.00

Privates:

  Name: Toncho Tonchev Id: 222 Salary: 80.08
  Name: Pesho Peshev Id: 1 Salary: 22.22

 

Input:

Engineer 7 Pencho Penchev 12,23 Marines Boat 2 Crane 17

Commando 19 Penka Ivanova 150,15 Airforces HairyFoot finished Freedom inProgress

End

 

Output:

Name: Pencho Penchev Id: 7 Salary: 12.23

Corps: Marines

Repairs:

  Part Name: Boat Hours Worked: 2

  Part Name: Crane Hours Worked: 17

Name: Penka Ivanova Id: 19 Salary: 150.15

Corps: Airforces
Missions:

  Code Name: Freedom State: inProgress

Тагове:
0
C# Advanced 07/04/2021 17:16:55
Axiomatik avatar Axiomatik 1169 Точки
Best Answer

Hi Eli,

This is a super-vital exercise for learning how to use interfaces and inheritance and when followed step-by-step usually doesn't contain any problems other than being very lengthy - the best thing to do is to watch the given exercise video that comes with it.

Some things that might be an issue:

1. When creating the specialized soldier types you first create the given object outside of the try-catch and then check if the array contains any additional info inside of the try-catch:

        private static void AddGeneral(List<Soldier> soldierList, string[] soldierInput)
        {
            int id = int.Parse(soldierInput[1]);
            string firstName = soldierInput[2];
            string lastName = soldierInput[3];
            decimal salary = decimal.Parse(soldierInput[4]);

            LieutenantGeneral general = new LieutenantGeneral(id, firstName, lastName, salary);
            if (soldierInput.Length > 5)
            {
                for (int i = 5; i < soldierInput.Length; i++)
                {
                    int targetId = int.Parse(soldierInput[i]);
                    var currentPrivate = (Private)soldierList.First(sol => sol.Id == targetId);
                    general.AddPrivate(currentPrivate);
                }
            }

            soldierList.Add(general);
        }

        private static void AddEngineer(List<Soldier> soldierList, string[] soldierInput)
        {
            int id = int.Parse(soldierInput[1]);
            string firstName = soldierInput[2];
            string lastName = soldierInput[3];
            decimal salary = decimal.Parse(soldierInput[4]);
            string corps = soldierInput[5];

            Engineer engineer = new Engineer(id, firstName, lastName, salary, corps);
            if (soldierInput.Length > 6)
            {
                for (int i = 6; i < soldierInput.Length; i+=2)
                {
                    string partName = soldierInput[i];
                    int repairTime = int.Parse(soldierInput[i + 1]);

                    try
                    {
                        Repair repair = new Repair(partName, repairTime);
                        engineer.AddRepair(repair);
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }

            soldierList.Add(engineer);
        }

        private static void AddCommando(List<Soldier> soldierList, string[] soldierInput)
        {
            int id = int.Parse(soldierInput[1]);
            string firstName = soldierInput[2];
            string lastName = soldierInput[3];
            decimal salary = decimal.Parse(soldierInput[4]);
            string corps = soldierInput[5];

            Commando commando = new Commando(id, firstName, lastName, salary, corps);
            if (soldierInput.Length > 6)
            {
                for (int i = 6; i < soldierInput.Length; i+=2)
                {
                    string missionName = soldierInput[i];
                    string missionState = soldierInput[i + 1];
                    try
                    {
                        Mission mission = new Mission(missionName, missionState);
                        commando.AddMission(mission);
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }

            soldierList.Add(commando);
        }

Also, interfaces should inherit the base interface or other derived interfaces for more specialized soldier-types, so that in the end the final class only inherits one interface and one base-class:

IPrivate => IPrivate : ISoldier
Private => Private : Soldier, IPrivate

ISoldier => ISoldier
Soldier => ISoldier

ISpecialisedSoldier => ISpecialisedSoldier : IPrivate 
SpecialisedSoldier =>  SpecialisedSoldier : Private, ISpecialisedSoldier

Commando => Commando: SpecialisedSoldier, ICommando
Engineer =>  Engineer : SpecialisedSoldier, IEngineer

ISpy =>  ISpy : ISoldier
Spy => Spy : Soldier, ISpy

For the mission class, I think it was necessary to check the input for the State property:

Mission => Mission : IMission

    public interface IMission
    {
        string Code { get; }

        string State { get; }

        void CompleteMission();
    }

        public string State
        {
            get
            {
                return this.state;
            }
            private set
            {
                if (value != "inProgress" && value != "Finished")
                {
                    throw new ArgumentException();
                }
                this.state = value;
            }
        }

Best,

 

1
Elena123456 avatar Elena123456 199 Точки

Hi Axiomatik, thank you so much again. :)

I changed everything in my code like you said:

1) edited  try catch;

2) added multiply inheritance in every my interface (my inheritance in every my class is like yours);

3) edited my class Mission and added interface IMission;

In the end I added blank space in my ToString() when I print listPrivates and listRepairs, because I missed them.

And the result is also 20/100 with three correct tests, one incorrect and three RunTime Errors. I'm very disparate.

Maybe I missed something important or might have been something else.

 

 

 

0
Axiomatik avatar Axiomatik 1169 Точки

RunTime errors are most likely triggered from your StartUp class (ie Engineer has its for-loop run until inputArray.Length - 1 instead of inputArray.Length), unless some errors in your class builds. You can compare with different StartUp classes from other solutions, to try to fix some errors but also do watch how the SoftUni instructors solve this exercise and then come back to your solution and eliminate all of the problems.

StartUp:

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

using MilitaryElite.Classes;
using MilitaryElite.Interfaces;

namespace MilitaryElite.Core
{
    public class Engine
    {
        public Engine()
        {
        }

        public void Run()
        {
            List<Soldier> soldierList = new List<Soldier>();

            string[] soldierInput = Console.ReadLine()
                .Split(" ", StringSplitOptions.RemoveEmptyEntries);


            while (soldierInput[0] != "End")
            {

                string typeSoldier = soldierInput[0];
                try
                {
                    if (typeSoldier == "Private")
                    {
                        AddPrivate(soldierList, soldierInput);
                    }
                    else if (typeSoldier == "LieutenantGeneral")
                    {
                        AddGeneral(soldierList, soldierInput);
                    }
                    else if (typeSoldier == "Engineer")
                    {
                        AddEngineer(soldierList, soldierInput);
                    }
                    else if (typeSoldier == "Commando")
                    {
                        AddCommando(soldierList, soldierInput);
                    }
                    else if (typeSoldier == "Spy")
                    {
                        AddSpy(soldierList, soldierInput);
                    }
                }
                catch (Exception ex)
                {

                }

                soldierInput = Console.ReadLine()
                    .Split(" ", StringSplitOptions.RemoveEmptyEntries);
            }


            foreach (var soldier in soldierList)
            {
                Console.WriteLine(soldier.ToString());
            }
        }

        private static void AddSpy(List<Soldier> soldierList, string[] soldierInput)
        {
            int id = int.Parse(soldierInput[1]);
            string firstName = soldierInput[2];
            string lastName = soldierInput[3];
            int codeNumber = int.Parse(soldierInput[4]);

            Spy spy = new Spy(id, firstName, lastName, codeNumber);
            soldierList.Add(spy);
        }

        private static void AddCommando(List<Soldier> soldierList, string[] soldierInput)
        {
            int id = int.Parse(soldierInput[1]);
            string firstName = soldierInput[2];
            string lastName = soldierInput[3];
            decimal salary = decimal.Parse(soldierInput[4]);
            string corps = soldierInput[5];

            Commando commando = new Commando(id, firstName, lastName, salary, corps);
            if (soldierInput.Length > 6)
            {
                for (int i = 6; i < soldierInput.Length; i+=2)
                {
                    string missionName = soldierInput[i];
                    string missionState = soldierInput[i + 1];
                    try
                    {
                        Mission mission = new Mission(missionName, missionState);
                        commando.AddMission(mission);
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }

            soldierList.Add(commando);
        }

        private static void AddEngineer(List<Soldier> soldierList, string[] soldierInput)
        {
            int id = int.Parse(soldierInput[1]);
            string firstName = soldierInput[2];
            string lastName = soldierInput[3];
            decimal salary = decimal.Parse(soldierInput[4]);
            string corps = soldierInput[5];

            Engineer engineer = new Engineer(id, firstName, lastName, salary, corps);
            if (soldierInput.Length > 6)
            {
                for (int i = 6; i < soldierInput.Length; i+=2)
                {
                    string partName = soldierInput[i];
                    int repairTime = int.Parse(soldierInput[i + 1]);

                    try
                    {
                        Repair repair = new Repair(partName, repairTime);
                        engineer.AddRepair(repair);
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }

            soldierList.Add(engineer);
        }

        private static void AddGeneral(List<Soldier> soldierList, string[] soldierInput)
        {
            int id = int.Parse(soldierInput[1]);
            string firstName = soldierInput[2];
            string lastName = soldierInput[3];
            decimal salary = decimal.Parse(soldierInput[4]);

            LieutenantGeneral general = new LieutenantGeneral(id, firstName, lastName, salary);
            if (soldierInput.Length > 5)
            {
                for (int i = 5; i < soldierInput.Length; i++)
                {
                    int targetId = int.Parse(soldierInput[i]);
                    var currentPrivate = (Private)soldierList.First(sol => sol.Id == targetId);
                    general.AddPrivate(currentPrivate);
                }
            }

            soldierList.Add(general);
        }

        private static void AddPrivate(List<Soldier> soldierList, string[] soldierInput)
        {
            int id = int.Parse(soldierInput[1]);
            string firstName = soldierInput[2];
            string lastName = soldierInput[3];
            decimal salary = decimal.Parse(soldierInput[4]);

            Private soldier = new Private(id, firstName, lastName, salary);
            soldierList.Add(soldier);
        }
    }
}

Repair-class (variant 1):

using System;
using MilitaryEliteDemo.Contracts;

namespace MilitaryEliteDemo.Models
{
    public class Repair : IRepair
    {
        public Repair(string partName, int hoursWorked)
        {
            this.PartName = partName;
            this.HoursWorked = hoursWorked;
        }

        public string PartName { get; private set; }

        public int HoursWorked { get; private set; }

        public override string ToString()
        {
            return $"Part Name: {this.PartName} Hours Worked: {this.HoursWorked}";
        }
    }
}

Repair class (variant 2):

using System;
using System.Text;
using MilitaryElite.Interfaces;

namespace MilitaryElite.Classes
{
    public class Repair : IRepair
    {
        private int hours;

        public Repair(string name, int hours)
        {
            Name = name;
            Hours = hours;
        }

        public string Name { get; }

        public int Hours
        {
            get
            {
                return this.hours;
            }
            private set
            {
                if (value < 0)
                {
                    throw new ArgumentException();
                }
                this.hours = value;
            }
        }

        public override string ToString()
        {
            return $"Part Name: {this.Name} Hours Worked: {this.Hours}";
        }
    }
}

 

 

1
07/04/2021 21:06:45
Elena123456 avatar Elena123456 199 Точки

@ Axiomatik  ,

I got 100/100 after three days working and nearly thirty attemps - https://github.com/elipopovadev/CSharp-OOP/tree/main/InterfacesAndAbstraction-Exercise/MilitaryElite. You really help me to understand how important is this exercise and to found out my mistakes in my last solution. This exercise is closest to the real web project, isn't it?!  Can you  tell me more exercises like this one, because I'm not very confident to work with Engine, Writer and Reader?

I made some folders:

- Core with Engine and IEngine;

-  Enums with enumeration for State and Corps;

-  Exceptions with three exceptions - "InvalidCorpsException", "InvalidMissionCompletion Exception", "InvalidStateException";

-  Interfaces;

-  IO with ConsoleReader, ConsoleWriter, IReader and IWriter;

-  Models;

And StartUp:

using MilitaryElite.Core;
using MilitaryElite.IO;
using MilitaryElite.IO.Contracts;

namespace MilitaryElite
{
    public class StartUp
    {
        static void Main(string[] args)
        {
            IReader reader = new ConsoleReader();
            IWriter writer = new ConsoleWriter();
            IEngine engine = new Engine(reader, writer);
            engine.Run();
        }
    }
}

 

Best Regards!

 

1