(P) IT-yritys

Tavoite: Opettelen modulaarisuutta olio-ohjelmoinnissa sekä sitä, miten luokat (oliot) voivat olla yhteydessä toisiinsa. Harjoittelen valmiin koodin lukemista sekä osoittimien käyttämistä ja dynaamista muistinhallintaa. Samalla kertaan STL:n säiliöitä. Myös ohjelman jakamista osiin funktioita ja luokkia käyttäen on syytä pohtia.

Ohjeita: Hae ohjelmakoodipohja: templates/10/it_company/ -> student/10/it_company/. Koodipohjassa on aika monta tiedostoa ja luokkaa, mutta ne ovat hyvin yksinkertaisia ja helposti ymmärrettäviä.

Pohjakoodissa on joitakin komentoja toteutettu valmiiksi. Voit aloittaa kokeilemalla, miten ne toimivat.

Tärkeää

Ennen kuin aloitat, lue huolellisesti koko tehtävänanto. Huomaa erityisesti kohdat Ohjelman toteuttaminen osissa (vaaditut commitit) sekä Erityisvaatimukset.

Kohdasta Arviointi huomaa erityisesti, että ohjelman pitää ensin läpäistä kaikki automaattitestit. Muuten työ ei mene assistenttien arvioitavaksi, eikä siitä saa pisteitä.

Huomautus

Tämä projekti tehdään itsenäisenä työskentelynä. Parityöskentely ei ole sallittua, vaan sitä pidetään plagiointina.

Toteuta valmiiksi ohjelma, joka käynnistyessään lukee käyttäjän antamia komentoja. Komennosta riippuen ohjelma joko tallentaa tietoja sopivaan tietorakenteeseen, poistaa niitä, tai tekee hakuja kyseiseen tietorakenteeseen.

Alkukommentti ja palautteen kieli

Samoin kuin ensimmäisessä projektissa, tässäkin projektissa vaaditaan alkukommentti. Tällä kertaa alkukommenttia ei anneta valmiina, vaan sinun pitää kirjoittaa se itse. Mallia voit katsoa ensimmäisen projektin tehtävänannosta (4.5 (P) Tammi).

Palautteen kieli valitaan palautuslaatikossa (tämän sivun lopussa). Palautteen kielenä on oletuksena suomi, mutta voit vaihtaa sen, jos haluat assistenttien antaman palautteen englanniksi. Kielivalinta määräytyy sen perusteella, minkä kielivalinnan olet tehnyt viimeisimmän palautuksen palautuslaatikossa.

Ohjelman toiminnan kuvaus

Ohjelmassa on luokat Company, Project, Employee, Date ja Cli sekä moduuli (nimiavaruus) Utils.

Luokan Employee oliot (ilmentymät) kuvaavat IT-yrityksen henkilökuntaa. Työntekijöitä voidaan rekrytoida, ja he voivat irtisanoutua. Työntekijällä on tunnisteenaan nimi (kuten alla olevissa esimerkkiajoissa) tai jokin muu merkkijono sekä taitoja, joita voidaan tarvita projekteissa.

Luokka Project kuvaa yhtä projektia. Projektissa voi työskennellä useita työntekijöitä, ja myös työntekijät voivat työskennellä useissa projekteissa. Projektilla on ainakin alkamispäivämäärä, ja päättyneillä projekteilla on myös päättymispäivämäärä. Lisäksi projektilla voi olla erilaisia vaatimuksia, eli sen työntekijöiltä vaaditaan joitakin taitoja.

Luokka Cli (command line interpreter) kuvaa komentotulkin, eli se hallinnoi ohjelmassa käytettyjä komentoja. Moduuli Utils tarjoaa muutaman yleiskäyttöisen funktion. Kumpaankaan näistä (Cli tai Utils) ei tarvitse tehdä mitään muutoksia. Näissä moduuleissa tarkistetaan esimerkiksi, antoiko käyttäjä komennolle oikean määrän oikean tyyppisiä parametreja. Tarkistukset on toteutettu valmiiksi, joten niistä ei tarvitse huolehtia.

Luokka Company hallinnoi koko ohjelmaa, ja siitä luodaan vain yksi olio. Yrityksellä on henkilökuntaa sekä projekteja.

Luokkien väliset suhteet näkyvät alla olevassa kuvassa.

Luokkien väliset suhteet

Luokasta A luokkaan B on piirretty nuoli, jos luokka A tuntee luokan B. Tällöin luokan A attribuuttina on luokan B ilmentymä (tai osoitin siihen). Luokka Cli ja moduuli Utils on jätetty kuvasta pois, koska ne ovat apumoduuleja, eivätkä varsinaisesti kuulu yritysjärjestelmään. Nuolten päälle on tarvittaessa kirjoitettu selvennys, joka voi auttaa ymmärtämään, miksi yhteys tarvitaan.

Kuvassa syntymäpäivänuoli on katkoviivalla, koska tällainen yhteys voisi hyvin luontevasti olla olemassa, mutta ohjelmassa tätä ei oikeasti käytetä.

Kuten edellä kerrottiin, sama työntekijä voi työskennellä useassa projektissa. Tästä syystä tarvitset osoittimia. Kukin työntekijä luodaan vain kerran, ja jos/kun työntekijää tarvitaan eri paikoissa, käytetään osoitinta kyseiseen työntekijään. Sama pätee projekteihin.

Yleistä asiaa komennoista

Ohjelmassa on aika monta komentoa (17), mutta sinun tehtävänäsi on toteuttaa vain noin puolet niistä (8).

Ohjelmalle ei anneta syötetiedostoa, joten alussa yritys on tyhjä, eli siellä ei ole henkilökuntaa eikä projekteja. Lisäykset (samoin kuin poistot) tehdään komennoilla. Komentojen joukossa on kuitenkin READ_FROM, joka lukee komennot annetusta tiedostosta (ks. komento 3 valmiiksi toteutetuista komennoista).

Ohjelman käynnistyessä sekä aina kun käyttäjältä odotetaan syötettä, tulostetaan rivin alkuun:

IT>

