Vaje 3 - Tabele, metode, datoteke
Ogled rešitev Vaj 2
Najprej boste vi predstavili (ostalim) rešitve nekaterih nalog prejšnjih vaj. Pri tem bomo uporabili tudi LiveShare, ki je sedaj na študentskih računalnikih pripravljen za uporabo.
O Visual studiu
Sestavi ustrezna navodila, kjer boš pregledno (s slikami, primeri, kako nastavitev vpliva ... ) opisal vsaj kakšno od nastavitev obnašanja urejevalnika kode, ki jih nastavljamo v Tools/Options/TextEditor. Izberi tiste, za katere meniš, da so uporabne (in jih boš verjetno ti pri sebi spremenil/uporabil) .
Tukaj https://ucilnica.fmf.uni-lj.si/mod/folder/view.php?id=28191 je že nekaj primerov.
Poleg tega si oglej, kako poskrbiš, da nastavitve v Code Style "potujejo" s tvojo rešitvijo [in seveda to napiši] ter pripravi primer vsaj ene datoteke z vsaj eno nastavitvijo! Morda si lahko pomagaš s tem virom, obstajajo pa tudi "boljši".
Napiši, za katero različico VS opisuješ nastavitve/postopek (ali še bolje - preveri in napiši, kako se nastavitev/postopek obnaša/izvede v različnih različicah VS).
Popravi, spremeni, napiši ...
Za naloge v tem razdelku bo na voljo tudi "referenčna" rešitev, ki si jo bomo ogledali naslednjič in kjer bodo morda uporabljeni tudi določeni drugi prijemi ...
V gore
Planinski krožek se je odpravil na izlet v bližnje gore. Pot jih je vodila tudi čez most, pod katerim je globoko v dolini tekla reka. Učenci so spraševali učitelje, kako visok je most, pa jim ti niso znali odgovoriti. Janezek je hitro napisal program za določanje višine mostov. Seveda je to storil tako, da je program glede na čas (v sekundah) padanja kamna z mostu izračunal višino mostu v metrih. Njegova koda je
class VisinaMostu {
double g = 9.8;
static void Main(string[] args) { Console.WriteLine("Visina : " + globina() + " m."); } public static double globina() {
Console.Write("Vnesi cas padanja kamna z mostu do tal (v sekundah): ");
double t = Double.Parse(Console.ReadLine());
//izracunamo visino
double h = g * t^2 / 2;
//zaokrozimo na dve decimalki
h = (h * 100) / 100.0;
return h;
} }
Seveda pa to ne bi bil Janezek, če bi zadeva delovala prav. Poišči napake in odpravi nelogičnosti v strukturi kode!
Zamenjava elementov
Miha je napisal metodo
static int[] Kopija(int[] t) { return t; }
ki naj bi vrnila kopijo tabele. Da bi se prepričal, kako deluje, je napisal še metodo
static void Izpisi(string ime, int[] t) { ... }
ki izpiše ime (tabele) in vse njene elemente v eni vrstici. Vse skupaj je uporabil v programu
static void Main(string[] args) {
int[] a = {1, 2, 3}; int[] b = Kopija(a);
Console.WriteLine("Prej: "); Izpisi("a", a); Izpisi("b", b);
a[1] = b[2]; a[2] = b[1];
Console.WriteLine("Potem: "); Izpisi("a", a); Izpisi("b", b);
}
A se mu račun ni čisto izšel ...
-
- Napiši metodo Izpisi in poglej kakšen izpis je dobil Miha.
- Popravi metodo Kopija tako, da bo program pravilno deloval.
Judging Troubles
Reši nalogo Judging Troubles s Kattisa. Če ne gre, je tukaj ustrezna rešitev v Pythonu.Album
Anže zbira sličice o živalih in jih lepi v album, v katerem je prostora za n sličic. Koliko sličic je v povprečju potrebno kupiti, da bi napolnil album? Povprečje izračunaj tako, da simuliraš 1000 polnitev albuma. Koliko je bilo najmanj in največ potrebnih sličic? Kaj pa če sličice niso na voljo posamezno, ampak le v kompletih po m sličic? Pri tem vemo, da so v kompletu vse sličice različne!
Prouči program, ali dela to, kar naj bi, ter potem program predelaj tako, da bo uporabnik vnesel število m, velikost albuma, ... . Prav tako zadevo ustrezno organiziraj - razbij na smiselne funkcije.
class Program
{
static void Main(string[] args)
{
// recimo, da je v albumu prostora za 50 sličic
// zbrati je potrebno vseh 50 različnih sličic
int n = 50;
int max = 0; // največ kupljenih sličic za zapolnjen album
int min = 1000; // najmanj kupljenih sličic za zapolnjen album, predpostavimo da nam nikoli ne bo potrebno kupiti več kot 1000 sličič
bool[] album = new bool[n]; //seznam sličic v albumu
Random nakljucna = new Random();
int i;
int skupajKupljene = 0; // štejemo koliko sličic smo kupili v vseh 1000-ih polnjenjih
for (i = 0; i < 1000; i++) // simuliramo 1000 polnitev albuma
{
int manjka = n; // album je prazen
int kupili = 0; // štejemo kupljene sličice
int j = 0;
while (j < n) // vse vrednosti v albumu postavimo na 'false', torej nismo še prilepili slicice
{
album[j] = false;
j++;
}
while (manjka > 0) // polnimo album dokler ne dobimo prav vseh sličic
{
int nakljucnoSt = nakljucna.Next(n); // kupimo eno sličico
kupili++;
if (!album[nakljucnoSt]) // če je mesto za to sličico še prosto...
{
album[nakljucnoSt] = true; // ...ga zapolnimo, tako da sličico prilepimo
manjka--; // manjka ena sličica manj
}
}
skupajKupljene = skupajKupljene + kupili;
if (kupili > max) max = kupili;
if (kupili < min) min = kupili;
}
int povprecje = skupajKupljene / 1000;
Console.WriteLine("Povprečno število sličic, ki jih je potrebno kupiti, da zapolnimo album je " + povprecje + " .");
Console.WriteLine("Najmanjše število sličic, ki jih je potrebno kupiti, da zapolnimo album je " + min + " .");
Console.WriteLine("Največje število sličic, ki jih je potrebno kupiti, da zapolnimo album je " + max + " .");
}
}
Trojk pa ne
Napiši metodo
void Krajsaj(int[] t)
ki iz vseh števil v dani tabeli celih števil pobriše vse števke 3. Tako npr. iz tabele [13,23,333,112,3] nastane [1,2,112]. Metodo preveri v programu.
Knjižnica metod
V spodnjih nalogah je potrebno pripraviti eno ali več metod. Če ni posebej zahtevano, je v glavnem programu potrebno prikazati delovanje vseh v programu definiranih metod. Nujno je, da so metode opremljene s kvalitetnimi dokumentacijskimi komentarji!
Pripravi si nekaj uporabnih metod za delo s tabelami, ki jih bomo kasneje potrebovali pri drugih projektih
-
- Napiši metodo PodvojiVelikost, ki kot parameter dobi tabelo celih števil in jo spremeni tako, da je sedaj dvojne velikosti (obstoječi elementi ostanejo). Pri tem NE UPORABLJAJ npr. razreda Array, ampak čim bolj "osnovne" prijeme. Seveda pa si kasneje lahko ogledaš, kako to storiš z Array.
-
Pripravi si metodo
int[] NakljucnaTabela(int d, int m)
ki vrne tabelo dolžine d, ki vsebuje naključna cela števila med 1 in m.
-
Pripravi si metodo
string TabelaKotNiz(int[] t)
ki iz tabele celih števil t naredi niz, sestavljen iz elementov tabele in ločenih s presledkom.
-
Pripravi si metodo
int[] NizKotTabela(string s)
ki iz niza naredi tabelo celih števil. Znaki so med seboj ločeni s presledki. (Predpostaviš lahko, da je niz v pravi obliki.)
Izboljšave
-
-
Metodo NakljucnaTabela lahko izboljšaš tako, da ji dodaš še en parameter tipa bool , ki pove, ali naj bodo v njej sami različni elementi.
static int[] NakljucnaTabela(int d, int m, bool razlicni)
prvotno metodo lahko potem spremeniš v
static int[] NakljucnaTabela(int d, int m)
{ return NakljucnaTabela(d, int m, false); } -
Metodo TabelaKotNiz lahko izboljšaš tako, da poveš, kaj je ločilo med elementi in podobno kot zgoraj naj TabelaKotNiz(t) pomeni klic metode, kjer je ločilo kar presledek. Podobno kot prej omogoči klic s privzetim parametrom.
-
Metodo NizKotTabela lahko izboljšaš tako, da poveš, kaj je ločilo (tipa char) in narediš metodo tako robustno, da ignorira vsa ločila na začetku in koncu in vsa ponovljena ločila. Podobno kot prej omogoči klic s privzetim parametrom.
-
Datoteke
To je moja datoteka
Miha želi napisati program, ki po vrsti
-
- Ustvari tekstovno datoteko z imenom "vaja.txt" in vanjo napiše "To je moja datoteka!"
- Prebere datoteko in izpiše njeno prvo vrstico
- Ko uporabnik vnese svoje ime, v datoteko doda vrstico z imenom.
- Nato prebere novo datoteko in na zaslon izpiše vse oštevilčene vrstice nove datoteke.
Program je že začel pisati, a ne dela. Ali znaš njegovo kodo popraviti?
string f = "u:\vaja.txt";
StreamWriter pisanje = File.CreateText(f);
pisanje.WriteLine(To je moja datoteka);
streamReader branje = File.OpenText(f);
string vrstica = branje.ReadLine();
branje.Close(); pisanje.WriteLine(vrstica);
StreamWriter dodajanje = File.CreateText(f);
string ime = branje.ReadLine("Vnesi ime: ")
dodajanje.WriteLine(ime);
dodajanje.Close();
StreamReader novobranje = File.OpenText(f);
int i = 0;
while ((vrstica = novobranje.ReadLine()) != null) {
Console.WriteLine(++i + ": " + vrstica);
}
novobranje.Close();
-
- Prepričaj se, da zadnji del kode (številčenje vrstic) deluje pravilno. Zakaj? Ali znaš to zapisati na bolj tradicionalen način?
- Program spremeni tako, da uporabnik sam vnese ime datoteke? Ali znaš to narediti na 'varen' način? (Ime? Kje se ustvari? Že obstaja?)
Datoteka naključnih števil
Napiši metodo, ki ustvari datoteko naključnih števil. V vsaki vrstici je lahko več števil, ki so med seboj ločena s presledki. Metoda naj bo oblike
void Ustvari(string ime, int maxvrstic, int maxstevil, int maxvrednost).
Delovanje metode preveri tako, da datoteko izpišeš po vrsticah.
Dopolni metodo tako, da ji dodaš parameter poravnaj s privzeto vrednostjo 0. Če ima poravnaj vrednost večjo od 0, naj metoda izpisuje števila poravnano desno na poravnaj mest, sicer pa naj se obnaša kot prej.
Prodaja banan
V podjetju Bananca d.o.o. beležijo prodajo banan in sicer tako, da v tekstovno datoteko po vrsti zapisujejo števila prodanih banan. Vso prodajo v enem dnevu zapišejo v eno vrsto, števila pa so med seboj ločena s presledki (enim ali več). Ime datoteke je enako imenu meseca, na katerega se podatki nanašajo. Napiši program, ki prebere podatke za dani mesec (vnese uporabnik!) in izpiše skupno prodajo in največjo dnevno prodajo. Če datoteke za določen mesec ni, naj to program prijazno izpiše.
Ker so tako zapisana poročila nepregledna, so se odločili, da bodo na začetku vsake vrstice dodali še datum (v obliki 'dd.mm.llll'). Seveda se jim starih podatkov ne da popravljati, zato imajo lahko v isti datoteki nekatere vrstice na začetku datum, nekatere pa ne. Dopolni program tako, da bo ignoriral morebitne datume na začetku vrstic.
Odstrani komentarje
Napiši program, ki besedilo iz dane tekstovne datoteke (ki je v resnici napisana v TeXu) prepiše na drugo datoteko in pri tem odstrani vse vrstične komentarje. Začetek vrstičnega komentarja predstavlja znak %. Če je % prvi znak v vrstici, odstrani celo vrstico.
-
- Zadeva se lahko zakomplicira, saj z ukazom \% znak izpišemo in torej \% ni začetek vrstičnega komentarja. (V resnici je zadeva še bolj komplicirana, saj lahko zapišemo \\%, kar v TeXu pomeni skok v novo vrsto in nato vrstični komentar, ali pa \\\%, \\\\%)
Obrni poročilo
Poslovanje podjetja Bananca d.o.o. sedaj dobro poznaš. Ni ti všeč, da so mesečna poročila napisana tako, da je zadnji datum na dnu. Napiši program, ki bo prebral tekstovno datoteko z mesečnim poročilom in vrstice napisal v drugo datoteko v obratnem vrstnem redu.
-
- Ali lahko program enostavno spremeniš tako, da pravilno deluje tudi za celoletno poročilo?
- Kaj pa poljubno dolgo poročilo?