Diskuze: Ternary operator a volani metody
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.


Atrament:31.1.2022 17:45
Máš proměnnou `url ` s hodnotou www.eviltester.com. Pomocí ternárního operátoru do této proměnné vložíš novou hodnotu v závislosti na tom zda je splněna podmínka (první část ternárního operátoru, ta před otazníkem). Podmínka je zda hodnota uložená v url začíná na http, pokud ano použije se k přiřazení hodnota v druhé části ternárního operátoru (mezi otazníkem a dvojtečkou). Jelokož je tam opět url tak se vlastně původní url nezmění. Pokud podmínka není splněna tak se použije hodnota ve třetí části, v té od dvojtečky do konce. Tam máš volání té funkce addHttp(), takže se použije to co ta funkce vrátí. Před hodnotu url vloží http. Celá věc znamená 'pokud url začíná na http tak nic nedělej jinak ji doplň o http na začátku.
DarkCoder:31.1.2022 21:33
Nejsem Java programátor, ale co to celé nezapsat takto:
public String strHttpAddress(String url){
return (url.startsWith("http")) ? (url) : ("http://" + url);
}
Viz forko programujte.com. Ternary operator je alternativa pro zapis IF
url = podminka ? operace_pro_true : operace_pro_false;
url = url.startsWith("http") ? url : addHttp(url);
if (url.startsWith("http"))
{ // operace_pro true
url = url;
}
else
{ // operace_pro false
url = addHttp(url);
}
// nebo, protoze pro true je url=url, to muzes zapsat jako
if (!url.startsWith("http"))
{
url = addHttp(url);
}
Proc je tam tolikrat url? Protoze to tam musi byt. Je tedy mozne predelatten kod tak, aby se to nemuselo tolikrat psat, to sem ti tam tez psal, ale ma to vse nevyhody. Ale chapu tvuj dotaz. Ono je to totiz tak, ze vse v tom zapise muze byt uplne jina promena. A pak uz to dava smysl to tam tolikrat psat?
url = url.startsWith("http") ? url : addHttp(url);
a = null
b = 'http'
c = "www.eviltester.com"
d = c
e = c
a = b.startsWith(c) ? d : addHttp(e);
// na tom je jeste matouci, ze se pouzivaji 2 odlisne konstrukce funkce, takhle by ti to mozna davalo vetsi smysl
a = stringStartsWith(b, c) ? d : addHttp(e);
"Z return vy jde nejaký výsledek, co se s ním stane, uloží se do
promenné"
Opet, chapu tvuj dotaz, ale nam ostatnim se jevi nesrozumitelne. Ptas se na
neco, co tak proste je.
String addHttp(String text_input)
{
return "http://" + text_input;
}
Jak ti to nejlepe priblizit...
Mas treba krabicku s otvorem nahore vlevo a dole vpravo.
Kdyz zhora pustis vodu, tak dole vyteka voda obarvena cervene.
Krabicka umi prijimat vstupni data, pruhlednou vodu a umi generovat vystupni
data, cervenou vodu.
addHttp(url); // kdyz tu funkci pouzijes takto, tak vygeneruje stale cervenou vodu, ale, protoze ji nikde neulozis, tak se zahodi, smaze
x = addHttp(url); // a kdyz tu funkci pouzijes takto, tak cervenou vodu ulozis do promene x
Tohle je asi jasne.
1)
String addHttp(String text_input) // funkce stale returnuje, jen jsem to napsal jinak
{
String text_output;
text_output = "http://" + text_input;
return text_output;
}
2)
void addHttp(String text_input) // funkce zadny return nema, zadna cervena voda netece. --- vsimni si, ze pri definici funkce se ztratilo na zacatku String, prave proto, ze nechci zadny return
{
String text_output;
text_output = "http://" + text_input;
dalsi_funkce(text_output); // Ale, muze data predavat dalsim funkcim, treba
}
3)
String addHttp(String text_input) // funkce stale returnuje
{
String text_output;
text_output = "http://" + text_input;
dalsi_funkce(text_output); // a muze data predavat dalsim funkcim
//text_output = dalsi_funkce(text_output); // nebo muze data predavat dalsim funkcim, ktere data dal upravuji
return text_output;
}
Cili, kdyz ma funkce return, tak jeji data zustavaji na vystupu funkce. A je
na tobe, zda si je prevezmes ci ne.
3 - je pripad, kdy funkce predava data jinym funkcim a soucasne returnuje. To se
tez pouziva. Proste, nekdy potrebujes return a jindy nee.
Treba, kdyz mas funkci odesli_mail, tak potrebujes vedet, zda mail byl ci nebyl
odeslan. Tak ti funkce vraci true/false. Ale, jsou pripady, kdy te to nezajima,
tak si ten stav nikde neukladas.
// posli mail a vypis zpravu uzivateli, kdyz se odeslani nepodari
odeslan = posli_mail('adresa', 'text')
if (odeslan==false) { vypis_zpravu('Nastala chyba, mail nebyl odeslan'); }
// posli mail a vypis zpravu uzivateli, kdyz se odeslani nepodari
if (posli_mail('adresa', 'text')==false) { vypis_zpravu('Nastala chyba, mail nebyl odeslan'); } // return funkce k necemu pouzijes, pro dalsi funkci
// uzivatele oznameni o odeslani nezajima, tak muzes napsat do kodu jen
posli_mail('adresa', 'text'); // return funkce zahodis, nevyuzijes
// posli nekolik mailu a vypis zpravu uzivateli, kdyz se nektere odeslani nepodari
text = '';
cyklus (seznam_adres as adresa)
{
if (posli_mail('adresa', 'text')==false) { text += 'Nastala chyba, mail nebyl odeslan na adresu' + adresa); }
}
vypis_zpravu(text);
Jeste mozna jedna vec. Ty muzes zanorovat funkce do sebe. Vyuzijes jejich return pro dalsi funkci.
text = '123'
text = pridej_koncovku_pdf( pridej_datum( nahrad_znaky_nepismena ( preved_na_mala_pismenka ( odstranDiakritiku(text) ) ) ) );
// Znalosti, o které se chceš podělit = text na zacatku
// Znalosti, o ktere se chces podelit
// znalosti, o ktere se chces podelit
// znalosti_o_ktere_se_chces_podelit
// znalosti_o_ktere_se_chces_podelit_2022_02_01
// znalosti_o_ktere_se_chces_podelit_2022_02_01.pdf = text na konci
josef klouda:2.2.2022 14:50
Peto, dekuji moc za tvuj cas. Jeste naposled se vratim ke kodu s tern. operatorem.
- snazil jsem se to shrnout do dvou poznamek u kodu, chapu to zhruba dobre?
Mel jsem se tak optat hned, mozna bych predesel mnohým nedorozumenim, nekdy
neni lehke formulovat dotaz.
Dekuji
@Test
public void moreTernary(){
String url = "www.eviltester.com";
url = url.startsWith("http") ? url : addHttp**(url)**; //tato promena tedy tady musi byt, jinak by funkce nevedela s cim pracovat??
assertTrue(url.startsWith("http://"));
assertEquals("http://www.eviltester.com", url);
}
private String addHttp(String url) {
return "http://" + url; //jak funkce vi, ze ma vystup priradit do url promenne, podle udaje z ternary operatoru addHttp(url) ??
}
private - typ funkce v class, ze bude private, neni mozne ji zavolat z venku class
String - VYSTUP_FUNKCE
addHttp(String VSTUP_FUNKCE)
{
return "http://" + VSTUP_FUNKCE;
}
Assemblerovy kod, ktery z toho generuje prekladac pro procesor:
adresa pameti, znak (textovy znak nebo asseblerovy prikaz)
100-108: "seznam.cz"
... {
4538: zkopiruj z adresy 100-108 na adresu 200-208, 8 znaku .... zkopijruj obsah url z addHttp(url) do VSTUPU funkce
4539: zapis na adresu 193-199 7 znaku (z adresy 4540-4546) ... "http://" + VSTUP;
4540-4546: "http://"
4547: nastave return na adresu pameti 200-208 ... return
4548: skoc na jinou oblast pameti a pokracuj v pameti ... }
Ta funkce dela tedy to, ze prepise nejake misto v pameti. A return vraci adresu pameti, kde je ten text ulozeny a jeho delku. Tu si prevezme funkce ternarniho operatoru
A ta funkce ternarniho operatoru vraci adresu pameti vysledku.
A pokud ji chces zachranit pred smazanim, tak si ji muzes ulozit do promene.
private String addHttp(String url) {
return "http://" + url;
}
addHttp(url) // takhle se vykona funkce, ale return hodnota je nenavratne smazana
x = addHttp(url) // a takhle si ji ulozis do promene X
Ternarni operator si muzes napsat jako funkci
ternarniOperator(podminka, vystup_a, vystup_b)
if (podminka)
{
return vystup_a;
}
else
{
return vystup_b;
}
//url = url.startsWith("http") ? url : addHttp(url);
x = ternarniOperator( url.startsWith("http"), url, addHttp(url) )
url.startsWith("http") ? url : addHttp(url); // takhle je vystup nenavratne smazan
x = url.startsWith("http") ? url : addHttp(url); // takto si ho ulozis do X (nebo url nebo jine promene)
Ten zapis pro smazani se tez pouziva, obcas, kdyz vystup nepotrebujes
Cili, vystup funkce se uchovava jen po dobu, dokud je treba jej nekomu
predat, dokud jej nekdo chce.
Kdyz reknes, ze ho nechces, ze ho neulozis ani do X ani nepredavas dalsi funkci,
tak jej procesor nemilosrdne smaze.
Da se k nemu dostat jen nahodou nebo chybou, kdyz si prectes obsah pameti na
adrese pameti, kam procesor ten vystup zrovna ulozil. To presne delaji hackeri.
snazi se ziskat informace, ktere meli byt smazane nebo nejsou pro ne urcene. ale
v pameti nekde stale jsou.
Nebo to zkusim popsat jeste jinak. Jak uz jsem psal, kazda ta promena muse byt jina. tam to mozna bude jasneji videt na kodu.
private String addHttp(String f) {
return "http://" + f;
}
a = b.startsWith(c) ? d : addHttp(e);
// 1 - do fukce addHttp() posli E
// ta jej prevezme, ale programator si E pro vnitrek fukce pojmenoval jako F
// a tato funkce navraci hodnotu, kterou si muzes, ale nemusis ulozit nebo predat dalsi funkci (XXX)
// 2 - do funkce startsWith() nad objektem B posli hodnotu C
// vnitrek te funkce tady nemas definovany, ale pracuje s B i C
// a tato funkce navraci hodnotu, kterou si muzes, ale nemusis ulozit nebo predat dalsi funkci (YYY)
// a = podminka ? hodnota_pro_true : hodnota_pro_false;
// 3 - do funkce ternarniho operatoru posli podminku=YYY, hodnotu pro true D, hodnotu pro false XXX
// pokud je podminka true, navraci funkce D
// pokud je podminka false, navraci funkce XXX
// a tuto hodnotu si pak muzes ulozit (a = ...) nebo predat dalsi funkci
- tato promena tedy tady musi byt, jinak by funkce nevedela s cim pracovat??
Ta funkce by nedostala zadna data ke zpracovani. A podle toho, jak je
napsana, tak by prekladac napsal error nebo by se uvazovalo, ze je string
prazdny "" a navracela by tedy vysledek operace
return "http://" + "";
- jak funkce vi, ze ma vystup priradit do url promenne, podle udaje z ternary operatoru addHttp(url) ??
To sem se ti snazil prave popsat. Ta funkce nema s externi promenou (s
promenou mimo kod funkce) nic spolecne. Ta dokaze prevzit data a vyplodit nejaky
vystup. Nic vic. (aspon podle toho, jak je napsana)
Ten vystup si pak musis ty nejak zpracovat. V tomhle pripade jej predavas funkci
ternarniho operatoru.
A ternarni operator pak rozhoduje, ktery z jeho vstupu bude on returnovat.
A jeho return si prirazujes do promene. Ja jsem ji prejmenoval na A (ty ji mas v
kodu pojmenovanou URL).
URL = podminka ? hodnota_pro_true : hodnota_pro_false;
Obecne, v tom kodu se nemusi vsechny promene jmenovat url, url, ... ale muzou
tam byt uplne jine jmena. To sem se ti tez pokousel napsat.
Ale, to, co chces programem docilit, tak potrebuje jen s URL.
==========
Jeste jinak ti zkusim vysvetlit.... Na necem, co znas.
x = a * b // nasobeni, zakladni skola
--------------------
// seznam funkci
Integer nasobeni (Integer c, Integer d)
{ return c * d; }
Integer deleni (Integer e, Integer f)
{ return e / f; }
// program
x = nasobeni (a, b) // vysledek funkce si ulozis do X
----------
// nebo tam muzes napsat vsude a, b
// ale jmeno A ve funkci nasobeni neni nijak propojene se jmenem A z radku `x = nasobeni (a, b)`,
// jedna se o jine misto v pameti, kam si funkce zkopiruje data, ktera ji posles
// tim, ze tam mas prave vsude url, tak ti to muze pripadat matouci
// seznam funkci
Integer nasobeni (Integer a, Integer b)
{ return a * b; }
// program
x = nasobeni(a, b)
y = nasobeni(3, 2) // y = 6
z = nasobeni(3, deleni(8, 2) ) // ---> krok1: deleni(8, 2) = 4 ---> krok2: nasobeni (3, 4) = 12 ---> z = 12
Nejdrive se provede funkce deleni(8, 2)
a jeji vysledek predas
nasobeni a nasobeni po ukonceni preda vysledek do Z.
// nebo totez muzes napsat takto
a = 8
b = 2
c = 3
d = deleni(a, b)
z = nasobeni(c, d)
Cili, ten kod, ktery tam mas, se jen snazi nejakym zpusobem zprehlednit mene dulezite operace. Aby se to nemuselo prilis rozepisovat a ukladat do spoustu promenych.
-----
// muzes si to klidne rozepsat, pokud se v tom vic vyznas
// url = url.startsWith("http") ? url : addHttp(url);
url = "www.eviltester.com"
a = url.startsWith("http") // vypocitej podminku, ta muze byt jen TRUE/FALSE
b = addHttp(url) // vypocitej B
x = a ? url : b; // dosad do ternarniho operatoru A, url a B
Jenze, tim naprosto zrusis vyhodu ternarniho operatoru. Ten funguje totiz tak, ze kdyz nemusi, tak ten kod nevykona, cim se usetri cas, zvysi rychlost behu programu. Jako IF a ELSE.
url = url.startsWith("http") ? url : addHttp(url);
// vypocitej podminku url.startsWith("http")
// kdyz je true, pouzij url
// kdyz je false, vypocitej funkci addHttp(url);
// v tomto pripade se cast v true nebo false vubec nemusi pocitat
// ale pri tom rozepsani, co sem napsal pred tim, si vypocitavas vsechno predem a pak dosazujes do terrnarnho operatoru
oprava
//x = a ? url : b;
url = a ? url : b; // ty vlastne chces vysledek ukladat do url, tak by muselo byt misto x na zacatku `url =`
S tou pameti zkusim to napsat srozumitelneji. Program je totiz jen kod v pameti. O tom, ze je neco instrukce a neco text rozhoduje kod programu. Ale, pro zjednoduseni dam stringy na zacatek. Kod programu napisi jako pismenka (aby to jako obrazek vypadalo hezky)
return "http://" + url;
| _ | _ | _ | _ | _ | _ | _ | _ | _ | _ | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |...
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| s | e | z | n | a | m | . | c | z | h | t | t | p | : | / | / | A | B | C | D | E | F | G | h | I | J | K | L
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
A = zkopiruj od B (B = 10), C (C = 6) znaku a uloz na D (D = rekneme 100)
(cili, zkopiruj od pozice 10, 6 znaku a uloz je na pozici 100)
E = zkopiruj od F (F = 0), G (G = 10) znaku a uloz na H (H = 106)
I = vrat procesoru, ze se vysledek naleza v pameti na pozici J (100) a ma delku K(16) znaku
return "http://" + url;
return (zkopiruj z pozice 10, 6 znaku) + (zkopiruj z pozice 0, 10 znaku)
vrat procesoru, ze vysledek spojovani dvou stringu v pameti se nachazi na pozici 100 a ma delku 16 znaku
Program, ktery je ve stejne pameti jako stringy http a seznam, tak se
zkopiruje do pameti procesoru. Nejak se to zpracuje, provedou se operace s
pameti a uzivateli vraci misto v pameti, kde najde vysledek (uklada jej vnitrni
pameti procesoru). A toto cislo pozice pak pouzije dalsi cast programu (pismenko
L).
Pokud nemas ve funkci return, tak dalsi ukladani nedela.
(Ale ty muzes pred ukoncenim funkce ulozit pozici do jine casti pameti - promene
z venku, pokud chces)
Pokud si tu informaci neprevezme dalsi cast programu, tak pri pristim pouziti
podobne instrukce nenavratne prepise.
- Cili, kdyz tam nedas return, tak se informace neulozi do pomocne pameti procesoru a pozdeni nenavratne ztrati.
- Kdyz tam return das, informace se ulozi do pomocne pameti a dalsi instrukci ji muze pouzit.
url = url.startsWith("http") ? url : addHttp(url);
url = prevezmi_hodnotu_z_procesoru ? url : addHttp(url);
url = smazano ? prevezmi_hodnotu_z_procesoru : preskoc; // stav = true
url = smazano ? preskoc : prevezmi_hodnotu_z_procesoru; // stav = false --- stav, kdy pouzil addHttp(url);
url = prevezmi_hodnotu_z_procesoru
Cili, hodnotu muzes ztratit hned 2x.
Kdyz addHttp
nebude mit return.
A kdyz si hodnotu zapomenes ulozit do promene url = hodnota
Nevim, teda, jestli to pochopis. Proste, ta hodnota je vzdy nekde v hlavni
pameti, nebo procesorove pameti. A ztrati se jen, kdyz pamet prepises (pouzijes
nejakou instrukci, ktera do mista te pameti ulozi nove informace).
Kdyz se neprepise, tak v te pameti obvykle zustava. Nekdy i po ukonceni
programu. A je mozne se k ni dostat, pokud vis, kde je (adresu pameti od-do) a
delaji to hackeri, ze si takhle najdou v pameti prihlasovaci udaje uzivatele.
Pamet se z uspornych duvodu (spotreba elektriny, rychlosti programu) nemaze
automaticky, pouze, kdyz si to vynutis programem..
Zobrazeno 10 zpráv z 10.