Tähän kehotteeseen ohjelman käyttäjä voi syöttää komentoja (tai vain painaa Enter-näppäintä). Komennot voidaan kirjoittaa isoilla tai pienillä kirjaimilla tai käyttää sekaisin isoja ja pieniä kirjaimia. Näin ollen lopetuskomennon sallittuja muotoja ovat esimerkiksi QUIT, quit ja Quit. Komennoilla on myös muutaman kirjaimen pituiset lyhenteet, jotka on kerrottu HELP-komennon yhteydessä. Esimerkiksi lopetuskomennon lyhenne on Q (tai pienellä kirjoitettuna q).

Kullakin komennolla on määrätty määrä parametreja. Parametrit näkyvät kunkin komennon kuvauksessa kulmasulkujen sisällä. Jos parametri koostuu useammasta sanasta, se pitää kirjoittaa lainausmerkkien sisään. Jos parametreja on liikaa tai liian vähän, tulostetaan virheilmoitus:

Error: Wrong amount of parameters.

Parametrien määrän tarkastaminen on toteutettu pohjakoodiin, joten siitä ei tarvitse huolehtia. Myös lainausmerkkien käsittely on toteutettu valmiiksi.

Jos käyttäjä antaa jonkin muun komennon kuin ohjelman tunteman, tulostetaan virheilmoitus:

IT> xxx
Error: Unknown commands given.
IT>
IT>

Kun käyttäjän syöttämä komento on suoritettu, ohjelma tulostaa kehotteen uudelleen. Tätä jatketaan kunnes käyttäjä syöttää komennon QUIT.

Jos käyttäjä pelkästään painaa Enter-näppäintä antamatta mitään komentoa, kehote tulostuu uudelleen, kuten näkyy viimeisimmässä esimerkissä. Tässä mielessä ohjelma toimii kuten Linux-etätyöpöydän komentorivi.

Seuraavissa kahdessa osiossa on ensin kuvattu toteutetut komennot ja sen jälkeen toteutettavat kommennot. Luonnollisesti ensimmäistä näistä osioista ei tarvitse lukea kovin tarkkaan, koska riittää osata käyttää komentoja. Jälkimmäinen osio taas tulee lukea tarkasti, koska tehtäväsi on toteuttaa nämä komennot.

