import java.util.Scanner; import java.util.regex.*; import java.util.NoSuchElementException; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; class Oblig7 { static class Data { File file; Tabell personer = new Tabell(10); Tabell legemidler = new Tabell(10); Tabell leger = new Tabell(10); Tabell resepter = new Tabell(10); Data(File file) throws Exception { this.file = file; read(); } public void insertPerson( int id, String navn, String fodselsnummer, String addresse, String postnr) { personer.leggTil(new Pasient( id, navn, addresse, postnr, fodselsnummer )); } public void insertLegemiddel( int id, String navn, String form, String type, int pris, int mengde, int virkestoffPerMengde, int styrke) throws Exception { if (type.equals("a") && form.equals("pille")) { legemidler.leggTil(new LegemiddelNarkotiskPille( id, pris, navn, styrke, mengde, virkestoffPerMengde )); } else if (type.equals("a") && form.equals("mikstur")) { legemidler.leggTil(new LegemiddelNarkotiskFlytende( id, pris, navn, styrke, mengde, virkestoffPerMengde )); } else if (type.equals("b") && form.equals("pille")) { legemidler.leggTil(new LegemiddelVanedannendePille( id, pris, navn, styrke, mengde, virkestoffPerMengde )); } else if (type.equals("b") && form.equals("mikstur")) { legemidler.leggTil(new LegemiddelVanedannendeFlytende( id, pris, navn, styrke, mengde, virkestoffPerMengde )); } else if (type.equals("c") && form.equals("pille")) { legemidler.leggTil(new LegemiddelVaneligPille( id, pris, navn, mengde, virkestoffPerMengde )); } else if (type.equals("c") && form.equals("mikstur")) { legemidler.leggTil(new LegemiddelVaneligFlytende( id, pris, navn, mengde, virkestoffPerMengde )); } else { throw new Exception( "Feil legemiddel: type "+type+", form "+form ); } } public void insertLege( String navn, int avtalenr) { if (avtalenr == 0) leger.leggTil(new Lege(navn)); else leger.leggTil(new Fastlege(navn, avtalenr)); } public void insertResept( int id, String farge, int pasientNr, String utskriverNavn, int legemiddelNr, int reit) throws Exception { Legemiddel legemiddel = null; for (Legemiddel l: legemidler) { if (l.id == legemiddelNr) { legemiddel = l; break; } } if (legemiddel == null) { throw new Exception( "Ingen legemiddel med ID "+legemiddelNr ); } if (farge.equals("blaa")) { resepter.leggTil(new BlaaResept( id, utskriverNavn, pasientNr, legemiddel, reit )); } else if (farge.equals("hvit")) { resepter.leggTil(new HvitResept( id, utskriverNavn, pasientNr, legemiddel, reit )); } } private void insert(String mode, String[] tokens) throws Exception { switch (mode) { case "Personer": { insertPerson( Integer.parseInt(tokens[0]), tokens[1], tokens[2], tokens[3], tokens[4] ); break; } case "Legemidler": { int styrke = 0; try { styrke = Integer.parseInt(tokens[7]); } catch (ArrayIndexOutOfBoundsException ex) {}; insertLegemiddel( Integer.parseInt(tokens[0]), tokens[1], tokens[2], tokens[3], Integer.parseInt(tokens[4]), Integer.parseInt(tokens[5]), Integer.parseInt(tokens[6]), styrke ); break; } case "Leger": { insertLege( tokens[0], Integer.parseInt(tokens[1]) ); break; } case "Resepter": { insertResept( Integer.parseInt(tokens[0]), tokens[1], Integer.parseInt(tokens[2]), tokens[3], Integer.parseInt(tokens[4]), Integer.parseInt(tokens[5]) ); break; } default: break; } } private void read() throws Exception { Scanner s = new Scanner(file); String mode = null; while (s.hasNextLine()) { String line = s.nextLine(); if (line.startsWith("#")) { String[] tokens = line.split("\\s+"); mode = tokens[1]; if (mode.equals("Slutt")) return; } else if (mode != null) { String[] tokens = line.split(",\\s+"); if (tokens.length == 1 && tokens[0].equals("")) continue; insert(mode, tokens); } } } private void writeln(OutputStream w, String s) throws Exception { w.write((s+"\n").getBytes()); } public void write() throws Exception { OutputStream w = new FileOutputStream(file); { // Personer writeln(w, "# Personer"); for (Pasient p: personer) { writeln(w, p.id+", "+ p.navn+", "+ p.fodselsnummer+", "+ p.addresse+", "+ p.postnr ); } writeln(w, ""); } { // Legemidler writeln(w, "# Legemidler"); for (Legemiddel l: legemidler) { int id = l.id; String navn = l.navn; String form = ""; String type = ""; int pris = l.pris; int mengde = 0; int virkestoffPerMengde = 0; Integer styrke = null; if (l instanceof LegemiddelNarkotiskPille) { LegemiddelNarkotiskPille c = (LegemiddelNarkotiskPille)l; form = "pille"; type = "a"; mengde = c.antallPiller(); virkestoffPerMengde = c.virkestoffPerPille(); styrke = c.styrke; } else if (l instanceof LegemiddelNarkotiskFlytende) { LegemiddelNarkotiskFlytende c = (LegemiddelNarkotiskFlytende)l; form = "mikstur"; type = "a"; mengde = c.cm3(); virkestoffPerMengde = c.virkestoffPerCm3(); styrke = c.styrke; } else if (l instanceof LegemiddelVanedannendePille) { LegemiddelVanedannendePille c = (LegemiddelVanedannendePille)l; form = "pille"; type = "b"; mengde = c.antallPiller(); styrke = c.hvorVanedannende; virkestoffPerMengde = c.virkestoffPerPille(); } else if (l instanceof LegemiddelVanedannendeFlytende) { LegemiddelVanedannendeFlytende c = (LegemiddelVanedannendeFlytende)l; form = "mikstur"; type = "b"; mengde = c.cm3(); styrke = c.hvorVanedannende; virkestoffPerMengde = c.virkestoffPerCm3(); } else if (l instanceof LegemiddelVaneligPille) { LegemiddelVaneligPille c = (LegemiddelVaneligPille)l; form = "pille"; type = "c"; mengde = c.antallPiller(); virkestoffPerMengde = c.virkestoffPerPille(); } else if (l instanceof LegemiddelVaneligFlytende) { LegemiddelVaneligFlytende c = (LegemiddelVaneligFlytende)l; form = "mikstur"; type = "c"; mengde = c.cm3(); virkestoffPerMengde = c.virkestoffPerCm3(); } writeln(w, id+", "+ navn+", "+ form+", "+ type+", "+ pris+", "+ mengde+", "+ virkestoffPerMengde+ (styrke == null ? "" : ", "+styrke) ); } writeln(w, ""); } { // Leger writeln(w, "# Leger"); for (Lege l: leger) { String navn = l.navn; int avtalenummer = 0; if (l instanceof Fastlege) { Fastlege f = (Fastlege)l; avtalenummer = f.avtalenummer; } writeln(w, navn+", "+avtalenummer); } writeln(w, ""); } { // Resepter writeln(w, "# Resepter"); for (Resept r: resepter) { int id = r.id; String type = ""; int pasientNr = r.pasientNr;; String utskriverNavn = r.utskriverNavn; int legemiddelNr = r.legemiddel.id; int reit = r.reit; if (r instanceof BlaaResept) type = "blaa"; else if (r instanceof HvitResept) type = "hvit"; writeln(w, id+", "+ type+", "+ pasientNr+", "+ utskriverNavn+", "+ legemiddelNr+", "+ reit ); } writeln(w, ""); } { // Slutt writeln(w, "# Slutt"); } } } static class CmdLine { private Scanner s; private boolean looping; private Data data; CmdLine(Scanner s, Data data) { this.s = s; this.data = data; } private String readln(String text, String rx, String prompt) { if (text != null) { System.out.print(text); if (rx != null) { System.out.print(" ("+rx+")"); } System.out.println(""); } if (rx == null) { System.out.print(prompt); return s.nextLine(); } else { // Strings must match entirely, not just partially String realrx = ("^"+rx+"$").replace("*", "\\*"); Pattern p = Pattern.compile(realrx); while (true) { System.out.print(prompt); String line = s.nextLine(); Matcher m = p.matcher(line); if (m.matches()) { return line; } else { System.out.println("'"+line+"' matcher ikke ("+rx+")."); } } } } private String readln(String text, String rx) { return readln(text, rx, "> "); } private int ireadln(String text, String rx) { try { return Integer.parseInt(readln(text, rx)); } catch (NumberFormatException ex) { return 0; } } private String readln() { return readln(null, null, "> "); } private int ireadln() { try { return Integer.parseInt(readln()); } catch (NumberFormatException ex) { return 0; } } public void loop() throws Exception { looping = true; while (looping) { String str; try { str = readln(null, null, "$ "); } catch (NoSuchElementException ex) { System.out.println(""); return; } cmd(str); } } public void cmd(String name) throws Exception { switch (name) { /* * Hjelp */ case "hjelp": { System.out.print( "Tilgjengelige kommandoer:\n"+ " hjelp - vis denne teksten\n"+ "\n"+ " skriv ut - skriv ut data\n"+ " nytt legemiddel - legg til et nytt legemiddel\n"+ " ny lege - legg til en ny lege\n"+ " ny person - legg til en ny person\n"+ " ny resept - legg til en ny resept\n"+ " hent legemiddel - vis legemiddel paa resept\n"+ "\n"+ " antall resepter - vis antall resepter basert paa kriterier\n"+ " vis resepter til person - vis reseptene til en person\n"+ " vis resepter til lege - vis reseptene en lege har skrevet ut\n"+ " finn narkotisk misbruk - finn misbruk av narkotika\n" ); break; } /* * Skriv ut */ case "skriv ut": { System.out.println("Personer:"); for (Pasient p: data.personer) { System.out.println(" "+p.identify()); } // Leger maa sorteres, saa vi legger dem inn i en // SortertEnkelList for vi printer dem SortertEnkelListe legeliste = new SortertEnkelListe<>(); for (Lege l: data.leger) { legeliste.settInn(l); } System.out.println("Leger:"); for (Lege l: legeliste) { System.out.println(" "+l.identify()); } System.out.println("Legemidler:"); for (Legemiddel l: data.legemidler) { System.out.println(" "+l.identify()); } System.out.println("Resepter:"); for (Resept r: data.resepter) { System.out.println(" "+r.identify()); } break; } /* * Nytt legemiddel */ case "nytt legemiddel": { data.insertLegemiddel( -1, readln("Navn?", null), readln("Form?", "pille|mikstur"), readln("Type?", "a|b|c"), ireadln("Pris?", "[0-9]+"), ireadln("Mengde?", "[0-9]+"), ireadln("Mengde virkestoff?", "[0-9]+"), ireadln("Styrke?", "([0-9]+)?") ); System.out.println("Satt inn."); break; } /* * Ny lege */ case "ny lege": { data.insertLege( readln("Navn?", null), ireadln("Avtalenummer?", "([0-9]+)?") ); System.out.println("Satt inn."); break; } /* * Ny person */ case "ny person": { data.insertPerson( -1, readln("Navn?", null), readln("Fodselsnummer?", "[0-9]+"), readln("Addresse?", null), readln("Postnummer?", "[0-9]+") ); System.out.println("Satt inn."); break; } /* * Ny resept */ case "ny resept": { data.insertResept( -1, readln("Farge?", "blaa|hvit"), ireadln("Pasient ID?", "[0-9]+"), readln("Legenavn?", null), ireadln("Legemiddel ID?", "[0-9]+"), ireadln("Reit?", "[0-9]+") ); System.out.println("Satt inn."); break; } /* * Hent legemiddel */ case "hent legemiddel": { int reseptId = ireadln("Resept ID?", "[0-9]+"); // Finn resept med riktig ID Resept resept = null; for (Resept r: data.resepter) { if (r.id == reseptId) { resept = r; break; } } if (resept == null) { System.out.println("Finner ingen resept med ID "+reseptId+"."); return; } if (resept.reit < 1) { System.out.println("Reseptens reit er for lav."); return; } // Finn riktig legemiddel Legemiddel legemiddel = resept.legemiddel; // Finn riktig person Pasient person = null; for (Pasient p: data.personer) { if (p.id == resept.pasientNr) { person = p; break; } } if (person == null) { System.out.println("Finner ingen personer som eiger resepten."); return; } resept.reit -= 1; System.out.println("Skal betales: "+(resept instanceof BlaaResept ? 0 : legemiddel.pris)); System.out.println("Legens navn: "+resept.utskriverNavn); System.out.println("Pasientens navn: "+person.navn); System.out.println(legemiddel.identify()); break; } /* * Vis antall resepter */ case "antall resepter": { String type = readln("Type?", "a|b|c|*"); Tabell resepter; if (type.equals("*")) { resepter = data.resepter; } else { resepter = new Tabell<>(10); for (Resept r: data.resepter) { Legemiddel lm = r.legemiddel; if ((type.equals("a") && lm instanceof LegemiddelNarkotisk) || (type.equals("b") && lm instanceof LegemiddelVanedannende) || (type.equals("c") && lm instanceof LegemiddelVanelig)) { resepter.leggTil(r); } } } String sted = readln("Hvor skal personen vaere bosatt?", "oslo|*"); Tabell personer; if (sted.equals("*")) { personer = data.personer; } else { personer = new Tabell<>(10); int postnrStart = 0; int postnrEnd = 9999; switch (sted) { case "oslo": postnrStart = 1; postnrEnd = 1295; break; } for (Pasient p: data.personer) { int postnr = Integer.parseInt(p.postnr); if (postnr >= postnrStart && postnr <= postnrEnd) { personer.leggTil(p); } } } int antall = 0; for (Resept r: resepter) { for (Pasient p: personer) { if (r.pasientNr == p.id) { antall += 1; break; } } } System.out.println(antall); break; } /* * Vis resepter til person */ case "vis resepter til person": { String fodselsnummer = readln("ID/Fodselsnummer?", "[0-9]+"); int id; try { id = Integer.parseInt(fodselsnummer); } catch (NumberFormatException ex) { id = -1; } // Finn person med IDen Pasient person = null; for (Pasient p: data.personer) { if (p.fodselsnummer.equals(fodselsnummer) || p.id == id) { person = p; break; } } if (person == null) { System.out.println( "Fant ingen person med id/fodselsnummer "+fodselsnummer+"." ); return; } String farge = readln("Farge?", "blaa|hvit|*"); System.out.println("Resepter skrevet ut til "+person.navn+":"); // Finn resepter som horer til personen og har riktig farge YngsteForstReseptListe yfrl = new YngsteForstReseptListe(); for (Resept r: data.resepter) { if (r.pasientNr == person.id) { if ((farge.equals("*")) || (farge.equals("blaa") && r instanceof BlaaResept) || (farge.equals("hvit") && r instanceof HvitResept)) { yfrl.settInn(r); } } } for (Resept r: yfrl) { System.out.println(" "+r.identify()); } break; } /* * Vis resepter til lege */ case "vis resepter til lege": { String navn = readln("Legenavn?", null); Lege lege = null; for (Lege l: data.leger) { if (l.navn.equals(navn)) { lege = l; break; } } if (lege == null) { System.out.println("Fant ingen lege som heter "+navn+"."); return; } String type = readln("Type?", "pille|mikstur|*"); int pilleVirkestoff = 0; int miksturVirkestoff = 0; // Liste over reseptene til legen, eldste forst EldsteForstReseptListe efrl = new EldsteForstReseptListe(); // Gaa igjennom resepter for aa finne de skrevet ut av legen for (Resept r: data.resepter) { if (r.utskriverNavn.equals(navn)) { // Tell pilleVirkestoff og miksturVirkestoff // Dete maa gjores her, siden det skal telles uansett // om resepten er paa riktig form eller ikke Legemiddel lm = r.legemiddel; if (lm instanceof LegemiddelPille) { LegemiddelPille l = (LegemiddelPille)lm; pilleVirkestoff += (l.antallPiller() + l.virkestoffPerPille()); } else if (lm instanceof LegemiddelFlytende) { LegemiddelFlytende l = (LegemiddelFlytende)lm; miksturVirkestoff += (l.cm3() * l.virkestoffPerCm3()); } if ((type.equals("*")) || (type.equals("pille") && lm instanceof LegemiddelPille) || (type.equals("mikstur") && lm instanceof LegemiddelFlytende)) { efrl.settInn(r); } } } for (Resept r: efrl) { Legemiddel lm = r.legemiddel; System.out.println(r.identify()); System.out.println(" for "+lm.identify()); } System.out.println( "Samlet virkestoff: "+(pilleVirkestoff + miksturVirkestoff)+ ", hvorav:" ); System.out.println(" "+pilleVirkestoff+" er fra piller"); System.out.println(" "+miksturVirkestoff+" er fra miksturpreparater"); break; } /* * Finn narkotisk misbruk */ case "finn narkotisk misbruk": { /* * Hva bor gjores hvis disse sporringene utfores veldig ofte? * * Disse sporringene er veldig tunge, fordi * vi maa gaa igjennom alle legemidler for hver resept * for baade hver lege og hver pasient. * * Hvis disse sporringene blir utfort veldig ofte, bor vi finne * en maate aa gjore at de gaar raskere. Her er noen maater * en kunne gjort det paa: * * 1. Cache resultatene. * Saa lenge vi ikke endrer paa legemidler, resepter, leger, * eller personer, vil resultatene alltid vaere det samme. * Det er derfor ikke noe vits i aa kalkulere alt paa nytt * hver gang; en kunne ha lagret resultatet, og kun vist frem * det lagrede resultatet hvis ingenting har endret seg. * Viktig aa passe paa at det lagrede resultatet slettes * slik at det rekalkuleres hver gang noe viktig endrer seg. * * 2. Bruke en database. * Relasjonelle databaser er laget for denne typen sporringer. * Aa gaa over fra et hjemmesnekret filformat til en form for * relasjonell database hadde nok vaert den beste losningen * hvis dette hadde vaert et ekte program for en ekte klient. * Naar en forst har gaatt over til en relasjonell database * finnes det ogsaa en del optimaliseringsteknikker * (indekser, etc.) som jeg ikke gaar in paa her. */ // Finn leger som har skrevet ut narkotiske resepter SortertEnkelListe legeliste = new SortertEnkelListe<>(); for (Lege lege: data.leger) { boolean skrevetUtNarkotisk = false; for (Resept r: data.resepter) { Legemiddel lm = r.legemiddel; if ((r.utskriverNavn.equals(lege.navn)) && (lm instanceof LegemiddelNarkotisk)) { skrevetUtNarkotisk = true; } } if (skrevetUtNarkotisk) { legeliste.settInn(lege); } } // Skriv ut legene som har skrevet ut narkotiske resepter System.out.println("Leger som har skrevet ut narkotiske resepter:"); for (Lege lege: legeliste) { int antall = 0; for (Resept r: data.resepter) { Legemiddel lm = r.legemiddel; if ((r.utskriverNavn.equals(lege.navn)) && (lm instanceof LegemiddelNarkotisk)) { antall += 1; } } System.out.println( " "+lege.navn+": "+ antall+" narkotisk(e) resept(er)" ); } // Skriv ut personene med en gyldig resept paa narkotiske legemidler System.out.println("Personer med en gyldig resept paa narkotiske legemidler:"); for (Pasient person: data.personer) { int antall = 0; for (Resept r: data.resepter) { Legemiddel lm = r.legemiddel; if ((r.pasientNr == person.id) && (r.reit > 0) && (lm instanceof LegemiddelNarkotisk)) { antall += 1; } } if (antall > 0) { System.out.println( " "+person.navn+": "+ antall+" narkotisk(e) resept(er)" ); } } break; } /* * Ukjent kommando */ default: System.out.println( "Ukjent kommando: "+name+". "+ "Skriv 'hjelp' for hjelp." ); } data.write(); } } public static void main(String[] args) throws Exception { if (args.length < 1) { System.out.println("Usage: java Oblig7 "); return; } Data d = new Data(new File(args[0])); Scanner s = new Scanner(System.in); CmdLine cmdline = new CmdLine(s, d); cmdline.loop(); } }