Skip to content

Instantly share code, notes, and snippets.

@juvuorin
Created April 28, 2021 05:25
Show Gist options
  • Save juvuorin/7a8b1f1ec32e41825e340d9189174c7a to your computer and use it in GitHub Desktop.
Save juvuorin/7a8b1f1ec32e41825e340d9189174c7a to your computer and use it in GitHub Desktop.
Koiramainen ohjelmointikisa 2021
/*
Koiramainen ohjelmointikisa - 2021 kisatehtävä
Osallistuja: Anssi K.
Viimeisin muutos: 11.3.2021
*/
/*
Koodin tarkoituksena on ottaa käyttäjän syötteenä tilinumero ja käsiteltävä summa.
Jotkut tilinumerot laukaisevat algoritmejä, jotka käsittelevät myös toisia tilejä.
Jos algoritmi käyttää toista tiliä, joka sisältää toista tiliä käyttävän algoritmin,
ei uusi algoritmiä sisältävä tili suorita algoritmiään. Näin estetään esimerkiksi
ikuiset loopit, jotka viittaavat toisiinsa.
*/
/*
Erikoiset ilmiöt ja algoritmit luvuilla 110, 111, 124, 400, 500, 666, 777 ja 800.
*/
//Sisällytetään tarvittavat kirjastot
#include <iostream>
#include <limits>
//namespacen määritys
using namespace std;
//globaalit muuttujat
bool useProgram = 1, byDevil = 0;
int tilinumero;
bool firstSevens = 0;
double rahaSumma;
double accountArr[800]= {};
//funktioiden alustus
void Welcome();
int AccountInput();
double MoneyInput();
bool ContinueCheck();
void AutomationCheck(int tili, double raha);
void AccountInitialize();
void EndProgram();
//main funktio
int main() {
//otetaan ääkköset käyttöön
setlocale(LC_ALL, "fin");
//Alustetaan automaatiotilit
AccountInitialize();
//Käyttäjän tervehtiminen
Welcome();
//"pääkierto"
while (useProgram) {
tilinumero = AccountInput();
rahaSumma = MoneyInput();
accountArr[tilinumero] += rahaSumma;
cout << "\nTilinumero:\tRahamäärä:\n";
cout << tilinumero << "\t\t" << accountArr[tilinumero] << endl;
AutomationCheck(tilinumero, rahaSumma);
if (!byDevil)useProgram = ContinueCheck();
}
if (!byDevil)
//Ohjelman lopetus
EndProgram();
else return 666;
}
//automaatiotilien alustusfunktio
void AccountInitialize() {
//Tähän kirjoitetaan automaatiotilien (tai/ja muidenkin käytössä olevien tilien) alkusummat
//note: tätä lohko ei juurikaan käytetty koodissa.
//Miljonääritili
accountArr[800] = 1000000;
}
//Ohjelman lopussa tulostettava funktio
void EndProgram() {
cout << "\n\n __ _\no'')}____//\n `_/ )\n (_(_/-(_/\n\n";
cout << "Kiitos kirjanpito-ohjelman käytöstä. Toivottavasti pidit järjestelmästämme. Voit nyt sulkea ikkunan.";
}
//automaatiosyötteen tarkastusfunktio
void AutomationCheck(int tili, double raha) {
//Funktio tarkastaa, oliko syötetty tilinumero osa tilejä, jotka käynnistävät automaatiorakenteita
int arr;
//Käytetään switch - case rakennetta automaatiotilien aktivointiin
switch (tili) {
case 124: {
//24% alv laskuri
//Tätä tiliä käyttäjä ei voi käsitellä suoraan, vaan kaikki suoraan tilille 124 lasketaan alvina tilille 24.
arr = 24;
accountArr[arr] += raha * 0.24;
cout << arr << "\t\t" << accountArr[arr] << "\n";
break;
}
case 110: {
//10% alv laskuri
//Tätä tiliä käyttäjä ei voi käsitellä suoraan, vaan kaikki suoraan tilille 110 lasketaan alvina tilille 10.
arr = 10;
accountArr[arr] += raha * 0.10;
cout << arr << "\t\t" << accountArr[arr] << "\n";
break;
}
case 666: {
//pirullinen meiniki
//Tätä automaatiotiliä (66) voi käyttää vain itse piru
if (raha == 666) {
cout << " |\\___/|\n / \\\n| /\\__/|\n||\\ <.><.>\n| _ > )\n \\ /----\n | -\\/\n / \\\n\n";
cout << "Kuka hölmö antaisi paholaiselle tällaisen rahasumman?!?!\nTästä saat kärsiä!";
useProgram = 0;
byDevil = 1;
}
else {
arr = 66;
accountArr[arr] += 666;
cout << arr << "\t\t" << accountArr[arr] << "\n";
cout << " |\\___/|\n / \\\n| /\\__/|\n||\\ <.><.>\n| _ > )\n \\ /----\n | -\\/\n / \\\n";
cout << "Aina kun käytät tätä tiliä, minä rikastun!\n\n";
}
break;
}
case 777: {
//aktivoi tilin 111 summat näkyviin
if (!firstSevens) {
firstSevens = 1;
cout << "\nAutomaatiotili 11 aktivoitu!\n";
}
break;
}
case 111: {
//pulmallinen tili
//näyttää tilin 11 oikean summan vasta kun tilille 777 on kerran talletettu rahaa
arr = 11;
accountArr[arr] += 2 * raha;
if (firstSevens) {
cout << arr << "\t\t" << accountArr[arr] << "\n";
}
else cout << "\nAutomaatiotilin aktivointi vaaditaan, että tilin 11 sisältö tulee näkyviin. Onnenluvut auttakoon!\n";
break;
}
case 400: {
//tili 60 saa summansa tileiltä 400 ja 500
arr = 60;
accountArr[arr] = accountArr[400] + accountArr[500];
cout << arr << "\t\t" << accountArr[arr] << "\n";
break;
}
case 500: {
//tili 60 saa summansa tileiltä 400 ja 500
arr = 60;
accountArr[arr] = accountArr[400] + accountArr[500];
cout << arr << "\t\t" << accountArr[arr] << "\n";
break;
}
}
}
//Tervehdysfunktio
void Welcome() {
cout << " __\n\\ ______/ V`-,\n } /~~\n /_)^--,r/\n\n";
cout << "Tervetuloa käyttämään koiranpito... siis kirjanpito-ohjelmaa!\n";
cout << "Kirjanpitoohjelma kysyy ensin tilinumeron ja sitten summan, jonka haluat tilille tallettaa.\n";
cout << "Tilinumero on väliltä 100-999 ja rahasummat nollaa isompia.\n\n";
}
//Pankkitilifunktio syötteentarkastuksella
int AccountInput() {
//Muuttujat
int a;
bool inRange = 0;
cout << "Syötä tilinumero: ";
cin >> a;
//syötteentarkastus
while (1)
{
//jos syöte ei sovi muuttujaan
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Syötteesi on väärä. Käytä numeroita syöttäessäsi numeroita väliltä 100-999. Yritä uudestaan.\nSyötä Tilinumero: ";
cin >> a;
}
//Jos syöte on väärällä alueella
if (!(a >= 100 && a <= 999)) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Syötteesi on väärä. Tilinumerot ovat välillä 100-999. Yritä uudestaan.\nSyötä Tilinumero: ";
cin >> a;
}
else inRange = 1;
if (!cin.fail() && inRange)
break;
}
//Palauttaa sallitusti syötetyn pankkitilinumeron
return a;
}
//Rahantalletus funktio syötteentarkastuksella
double MoneyInput() {
int a;
bool inRange = 0;
cout << "Syötä rahasumma: ";
cin >> a;
//Syötteentarkastus
while (1)
{
//jos syöte ei sovi muuttujaan
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Syötteesi on väärä. Käytä numeroita syöttääksesi rahasumma euron tarkkuudella Yritä uudestaan.\nSyötä rahasumma: ";
cin >> a;
}
//Jos syöte on alle nollan
if (a <= 0) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Syötteesi on väärä. Rahasumman tulee olla vähintään 1 euro. Yritä uudestaan.\nSyötä rahasumma: ";
cin >> a;
}
else inRange = 1;
if (!cin.fail() && inRange)
break;
}
//Palauttaa hyväksytysti syötetyn raha-arvon
return a;
}
//Käytönjatkamistarkastus
bool ContinueCheck() {
//Funktio tarkastaa haluaako käyttäjä jatkaa sovelluksen käyttöä
cout << "Haluatko jatkaa järjestelmän käyttöä? (k/e): ";
bool inRange = 0;
char a;
cin >> a;
//Syötteentarkastus
while (1)
{
//Jos syöte ei sovi muuttujaan
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Syötteesi on väärä. Käytä numeroita syöttääksesi rahasumma euron tarkkuudella Yritä uudestaan.\nSyötä rahasumma: ";
cin >> a;
}
//Tarkastetaan, onko syöte k tai e isolla tai pienellä
if (a != 'k' && a != 'K' && a != 'e' && a != 'E') {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Syötteesi on väärä. Käytä kirjainta k (kyllä) tai e (ei).\nHaluatko jatkaa ohjelman käyttöä? (k/e):";
cin >> a;
}
else inRange = 1;
//jos syöte on oikein niin jatketaan
if (!cin.fail() && inRange)
break;
}
//Palautetaan 1 jos vastaus on k ja 0 jos vastaus on e. Arvo menee muuttujaan useProgram, joka tarkastetaan main-funktiossa
if (a == 'k' || a == 'K') return 1;
else
return 0;
}
@juvuorin
Copy link
Author