Toteutetut komennot virheilmoituksineen

  1. QUIT - Ohjelman suoritus päätty paluuarvoon EXIT_SUCCESS ilman, että ohjelma tulostaa mitään. Komennolla ei ole parametreja, mutta jos käyttäjä antaa parametreja, niitä ei huomioida.

  2. HELP - Komento tulostaa kaikki käytössä olevat ole komennot lyhenteineen. Kullakin rivillä näkyy ensin komennon kuvaus ja kaksoispisteen jälkeen komento ja sen lyhenne:

    IT> HELP
    Quit : QUIT Q
    Help : HELP H
    Read : READ_FROM RF
    Set date : SET_DATE SD
    Advance date : ADVANCE_DATE AD
    Recruit staff : RECRUIT R
    Resign employee from company : LEAVE L
    Add skill for an employee : ADD_SKILL AS
    Print current staff : PRINT_CURRENT_STAFF PCS
    Create a new project : CREATE_PROJECT CR
    Close a project : CLOSE_PROJECT CL
    Print all projects : PRINT_PROJECTS PP
    Add requirement for a project : ADD_REQUIREMENT AR
    Assign employee for a project : ASSIGN A
    Print project's info : PRINT_PROJECT_INFO PPI
    Print employee's info : PRINT_EMPLOYEE_INFO PEI
    Print active staff : PRINT_ACTIVE_STAFF PAS
    IT>
    IT> HELP AS
    Add skill for an employee : ADD_SKILL AS
    Params:
    employee id
    skill name
    IT>
    

    Komennolla on yksi optionaalinen parametri. Jos parametria ei anneta, komento tulostaa tiedot kaikista komennoista. Jos parametriksi annetaan jokin komento, HELP-komento tulostaa tarkemmat tiedot annetusta komennosta.

  3. READ_FROM <tiedosto> - Komennolla voidaan lukea annetusta tiedostosta komennot parametreineen, mikä voi helpottaa ohjelman testaamista. Pohjakoodien mukana saat tiedoston assignment.txt, joka sisältää esimerkkiajoissa esiintyneitä komentoja. Tiedostossa on käytetty komentojen lyhenteitä. Tiedoston sisältö on seuraava:

    r "Teemu Teekkari"
    l "Teemu Teekkari"
    r "Teemu Teekkari"
    as "Teemu Teekkari" C++
    cr Checkers
    ad 3
    ar Checkers Git
    cl Checkers
    cr Theatre
    a "Teemu Teekkari" Theatre
    q
    

    Kyseinen tiedosto voidaan antaa lukukomennolle parametrina seuraavasti:

    IT> READ_FROM assignment.txt
    Input read from file: assignment.txt
    IT>
    

    Tällä tavalla saat suoritettua kaikki tiedoston sisältämät onnistuneet komennot nopeammin, kuin jos kirjoittaisit ne yksitellen kehotteen jälkeen.

    Huomaa, että tiedosto assignment.txt sisältää myös sellaisia komentoja, joita ei ole toteutettu pohjakoodissa.

    Jos tiedostossa oleva komento on virheellinen, esimerkiksi parametreja on väärä määrä, mitään virheilmoitusta ei tulostu, kuten komentoriviltä tulostuisi. Lisäksi tiedostossa täytyy olla viimeisenä komentona QUIT (tai sen lyhenne), sillä muuten tiedoston lukeminen ei lopu koskaan. Noudata siis edellä kerrottuja ohjeita, jos käytät itse kirjoittamaasi syötetiedostoa testatessasi ohjelmaa. Ohjelman testaaminen (tavalla tai toisella) on erittäin suositeltavaa.

    Jos komennon parametriksi annetaan tuntematon tiedosto, tulostetaan virheilmoitus:

    IT> READ_FROM ei_loydy.txt
    Error: Can't read given file.
    

    Tämän jälkeen ohjelman toiminta päättyy paluuarvoon EXIT_SUCCESS.

  4. SET_DATE <pp> <kk> <vvvv> - Komennolla voidaan asettaa uudeksi päivämääräksi päivämäärä pp.kk.vvvv. (Nykyiseksi päivämääräksi on asetettu 1.9.2023 tiedostossa utils.hh, ja halutessasi voit muuttaa sitä myös koodiin, mutta tämä komento hoitaa saman asian.) Komennolla on kolme kokonaislukuparametria. Jos päivä (tai kuukausi) on numeroltaan 1, se voidaan antaa joko muodossa 1 tai 01, ja sama pätee muihin 1-numeroisiin lukuihin. Esimerkiksi:

    IT> SET_DATE 2 09 2023
    Date has been set to 2.9.2023
    IT>
    

    Jos parametriksi annetaan liian suuri luku, joka ei sovi päiväksi tai kuukaudeksi, kyseiseksi luvuksi asetetaan 1. Esimerkiksi:

    IT> SET_DATE 32 13 2023
    Date has been set to 1.1.2023
    IT>
    

    Jos jokin parametreista on jotakin muuta kuin positiivinen kokonaisluku, ohjelma tulostaa virheilmoituksen:

    IT> SET_DATE 1 3 ww
    Error: Wrong type of parameters.
    IT>
    
  5. ADVANCE_DATE <ei-negatiivinen kokonaisluku> - Komennolla voidaan siirtää nykyistä päivämäärää (1.9.2023) parametrina annetun ei-negatiivisen kokonaisluvun verran päiviä eteenpäin. Jos komennolle antaa parametriksi nollan, saa selville nykyisen päivämäärän:

    IT> ADVANCE_DATE 0
    New date is 1.9.2023
    IT>
    

    Jos parametriksi annetaan positiivinen luku, päivämäärä siirtyy yhtä monta päivää eteenpäin:

    IT> ADVANCE_DATE 7
    New date is 8.9.2023
    IT>
    

    Jos parametriksi annetaan negatiivinen kokonaisluku, tulostetaan virheilmoitus:

    IT> ADVANCE_DATE -1
    Error: Wrong type of parameters.
    IT>
    
  6. RECRUIT <id> - Komennolla voidaan palkata yritykseen uusi työntekijä. Parametrina annetaan tunniste, esimerkiksi nimi. (Annettua tunnistetta käytetään parametrina muissa komennoissa.) Esimerkki henkilökunnan lisäämisestä:

    IT> RECRUIT "Teemu Teekkari"
    A new employee has been recruited.
    IT> RECRUIT "Teemu Teekkari"
    Error: Already exists: Teemu Teekkari
    IT>
    

    Yllä näkyy myös virheilmoitus, joka tulostetaan, jos samanniminen henkilö on henkilökunnassa jo ennestään.

    Jos kuitenkin työntekijä lähtee yrityksestä, hänet voidaan lisätä myöhemmin uudelleen, mikä näkyy seuraavan komennon esimerkissä.

  7. LEAVE <id> - Komennolla työntekijä voi irtisanoutua yrityksestä. Komento ei kuitenkaan poista työntekijää niiden projektien tiedoista, joissa työntekijä on työskennellyt. (Tämä tieto jää ikään kuin historiatiedoksi.) Esimerkiksi:

    IT> LEAVE "Teemu Teekkari"
    Employee left company.
    IT> LEAVE "Teemu Teekkari"
    Error: Can't find anything matching: Teemu Teekkari
    IT> RECRUIT "Teemu Teekkari"
    A new employee has been recruited.
    IT>
    

    Yllä näkyy myös virheilmoitus, joka tulostetaan, jos parametrina annettua työntekijää ei löydy. Työntekijää ei löydy, jos hän on jo irtisanoutunut aiemmin. Irtisanoutumisen jälkeen työntekijä voidaan lisätä uudelleen, ja hänelle aikaisemman työsuhteen aikana lisätyt taidot säilyvät. (Tämä näkyy esimerkiksi myöhemmin esiteltävän komennon PRINT_EMPLOYEE_INFO kohdalla seuraavassa osiossa.)

  8. ADD_SKILL <id> <taito> - Komennolla voidaan lisätä työntekijälle uusi taito. Jos työntekijällä on annettu taito jo ennestään, komento ei tee mitään, ei siis myöskään anna mitään virheilmoitusta:

    IT> ADD_SKILL "Teemu Teekkari" C++
    Skill added for: Teemu Teekkari
    IT> ADD_SKILL "Teemu Teekkari" C++
    Skill added for: Teemu Teekkari
    IT> ADD_SKILL xx C++
    Error: Can't find anything matching: xx
    IT> LEAVE "Teemu Teekkari"
    Employee left company.
    IT> ADD_SKILL "Teemu Teekkari" Python
    Error: Can't find anything matching: Teemu Teekkari
    IT>
    

    Yllä näkyy myös virheilmoitus, joka tulostetaan, jos parametrina annettua työntekijää ei löydy. Irtisanoutuneelle työntekijälle ei voida lisätä taitoja.

  9. PRINT_CURRENT_STAFF - Komento tulostaa yrityksen nykyisen henkilökunnan, eli rekrytoidut työntekijät, mutta ei irtisanoutuneita. Työntekijöiden tunnisteet tulostetaan allekkain aakkosjärjestyksessä. Jos työntekijöitä ei ole yhtään, tulostetaan None. Esimerkiksi:

    IT> PRINT_CURRENT_STAFF
    None
    IT> RECRUIT "Teemu Teekkari"
    A new employee has been recruited.
    IT> RECRUIT "Aatu Arkkari"
    A new employee has been recruited.
    IT> RECRUIT "Essi Esimerkki"
    A new employee has been recruited.
    IT> LEAVE "Essi Esimerkki"
    Employee left company.
    IT> PRINT_CURRENT_STAFF
    Aatu Arkkari
    Teemu Teekkari
    IT>
    

