Diskuze: C# aplikace na výpočet provizí
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Michal Štěpánek:8.11.2016 21:22
- chtělo by to psát komentáře, aby se i ostatní v tom kódu vyznali.
- asi by bylo lepší používat konstrukci podmínek "if -> else if -> else" místo prostého "if", pak by se daly podmínky výrazně zjednodušit
třeba
if (s < 20000)
odecet = odecet + s * 0.04;
else if (s < 40000)
odecet = odecet + s * 0.08;
else if (s < 60000)
odecet = odecet + s * 0.12;
else if...
...
...
...
else
{
co se stane, když nevyhovuje žádná podmínka
}
- ty podmínky se mi zdají trochu zběsilé, např. co se bude dít, když třeba "s < 10000", nebo s > 360000 a přitom procenty[i].Text = "35%"?
- těžko fundovaně radit, když nevím, co která proměnná v kódu znamená, kde se bere a proč?
Mára:8.11.2016 22:28
Děkuji mockrát za reakci i přes to, že jsem kód nepopsal!
procenty jsou instance TextBoxů, ve kterých jsou uložené přesně dané
procenta - tzn. když si uživatel přesně zadá, kolik procent potřebuje
protected List<int> hodnoty = new List<int>() ; // uložené Parsované int hodnoty
protected List<TextBox> textboxy = new List<TextBox>(); // objekty TextBox - parsuji do protected Listu hodnoty
protected List<Label> labely = new List<Label>(); // text - nijak nezpracovávám
protected List<TextBox> procenty = new List<TextBox>(); // čtu a používám při výpočtech
tyhle Listy mám v
public partial class MainWindow : Window
To, čeho se snažím dosáhnout v kódu, který se nachází pod
if (bodovy_soucet >= 360000)
{
procenta = 0.32;
}
je to, že pokud má uživatel ve své síti 35 a nebo 32, tak mu podle toho
vypočítá provizi
to, že má uživatel 35, nebo 32 se zjistí pomocí Listů, ve kterých jsou
uloženy při
if (s >= 360000 && (procenty[i].Text != "35%") && (procenty[i].Text != "37%") && (procenty[i].Text != "39%") && (procenty[i].Text != "40%"))
{
odecet = odecet + s * 0.32;
seznamtricetdvojek.Add(s);
}
if (procenty[i].Text == "35%")
{
odecet = odecet + s * 0.35;
seznamtricetpetek.Add(s);
}
Pokud má jednu 32(a zároveň když odečteme od bodovy_soucet tuhle 32, musí vyjít číslo větší než 300 000), jeho procenta jsou 35
Pokud má dvě 32(stejná podmínka), jeho procenta jsou 37 - zároveň se snažím ošetřit to, že kdyby měl méně než 300 000, tak se zkusí podívat, jestli aspoň ta jedna má dostatek, a pak by jeho procenta byli 35
Pokud má tři 32(stejná podmínka), procenta = 39 - zároveň se snaží ošetřit dvě, když to nestačí tak jednu 32
Pokud má alespoň tři 35 - procenta jsou 40, zároveň zkouší další možnosti, když je míň než 300 000 (tzn. měl by odebrat největší prvek ze seznamu(Listu hodnoty), atd. pokud už je 35 méně než tři, tak zkusí všechny možnosti 32)
Přikládám ještě celý kód, okomentovaný a snad lépe viditelný.
Děkuji, pokud bys mi byl ochoten zase odpovědět:)
kód
Obávám se, že přesně takovýto kód je neobjektový kód. Nebudu ti to přepisovat, ale dám ti jednoduchý příklad na kterém to třeba pochopíš.
1)
class pocitani : textove_prvky // textove_prvky dědí MainWindows - takže jsou v ní ty protected Listy v MainWindow
{
Už todle je hodně špatně.. Ty máš Model, tedy věc čisté logiky.. ten tvuj class Pocitani nic jineho ani neni.. a ty abys dostal hodnoty textboxu, tak si podedis od Main_WINDOW????
Pokud vim, tak ty potrebujes dostat jen ty jejich hodnoty,.. spravny pristup (je jich spoustu) je poslat si do vypocitej ty hodnoty tech textboxu.
- Mas tam asi tak 100 podminek, ktere ti kontroluji urcite meze a na zaklade toho nejak modifikuji odecet, procenta atp,
Todle je naprosto ideální čas na to udělat si nějaký třeba List "mezí a modifikací". Dám ti jednoduchý příklad v pseudokodu.
class Procenta {
int horniMez;
intDolniMez;
int procenta;
getProcenta() {
return procenta;
}
bool vyhovuje(int value) {
return value>=dolniMez && <hornimez;
}
}
List<Procenta> procentaList = new...;
procentaList.Add(new Procenta(10000, 20000, 0.04);
procentaList.Add(new Procenta(20000, 40000, 0.08);
a použití místo těch 10 000 podmínek:
procenta = procentaList.First(x=>x.vyhovuje(bodovy_soucet)).getProcenta();
Samozřejmě by si mohl ten LINQ nahradit vlastní třídou atp. Toto řešení má spoustu i dalších výhod.. například... pokud se ti změní ty hodnoty a meze pro procenta.. změníš jen to přidávání do listu.. nebo to můžeš číst z configu atp.
Toto je objektový přístup.Cela ta metoda vypocitej, by se dala pomoci ruznych navrhovych vzoru (State, Behavior) a nastroju OOP (polymorfismus) smrsknout tak na 1/10 a hlavne by to bylo zcela pochopitelne co to dela.. Takhle je to jen dlouhy nic nerikajici kod.
Píši ti to protože tě očividně zajímá OOP... Správné OOP se ale nikde úplně neučí a tak ti povím, co ti může dobře napovědět, že nějaký kód nen napsaný jako spávné OOP, ale jen imperativní kod s classama...
- Obsahuje tam prave podobný decision tree pomocí 20ti ifu, co tam ty máš - tomudle se říká branching a v OOP se řeší často pomocí nějakého vnitřního stateu (tam se používá návrhový vzor state, předek- potomek a polymorfismus.)
- Objekty mají public settery.
+20 Zkušeností
+2,50 Kč
Mára:9.11.2016 8:50
Moc děkuji za tvoji reakci, hodně jsem si z toho vzal a jsem rád za rady. Ale je pro mě stále záhadou, jak pomocí OOP tam dostat ty podmínky týkající se tohohle kódu.
if (seznamtricetdvojek.Count() == 1)
{
int pomocna_promenna = 0;
foreach (int s in seznamtricetdvojek)
{
pomocna_promenna = pomocna_promenna + s;
}
if (bodovy_soucet - pomocna_promenna >= 300000)
{
procenta = 0.35;
}
else
procenta = 0.32;
}
Ja jsem z toho kodu silne ponekud nesvuj , mozna kdyby si to popsal matematickou funkcí, poznas ze to jde pomoci matematickyh pravidel pretransformovat na neco rozumnejsiho. Takhle to vypada jako nejaka matematicka posloupnost, z toho co jsem pochopil.
Ten kod co si daval nahore moc nedava smysl sam o sobe..
- Kouknes se jestli nejaky "SEZNAMTRICETDVOJEK" ma jeden prvek a pokud ano, tak to projizdis foreachem? :-/
- Neomezuj se v C# zadnyma programovacíma paradigmatama. C# zvládá velmi dobře libovolnou kombinace OOP, imperativního a funkcionalniho programovani.
Opět příklad:
if (seznamtricetdvojek.Count() == 1)
{
int pomocna_promenna = 0;
foreach (int s in seznamtricetdvojek)
{
pomocna_promenna = pomocna_promenna + s;
}
if (bodovy_soucet - pomocna_promenna >= 300000)
{
procenta = 0.35;
}
else
procenta = 0.32;
}
Lze převézt na třeba:
procenta = (bodovy_soucet - seznamtricetdvoje.Sum()) >= 30000 ? 0.35 : 0.32;
a stále je to velmi čitelné = stačí pohled na to a hned je každému jasné, co to dělá.. Je mu totiž hned jasné, že v tom není žádná složitá logika.
kdežto pokud tam dáě těch 25řádek kódu, tak bude každý luštit, co to vlastně dělá.
Přesto, že jsem mluvil o tom, že tvůj kód není OOP, tak nesdílím názor Čápky (autora těch článků), že OOP je samospásné a neOOP kód je spaghetti. Využij jedné z největších výhod C# a sice to, že jde o tzv. multi-paradigmatický jazyk.
Zatímco pro řízení programu můžeš dobře použít OOP, na matematické výpočty (jako jsou tvoje procenta) se hodí třeba zase jeho funkcionální číst, případně kombinace funkcionální+OOP.
NO.. a pak je tam ještě další level. A sice reactive extensions.. ale tim te nebudu zatezovat
Zobrazeno 7 zpráv z 7.