juvuorin commented Apr 28, 2021

Anssin ratkaisu on fiksusti kommentoitu ja funktioiden nimeäminen on johdonmukaista kautta linjan. Huumoriakin on viljelty ja 666-alkuiselle tilille rahaa kirjatessa nousee hymy huulille. Tehtävänanto lienee ollut hieman moniselitteinen, sillä ratkaisu ei ehkä ole ihan sitä mitä on etsitty. Se ei kuitenkaan Selma-koiraa haittaa!

Ohjelma käsittelee myös virhetilanteet ja niihin on kiinnitetty erityistä huomiota. CTRL+C:n avulla ohjelman tosin saa pysähtymään, mutta niin saa monen muunkin komentorivillä pyörivän ohjelman :). Ohjelma osoittaa, että tekijä hallitsee perusalgoritmien tekemisen hyvin ja tästä on helppo jatkaa minkä tahansa ohjelmointikielen tai ohjelmointitöiden kanssa; kukaties tekijä jo niitä töitä tekeekin. Rakenteisia tietotyyppejä ei ole käytetty, mutta näin yksinkertaisen tiedon tapauksessa se ei liene tarpeenkaan, vaikka siihen C++ antaisi mahdollisuuden (struct, class jne.).

Tekijä osaa käyttää myös virta-operaattoreita sujuvasti (esim. >>). Virtaoperaattoreita ja niitä vastaavia käytetään monissa kielissä ja niiden osaamisesta on aina hyötyä; lisäksi tekijä osaa lyhyemmän muodon sijoitusoperaatioista yhdistettynä esimerkiksi yhteenlaskuoperaatioon esim. accountArr[arr] += 2 * raha. Tekijä osaa myös tekstivirtojen perusmuotoilun, mistä kertoo mm. \n käyttö, taito mikä ei vanhene koskaan ja mitä on tarvittu vuosikymmeniä eri ohjelmointiympäristöissä.