Toteutettavat komennot virheilmoituksineen

  1. CREATE_PROJECT <id> - Komennolla voi lisätä uuden projektin yritykseen. Parametrina annetaan tunniste, esimerkiksi projektin nimi. (Annettua tunnistetta käytetään parametrina muissa komennoissa.) Esimerkki projektin lisäämisestä:

    IT> CREATE_PROJECT Checkers
    A new project has been created.
    IT> CREATE_PROJECT Checkers
    Error: Already exists: Checkers
    IT>
    

    Yllä näkyy myös virheilmoitus, joka tulostetaan, jos samanniminen projekti on olemassa jo ennestään. Virheilmoitus annetaan kaikista joskus (saman ajon aikana) luoduista projekteista, vaikka kyseinen projekti olisi suljettu.

    Tunnisteen lisäksi uudelle projektille asetetaan aloituspäiväksi Utils-moduulin today-muuttujan sen hetkinen arvo.

  2. CLOSE_PROJECT <id> - Komennolla voi sulkea projektin. Sulkeminen tarkoittaa, että projektille asetetaan päättymispäiväksi Utils-moduulin today-muuttujan sen hetkinen arvo. Projektin tiedot (id, henkilökunta, vaatimukset, päivämäärät) kuitenkin säilytetään. Esimerkiksi:

    IT> CLOSE_PROJECT Checkers
    Project closed.
    IT> CLOSE_PROJECT Checkers
    Project closed.
    IT> CREATE_PROJECT Checkers
    Error: Already exists: Checkers
    IT> CLOSE_PROJECT xx
    Error: Can't find anything matching: xx
    IT>
    

    Edellä nähdään, että saman projektin voi sulkea useita kertoja (koska suljettavan projektin tiedot säilyvät). Uusi sulkeminen ei tee mitään, edes sulkemispäivä ei muutu. Suljettua projektia ei voi kuitenkaan luoda uudelleen. Jos komennolle annetaan parametrina sellainen projekti, jota ei ole koskaan luotukaan, tulostetaan yllä näkyvä virheilmoitus.

    Tietojen säilyminen näkyy komennon PRINT_PROJECT_INFO kohdalla vähän jäljempänä.

  3. PRINT_PROJECTS - Komento tulostaa kaikki projektit siinä järjestyksessä, kuin ne on luotu. Kustakin projektista tulostetaan tunniste ja aloituspäivä. Suljetuista projekteista tulostetaan myös sulkemispäivä. Jos yhtäkään projektia ei ole vielä luotu, komento tulostaa tekstin None. Tulostuksen tarkempi muoto tulee ilmi esimerkistä:

    IT> PRINT_PROJECTS
    None
    IT> CREATE_PROJECT Checkers
    A new project has been created.
    IT> CREATE_PROJECT Theatre
    A new project has been created.
    IT> ADVANCE_DATE 3
    New date is 4.9.2023
    IT> CLOSE_PROJECT Checkers
    Project closed.
    IT> CREATE_PROJECT GUI-project
    A new project has been created.
    IT> PRINT_PROJECTS
    Checkers : 1.9.2023 - 4.9.2023
    Theatre : 1.9.2023 -
    GUI-project : 4.9.2023 -
    IT>
    
  4. ADD_REQUIREMENT <id> <vaatimus> - Komennolla voidaan lisätä projektille uusi vaatimus. Jos projektilla on annettu vaatimus jo ennestään, komento ei tee mitään, ei siis myöskään anna mitään virheilmoitusta:

    IT> CREATE_PROJECT Checkers
    A new project has been created.
    IT>
    IT> ADD_REQUIREMENT Checkers Git
    Requirement added for: Checkers
    IT> ADD_REQUIREMENT Checkers Git
    Requirement added for: Checkers
    IT> ADD_REQUIREMENT xx Git
    Error: Can't find anything matching: xx
    IT> CLOSE_PROJECT Checkers
    Project closed.
    IT> ADD_REQUIREMENT Checkers C++
    Error: Can't find anything matching: Checkers
    IT>
    

    Yllä näkyy myös virheilmoitus, joka tulostetaan, jos parametrina annettua projektia ei löydy. Suljetulle projektille ei voi lisätä vaatimuksia.

    Projektin vaatimusten ja projektin työntekijöiden taitojen pitää vastata toisiaan niin, että projektiin palkattavalla työntekijällä pitää olla ainakin yksi sellainen taito, joka löytyy projektin vaatimuksista. (Tämä tarkistetaan seuraavaksi esiteltävän ASSIGN-komennon kohdalla, tosin kyseistä komentoa käytetään jo alla olevassa esimerkissä.)

    On kuitenkin mahdollista, että projektille lisätään uusia vaatimuksia sen jälkeen, kun siihen on otettu työntekijöitä. Jos tällöin käy niin, että vaatimuksen lisäämisen jälkeen jollakin projektissa työskentelevällä ei ole yhtäkään projektin vaatimaa taitoa, niin työntekijä poistetaan projektista. (Tällainen tilannehan on mahdollinen vain silloin, jos projektilla ei ennestään ole yhtään vaatimusta, eli jos sille ollaan lisäämässä ensimmäistä vaatimusta.) Esimerkiksi:

    IT>
    IT> RECRUIT "Teemu Teekkari"
    A new employee has been recruited.
    IT> CREATE_PROJECT Theatre
    A new project has been created.
    IT> ASSIGN "Teemu Teekkari" Theatre
    Staff assigned for: Theatre
    IT> ADD_REQUIREMENT Theatre Git
    Not qualified any more: Teemu Teekkari
    Requirement added for: Theatre
    IT>
    IT> RECRUIT "Aatu Arkkari"
    A new employee has been recruited.
    IT> CREATE_PROJECT GUI-project
    A new project has been created.
    IT> ASSIGN "Teemu Teekkari" GUI-project
    Staff assigned for: GUI-project
    IT> ASSIGN "Aatu Arkkari" GUI-project
    Staff assigned for: GUI-project
    IT> ADD_REQUIREMENT GUI-project Qt
    Not qualified any more: Aatu Arkkari, Teemu Teekkari
    Requirement added for: GUI-project
    IT>
    IT> ADD_SKILL "Teemu Teekkari" Git
    Skill added for: Teemu Teekkari
    IT> ASSIGN "Teemu Teekkari" Theatre
    Staff assigned for: Theatre
    IT>
    

    Kuten edellä näkyy, epäpätevät työntekijät luetellaan aakkosjärjestyksessä yhdellä rivillä pilkulla eroteltuina. Edellä näkyy myös, että sen jälkeen, kun työntekijälle on lisätty vaadittava taito, hänet voidaan lisätä projektiin uudelleen.

    (Myöhemmin esiteltävä komento PRINT_PROJECT_INFO tulostaa vaatimukset aakkosjärjestyksessä.)

  5. ASSIGN <työntekijän id> <projektin id> - Komennolla voidaan sijoittaa annettu työntekijä työskentelemään annetussa projektissa. Kuten edellisen komennon kohdalla mainittiin, sijoitettavalla työntekijällä pitää olla ainakin yksi sellainen taito, joka löytyy projektin vaatimuksista. Jos projektilla ei ole mitään vaatimuksia, sijoitettavalta työntekijältäkään ei vaadita mitään taitoja. Esimerkiksi:

    IT> RECRUIT "Teemu Teekkari"
    A new employee has been recruited.
    IT> CREATE_PROJECT Checkers
    A new project has been created.
    IT> ADD_REQUIREMENT Checkers Git
    Requirement added for: Checkers
    IT> ASSIGN "Teemu Teekkari" Checkers
    Error: Can't assign: Teemu Teekkari
    IT> ADD_SKILL "Teemu Teekkari" Git
    Skill added for: Teemu Teekkari
    IT> ASSIGN "Teemu Teekkari" Checkers
    Staff assigned for: Checkers
    IT> ASSIGN "Teemu Teekkari" Checkers
    Error: Can't assign: Teemu Teekkari
    IT>
    

    Yllä olevassa esimerkissä näkyy, miten sijoitettavalla työntekijällä ei ensin ole vaadittua taitoa. Taidon lisäämisen jälkeen hänet voidaan ottaa projektiin. Onnistuneen sijoittamisen jälkeen samaa työntekijää ei voi kuitenkaan sijoittaa uudelleen samaan projektiin.

    Suljettuun projektiin ei voida sijoittaa työntekijöitä (oletetaan, että edellisen esimerkin komennot on tehty):

    IT>
    IT> CREATE_PROJECT Theatre
    A new project has been created.
    IT> CLOSE_PROJECT Theatre
    Project closed.
    IT> ASSIGN "Teemu Teekkari" Theatre
    Error: Can't assign: Teemu Teekkari
    IT>
    

    Huomaa, että yllä näkyvä virheilmoitus voi tulla kolmessa tapauksessa: projekti on suljettu, työntekijältä puuttuu vaadittava taito, tai työntekijä yritetään lisätä samaan projektiin, jossa hän on jo ennestään.

    Jos parametrina annettavaa työntekijää tai projektia ei löydy, tulostetaan virheilmoitus (oletetaan, että kahden edellisen esimerkin komennot on tehty):

    IT>
    IT> ASSIGN xx Checkers
    Error: Can't find anything matching: xx
    IT> ASSIGN "Teemu Teekkari" yy
    Error: Can't find anything matching: yy
    IT> ASSIGN xx yy
    Error: Can't find anything matching: xx
    IT>
    

    Huomaa, että virheilmoitus annetaan vain ensimmäisestä tunnistamattomasta parametrista.

  6. PRINT_PROJECT_INFO <id> - Komento tulostaa tiedot annetusta projektista: aloituspäivän, vaatimukset ja työntekijät. Suljetusta projektista tulostetaan myös sulkemispäivä. Vaatimukset ja työntekijät tulostetaan aakkosjärjestyksessä, kummatkin yhdelle riville pilkulla eroteltuna seuraavasti. Jos vaatimuksia tai työntekijöitä ei ole, niiden kohdalle tulostetaan None. Tarkempi tulostusmuoto näkyy esimerkissä:

    IT> CREATE_PROJECT Checkers
    A new project has been created.
    IT> PRINT_PROJECT_INFO Checkers
    Checkers : 1.9.2023 -
    ** Requirements: None
    ** Staff: None
    IT> ADD_REQUIREMENT Checkers Git
    Requirement added for: Checkers
    IT> ADD_REQUIREMENT Checkers C++
    Requirement added for: Checkers
    IT> RECRUIT "Teemu Teekkari"
    A new employee has been recruited.
    IT> ADD_SKILL "Teemu Teekkari" Git
    Skill added for: Teemu Teekkari
    IT> RECRUIT "Aatu Arkkari"
    A new employee has been recruited.
    IT> ADD_SKILL "Aatu Arkkari" C++
    Skill added for: Aatu Arkkari
    IT> ASSIGN "Teemu Teekkari" Checkers
    Staff assigned for: Checkers
    IT> ASSIGN "Aatu Arkkari" Checkers
    Staff assigned for: Checkers
    IT> PRINT_PROJECT_INFO Checkers
    Checkers : 1.9.2023 -
    ** Requirements: C++, Git
    ** Staff: Aatu Arkkari, Teemu Teekkari
    IT> ADVANCE_DATE 3
    New date is 4.9.2023
    IT> CLOSE_PROJECT Checkers
    Project closed.
    IT> PRINT_PROJECT_INFO Checkers
    Checkers : 1.9.2023 - 4.9.2023
    ** Requirements: C++, Git
    ** Staff: Aatu Arkkari, Teemu Teekkari
    IT> LEAVE "Teemu Teekkari"
    Employee left company.
    IT> PRINT_PROJECT_INFO Checkers
    Checkers : 1.9.2023 - 4.9.2023
    ** Requirements: C++, Git
    ** Staff: Aatu Arkkari, Teemu Teekkari
    IT>
    IT> PRINT_PROJECT_INFO xx
    Error: Can't find anything matching: xx
    IT>
    

    Yllä näkyy myös virheilmoitus, joka tulostetaan, jos parametrina annettua projektia ei löydy. Samoin siinä näkyy, että projektin tiedot säilyvät sulkemisen jälkeen sekä projektin työntekijän irtisanoutumisen jälkeen.

  7. PRINT_EMPLOYEE_INFO <id> - Komento tulostaa työntekijän tiedot: taidot ja projektit, joissa hän työskentelee tai on työskennellyt. Taidot luetellaan aakkosjärjestyksessä samalla rivillä pilkulla eroteltuina. Projektit luetellaan kukin omalla rivillään siinä järjestyksessä, kuin työntekijä on niihin sijoitettu. Kustakin projektista tulostetaan alkamispäivä, ja päättyneistä projekteista myös päättymispäivä. Jos taitoja tai projekteja ei ole, niiden kohdalle tulostetaan None. Tarkempi tulostusmuoto näkyy esimerkissä:

    IT> RECRUIT "Teemu Teekkari"
    A new employee has been recruited.
    IT> PRINT_EMPLOYEE_INFO "Teemu Teekkari"
    Skills: None
    Projects: None
    IT>
    IT> CREATE_PROJECT Checkers
    A new project has been created.
    IT> CREATE_PROJECT Theatre
    A new project has been created.
    IT> CREATE_PROJECT GUI-project
    A new project has been created.
    IT> ASSIGN "Teemu Teekkari" Theatre
    Staff assigned for: Theatre
    IT> ADD_SKILL "Teemu Teekkari" Python
    Skill added for: Teemu Teekkari
    IT> PRINT_EMPLOYEE_INFO "Teemu Teekkari"
    Skills: Python
    Projects:
    ** Theatre : 1.9.2023 -
    IT>
    IT> ADD_SKILL "Teemu Teekkari" C++
    Skill added for: Teemu Teekkari
    IT> ADVANCE_DATE 3
    New date is 4.9.2023
    IT> CLOSE_PROJECT Theatre
    Project closed.
    IT> ASSIGN "Teemu Teekkari" GUI-project
    Staff assigned for: GUI-project
    IT> PRINT_EMPLOYEE_INFO "Teemu Teekkari"
    Skills: C++, Python
    Projects:
    ** Theatre : 1.9.2023 - 4.9.2023
    ** GUI-project : 1.9.2023 -
    IT>
    IT> PRINT_EMPLOYEE_INFO xx
    Error: Can't find anything matching: xx
    IT> LEAVE "Teemu Teekkari"
    Employee left company.
    IT> PRINT_EMPLOYEE_INFO "Teemu Teekkari"
    Error: Can't find anything matching: Teemu Teekkari
    IT> RECRUIT "Teemu Teekkari"
    A new employee has been recruited.
    IT> PRINT_EMPLOYEE_INFO "Teemu Teekkari"
    Skills: C++, Python
    Projects:
    ** Theatre : 1.9.2023 - 4.9.2023
    ** GUI-project : 1.9.2023 -
    IT>
    

    Yllä näkyy myös virheilmoitus, joka tulostetaan, jos parametrina annettua työntekijää ei löydy. Työntekijää ei löydy silloinkaan, jos hän on irtisanoutunut. Kuitenkin jos hän palaa yritykseen, hänen tietonsa (taidot, projektit) säilyvät työsuhteiden välillä.

  8. PRINT_ACTIVE_STAFF - Komento tulostaa kaikki aktiiviset työntekijät eli sellaiset, jotka työskentelevät tai ovat työskennelleet jossakin projektissa. Aktiiviset työntekijät tulostetaan tunnisteen (id) mukaisessa aakkosjärjestyksessä kukin omalle rivilleen. Jos yrityksessä ei ole yhtään aktiivista työntekijää, tulostetaan None:

    IT> RECRUIT "Teemu Teekkari"
    A new employee has been recruited.
    IT> RECRUIT "Aatu Arkkari"
    A new employee has been recruited.
    IT> CREATE_PROJECT Checkers
    A new project has been created.
    IT> PRINT_ACTIVE_STAFF
    None
    IT> ASSIGN "Teemu Teekkari" Checkers
    Staff assigned for: Checkers
    IT> PRINT_ACTIVE_STAFF
    Teemu Teekkari
    IT> CLOSE_PROJECT Checkers
    Project closed.
    IT> PRINT_ACTIVE_STAFF
    Teemu Teekkari
    IT> LEAVE "Teemu Teekkari"
    Employee left company.
    IT> PRINT_ACTIVE_STAFF
    Teemu Teekkari
    IT> PRINT_CURRENT_STAFF
    Aatu Arkkari
    IT>
    IT> RECRUIT "Essi Esimerkki"
    A new employee has been recruited.
    IT> CREATE_PROJECT Theatre
    A new project has been created.
    IT> ASSIGN "Essi Esimerkki" Theatre
    Staff assigned for: Theatre
    IT> PRINT_ACTIVE_STAFF
    Essi Esimerkki
    Teemu Teekkari
    IT>
    

Ohjelman moduulit

Koodipohja koostuu pääohjelmamoduulista sekä kuudesta muusta moduulista. Pääohjelmamoduuli on hyvin yksinkertainen. Se vain käynnistää komentotulkin (command line interpreter, CLI), joka pyörii niin kauan kuin käyttäjä antaa komennon QUIT. Pääohjelmaa ei ole tarpeen muuttaa.

Ohjelmaan kuuluu moduuli Utils, joka ei ole luokka vaan nimiavaruus. Se tarjoaa tutun apufunktion split, funktion is_numeric sekä päivämäärän today. Päivämäärän arvoa voit halutessasi päivittää tiedostosta utils.hh. Tällä hetkellä päivämääränä on 1.9.2023. Muilta osin tätä moduulia ei ole tarpeen muuttaa. Päivämäärää voi muuttaa myös komennolla SET_DATE.

Komentotulkki eli luokka Cli on määritelty ja toteutettu tiedostoissa cli.hh ja cli.cpp. Luokka on annettu koodipohjassa valmiina, eikä siihen tarvitse tehdä muutoksia. Luokan tehtävänä on tunnistaa komennot käyttäjän syötteistä. Kaikki komennot toteutetaan luokassa Company. Komentotulkin otsikkotiedostossa on komentovektori, joka sisältää funktio-osoittimia. Sen perusteella näet missä Company-luokan jäsenfunktiossa mikäkin komento on toteutettu. Muilta osin komentotulkin toimintaa ei ole välttämätöntä ymmärtää. Erityisesti funktio-osoittimien osaamista/ymmärtämistä ei vaadita.

Luokka Date kuvaa päivämääriä. Kukin päivämäärän osa (päivä, kuukausi, vuosi) on esitetty kokonaislukuna. Päivämäärää voidaan siirtää parametrina saadun päivälukumäärän verran eteenpäin metodilla advance. Metodi is_default kertoo, onko päivämäärä oletuspäivämäärä eli päivämäärä, jossa päivän, kuukauden ja vuoden arvot ovat nollia. Jos projekti ei ole vielä päättynyt, sen loppupäivämäärä on oletuspäivämäärä. Metodia is_default voi siis käyttää selvittämään, onko projekti päättynyt. Lisäksi Date-luokassa on metodit päivämäärän asettamiseen ja tulostamiseen. Päivämäärien yhtäsuuruutta voidaan vertailla. Luokalla on myös <-operaattori: päivämäärä a on pienempi kuin päivämäärä b, jos a edeltää päivämäärää b. (Vertailuoperaattorifunktioille ei nykyisessä koodissa ole käyttöä.) Luokkaan Date ei tarvitse tehdä muutoksia.

Luokka Employee kuvaa työntekijää. Työntekijä tunnistetaan attribuutin id_ avulla. Edellä olevissa esimerkeissä tunnisteina käytettiin nimiä. Tällöin työntekijöillä pitää olla yksikäsitteiset nimet. Luokalla Employee on myös attribuutti date_of_birth_, mutta sitä ei välttämättä tarvittaisi. Luokkaa Employee ei välttämättä tarvitse muuttaa, mutta voit lisätä sinne metodeita, joita kutsut muihin luokkiin toteuttamistasi metodeista, jos lisättävät metodit loogisesti kuuluvat kyseiseen luokkaan.

Ohjelmassa on myös luokka Project, joka kuvaa projektia. Luokan toteuttaminen on jätetty sinun tehtäväksesi.

Luokka Company kuvaa yritystä (joita yleisesti voisi olla useitakin mutta joita tässä ohjelmassa on vain yksi). Yritys voisi olla minkä alan yritys tahansa, mutta tämän tehtävänannon esimerkeissä sen on ajateltu olevan IT-yritys. Luokassa on tiedot kaikista yrityksen henkilöistä ja projekteista. Näitä tietoja varten luokassa on säiliöt, joihin tallennetaan uusia alkioita käyttäjän komentojen perusteella. Kaikki komennot toteutetaan tässä luokassa, mutta komentometodeista voidaan kutsua muiden luokkien metodeita.

Huomaa, että työntekijä voi työskennellä useissa projekteissa, ja projektissa voi olla useita työntekijöitä. Tällaisissa tapauksissa luodaan vain yksi Employee-olio, johon on osoittimet useasta eri paikasta (tietorakenteesta). Tällaisessa tilanteessa osoittimet ovat välttämättömiä. Samoin yhteen Project-olioon voi olla osoittimia useista eri paikoista.

Moduulien (luokkien) väliset suhteet tulevat ilmi tehtävänannon alussa esitetystä kuvasta.

Tarkempi tehtävänanto

Tehtävänäsi on täydentää luokat Company ja Project niin, että komennot toimivat edellä kuvatulla tavalla. Muitakin luokkia saat muuttaa tarpeen mukaan. Voit ehkä kokea tarpeelliseksi lisätä johonkin luokkaan uusia metodeja. Useimmat tietorakenteet on annettu valmiina.

Luokka Project on melkein kokonaan tyhjä, ja sen saat suunnitella ja toteuttaa kokonaan itse. Luokasta Company puuttuu toteutukset metodeille:

  • create_project
  • close_project
  • print_projects
  • add_requirement
  • assign
  • print_project_info
  • print_employee_info
  • print_active_staff.

Kunkin näistä on tarkoitus toteuttaa samanniminen puuttuva komento. Myös muita apufunktioita saa toteuttaa ja lisätä attribuutteja.

Huomaa erityisesti, että Company-luokan purkaja ei ole valmis, vaan sinun tulee täydentää sitä.

Koodi (esimerkiksi tulostuskoodi) kannattaa sijoittaa siihen luokkaan, jonka tietoja käsitellään (tulostetaan). Esimerkiksi tulostusketju voi lähteä jostakin “isommasta” luokasta, joka ehkä itse tulostaa jotakin ja pyytää sitten osiaan tulostamaan osuutensa. Tässä isommalla luokalla tarkoitetaan luokkaa, jolla on osinaan (attribuutteinaan) toisten luokkien ilmentymiä.

Tehtävää tehdessäsi kannattaa juurikin kiinnittää huomiota siihen, miten toisen luokan ilmentymät (oliot tai osoittimet niihin) voivat olla toisen luokan attribuutteina.

Monien komentofunktioiden (komennon toteuttava metodi) parametrina on params, jonka tyyppinä on Params. Kyseessä on vektori, jonka määrittely on tiedostossa company.hh. Parametrien määrät tarkistetaan Cli-luokan exec-metodissa, joten kaikissa toteutettavissa funktioissa voit olettaa, että params-vektorissa on juuri sen verran alkioita, kuin kyseinen komento vaatii.

Joillakin komennoilla ei ole lainkaan parametreja, jolloin vastaavat komentofunktiot eivät käytä saamaansa params-parametria. Silloin tämän parametrin nimi on jätetty pois. Tyyppiä ei kuitenkaan voi jättää pois, sillä funktiota on kutsuttu funktio-osoittimen kautta. Kaikilla samantyyppisen funktio-osoittimen kautta kutsutuilla funktioilla täytyy olla sama määrä samantyyppisiä parametreja. Kaikki tämä on kuitenkin toteutettu pohjakoodiin, joten asiasta ei tarvitse huolehtia. Tehtävän tekeminen ei siis vaadi funktio-osoittimien osaamista.

Vihjeitä

  • Aloita tutustumalla valmiiseen koodiin. Annettua koodia ei kuitenkaan tarvitse ymmärtää perin pohjin. Ei haittaa, vaikka et ymmärtäisi luokan Cli koodia. Muista luokista kannattaa tutkia, mitä metodeja ne tarjoavat (julkiset metodit) ja mitä attribuutteja niillä on. Tutustu metodien toteutusten yksityiskohtiin vasta, jos/kun huomaat tarvitsevasi kyseisten yksityiskohtien tuntemusta. Useimmissa tapauksissa riittää, että päättelet metodin tekemän toiminnon sen nimestä.
  • Ennen ohjelman toteuttamista, mieti huolellisesti, miten rakennat ohjelman niin, että pystyt vastaamaan annettuihin vaatimuksiin.
  • Tässä projektissa pääpaino on modulaarisuudella sekä osoittimilla. Joudut kuitenkin lisäämään pari STL-säiliötä, mutta niiden valinnan ei pitäisi tuottaa hankaluuksia enää tässä vaiheessa.
    • Mikä olisi sopiva säiliö yrityksen projekteille, kun projektit halutaan käydä läpi lisäysjärjestyksessä?
    • Mikä olisi sopiva säiliö projektin henkilökunnalle, kun henkilökunnan jäsenet halutaan tulostaa aakkosjärjestyksessä?
  • Huomaa, että luokan sisäiset const-funktiot eivät voi kutsua funktioita, joista puuttuu määre const. Sanan const puuttuminen aiheuttaa kääntäjässä [-fpermissive]-virheen. Eli funktio, jota on kielletty muuttamasta olion tilaa, ei saa kutsua funktioita, jotka voivat muokata olion tilaa.
  • Muista, että oletuksena ohjelma käännetään build-hakemistoon. Testaamista varten kannattaa siirtää mahdolliset syötetiedostot tähän samaan hakemistoon.

Ohjelman toteuttaminen osissa

Tässä vaiheessa kurssia pitäisi jo olla muodostunut riittävän hyvä käsitys siitä, millaisissa osissa ohjelmia kannattaa toteuttaa ja millaisia committeja kannattaa tehdä.

Erityisvaatimukset

Seuraavia vaatimuksia on noudatettava, mikäli haluaa työstä hyväksytyn arvosanan:

  • Ohjelmassa pitää käyttää dynaamista muistinhallintaa, mutta siinä ei saa olla muistinhallintaan liittyviä virheitä. Kannattaa siis suorittaa valgrind. Osoittimina voit käyttää joko tavallisia osoittimia tai älykkäitä osoittimia tai molempia.
  • Vain STL-kirjaston säiliöt sallitaan, ei esim. Boost-kirjaston.

Arviointi

Jotta työ päätyisi assistenttien arvioitavaksi, sen pitää ensin läpäistä automaattitestit. Jos saat automaattitesteistä 0 pistettä, myös lopullinen pistemääräsi on 0, eikä työ mene assistenttien arvioitavaksi. Automaattitestit ajavat ohjelmallesi myös valgrindin, joten ohjelmasi ei läpäise testejä, jos siinä on muistinhallintaan liittyviä virheitä. Kannattaa siis ajaa valgrind jo ennen tehtävän palauttamista.

Assistentti arvioi ja pisteyttää automaattitestit läpäisseistä (= 1 p) sekä tehtävänannon erikoisvaatimukset täyttävistä töistä viimeisimmän Plussa-palautuksen, joka on tehty määräajan loppuun mennessä, seuraavien arviointikriteerien mukaan:

  • Ratkaisun yleisperiaate: 0-40 pistettä:
    • Tehtävän osaamistavoitteet on saavutettu.
    • Ohjelmakoodi on jaettu funktioita, luokkia ja/tai metodeita käyttäen loogisiksi kokonaisuuksiksi, jotka ovat sopivan pituisia.
    • Jos luokkia ja olioita on käytetty, ne on toteutettu olio-ohjelmoinnin periaatteita noudattaen (ks. 4-kierroksen Tyyliseikoista kohta Olio-ohjelmointi).
    • Tietorakenne ei sisällä toisteista eikä turhaa tietoa. Valittuja tietorakenteita on käytetty järkevästi.
    • Ohjelmakoodi ei sisällä turhaa toisteisuutta eikä muutakaan turhaa.
    • Ohjelmakoodi ei sisällä tarpeettomia rajoitteita tai oletuksia tai muita väkinäisiä ratkaisuita.
    • Ohjelmarakenteet on toteutettu helposti ymmärrettäviksi.
    • Ohjelmakoodissa ei ole käytetty globaaleja muuttujia (globaalit const-vakiot ovat OK).
    • Ohjelman toimintaa ei lopeteta exit-funktiota käyttäen.
    • Ohjelmassa ei ole muistinhallintaan liittyviä virheitä (suorita valgrind).
  • Ohjelmointityyli: -20-0 pistettä:
    • Muuttujat ja funktiot nimetty selkeästi ja kuvaavasti. Nimeämisessä on käytetty vain yhtä kieltä, ei esim. suomea ja englantia sekaisin.
    • Ohjelmassa on käytetty nimettyjä vakioita taikalukujen sijasta.
    • Ohjelmakoodi on asemoitu siististi.
    • Koodirivien pituus on enintään 80 merkkiä.
    • Jokaisen itse kirjoittamasi/editoimasi tiedoston alussa on kommentti, josta käy ilmi tiedoston tarkoitus, nimesi, opiskelijanumerosi ja muut tarvittavat tiedot. (Tarvittaessa katso mallia ensimmäisen projektin tehtävänannosta.)
    • Jokaisen funktion/metodin alussa (otsikkotiedostossa jos sellainen on olemassa) on kommentti, joka kuvaa sen toiminnan, paluuarvon ja parametrit.
    • Kommentteja on muutenkin tarpeellisissa kohdissa.
    • Kommentit liittyvät toteutettuun ohjelmaan eivätkä johonkin sen vanhempaan versioon.
    • Kaikki kommentit on kirjoitettu samalla kielellä (fi/en), mutta kommentoinnissa saa käyttää eri kieltä kuin muuttujien ym. nimissä.
    • Kaikki muuttujat on alustettu.
    • Kääntäjä ei anna koodia käännettäessä varoituksia.
  • Versionhallinnan käyttö: 0-10 pistettä:
    • Committeja on riittävä määrä.
    • Commit-viestien sisältö on selkeä ja kuvaava.

Huomaa yllä olevasta listasta, että tässä vaiheessa tyyliseikkojen oletetaan olevan opiskelijoilla hallussa. Enää et siis saa pisteitä tyylisääntöjen noudattamisesta, vaan niiden käyttämättä jättämisestä sakotetaan. Kannattaa siis tarkistaa, mitä tyyliasioista on kerrottu materiaalin kierroksilla 4 ja 10.

Huomautus arvioinnista

Automaattitesteillä tarkistetaan, toimiiko ohjelma. Assistentit taas kiinnittävät huomiota tyyliseikkoihin ym. yllä lueteltuihin kriteereihin. Periaatteessa on siis mahdollista, että täysin toimivasta ohjelmasta saa nolla pistettä, jos ohjelma ei täytä yllä lueteltuja vaatimuksia.

Erityisesti tyylivaatimuksista on kerrottu tämän kierroksen aikaisemmassa materiaaliosiossa.

Huomautus arvosteltavan työn versiosta

Arvosteluun otetaan ohjelman se versio, josta on tehty viimeisin onnistunut Plussa-palautus (määräaikaan mennessä). Onnistuneella palautuksella tarkoitetaan palautusta, joka on läpäissyt automaattitestit.

Ensimmäisen onnistuneen Plussa-palautuksen jälkeen haluat todennäköisesti vielä korjailla koodisi tyyliä (esim. lisätä kommentteja), jos vain palautusaikaa on vielä jäljellä.

Muista lopuksi kuitenkin tämä: Kun olet palauttanut viimeisen version Gittiin, palauta se vielä kerran Plussaan.

A+ esittää tässä kohdassa tehtävän palautuslomakkeen.