Tekijä käyttää ohjelman alussa termiä "funktioiden alustus" - ehkä kyseessä on kuitenkin "funktioiden esittely". Asia on pikkujuttu, mutta on hyvä pitää mielessä, että termeillä on eroa, vaikka ne joskus tuntuvatkin menevän sekaisin niin ammattilaisilla kuin aloittelijoillakin.

Riveillä 218-240 olisi kenties voinut käyttää loppuehtoista toistoa (do-while), mutta toisaalta kyseinen koodin kohta on erittäin hyvin luettavaa ja siitä selviää, miten syötettä pitää tarkistella. Muuttujien nimeäminen on kauttaaltaan fiksua, tosin inRange muuttuja voisi saada true/false -arvoja 1 arvon sijaan - se voisi tehdä koodista hieman luettavampaa. Samaan hengenvetoon voidaan sanoa, että muuttujan nimeäminen "inRange" JA arvo 1, kyllä kertovat koodin lukijalle kyseessä olevan asiallisesti ottaen "booleanin".

Switch-case -rakennetta on käytettyä oikeassa paikassa ja modulointi on järkevästi toteutettu - on ollut viisasta pitää ohjelma yhdessä tiedostossa, koska se on kuitenkin verrattain pieni.

Jos tekijä ei jo ole ohjelmistosuunnittelutöissä, niin tästä on hyvä jatkaa! Selma-koira kiittää kisatyöstä ja toivottaa hyvää jatkoa pirullisten ohjelmointihaasteiden parissa :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment