V Bostonu probíhá konference Red Hat Summit 2025. Vybrané přednášky lze sledovat na YouTube. Dění lze sledovat na síti 𝕏 (#RHSummit).
Společnost Red Hat oficiálně oznámila vydání Red Hat Enterprise Linuxu 10. Vedle nových vlastností přináší také aktualizaci ovladačů a předběžné ukázky budoucích technologií. Podrobnosti v poznámkách k vydání.
Tuto sobotu 24. května se koná historicky první komunitní den projektu Home Assistant. Zváni jsou všichni příznivci, nadšenci a uživatelé tohoto projektu. Pro účast je potřebná registrace. Odkazy na akce v Praze a v Bratislavě.
Troy Hunt představil Have I Been Pwned 2.0, tj. nový vylepšený web služby, kde si uživatelé mohou zkontrolovat, zda se jejich hesla a osobní údaje neobjevili v únicích dat a případně se nechat na další úniky upozorňovat.
Microsoft představil open source textový editor Edit bežící v terminálu. Zdrojové kódy jsou k dispozici na GitHubu pod licencí MIT.
V Seattlu a také online probíhá konference Microsoft Build 2025. Microsoft představuje své novinky. Windows Subsystem for Linux je nově open source. Zdrojové kódy jsou k dispozici na GitHubu pod licencí MIT.
Z příspěvku Turris Sentinel – co přinesl rok 2024 na blogu CZ.NIC: "Za poslední rok (únor 2024 – únor 2025) jsme zachytili 8,3 miliardy incidentů a to z 232 zemí a z jejich závislých území. Tyto útoky přišly od 6,2 milionu útočníků (respektive unikátních adres). SMTP minipot je stále nejlákavější pastí, zhruba 79 % útoků bylo směřováno na tento minipot, 16 % útoků směřovalo na minipot Telnet, 3 % útoků směřovaly na minipot HTTP a 2 % na minipot FTP. Dále jsme zaznamenali 3,2 milionu unikátních hesel a 318 tisíc unikátních loginů, které útočníci zkoušeli."
Byla vydána (Mastodon, 𝕏) nová verze 3.0.4 svobodné aplikace pro úpravu a vytváření rastrové grafiky GIMP (GNU Image Manipulation Program). Přehled novinek v oznámení o vydání a v souboru NEWS na GitLabu. Nový GIMP je již k dispozici také na Flathubu.
Byla vydána nová stabilní verze 7.4 webového prohlížeče Vivaldi (Wikipedie). Postavena je na Chromiu 136. Přehled novinek i s náhledy v příspěvku na blogu.
Spolek vpsFree.cz vydal statistiky týkající se distribucí nasazených na serverech členů. V dlouhodobém pohledu je zřejmé, že většina uživatelů z původního CentOS přechází na Rocky Linux. Pozoruhodný je také nárůst obliby distribuce NixOS, která dnes zaujímá třetí místo po Debianu a Ubuntu.
Foreach cyklus s podmienkou prázdneho poľaTo jsem neznal, díky
Python 3.3.3 (default, Mar 27 2014, 16:17:16) Type "copyright", "credits" or "license" for more information. IPython 1.2.1 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: kosik = ["mlieko", "maslo"] In [2]: for produkt in kosik: ...: print(produkt) ...: else: ...: print("Prazdny nakupny kosik") ...: mlieko maslo Prazdny nakupny kosik
the else suite is executed after the for, but only if the for terminates normally (not by a break).To je dost rozdíl
$rows = array_map(
function($r) { return str_getcsv($r); },
explode("\n", file_get_contents('produkty.csv'))
);
$header = array_shift($rows);
foreach ($rows as $row) {
$produkt = (object)array_combine($header, $row);
echo "{$produkt->nazov} - {$produkt->cena} EUR\n";
}
$rows = array_map( function($r) { return str_getcsv($r); }, explode("\n", rtrim(file_get_contents('produkty.csv'))) ); $header = array_shift($rows); foreach ($rows as $row) { $produkt = (object)array_combine($header, $row); echo "{$produkt->nazov} - {$produkt->cena} EUR\n"; }
v PHP mozes "Zistenie prítomnosti kľúča v asociatívnom poli" spravit ako if($pole[kluc])
V tomto pripade je to presne to iste co si uviedol pre python
tiez "Posledný prvok poľa" nacitas ako end($pole)
ale inak super clanok, ako cloveku co pisem v php aj pythone mi rozsiril obzory :)
člověk ale musí vědět přesně, co chce (z hlediska očekávaných hodnot v poli), např.v PHP mozes "Zistenie prítomnosti kľúča v asociatívnom poli" spravit ako
if($pole[kluc])
$a = array('a' => 0, 'b' => null, 'c' => 1);
foreach (array_keys($a) as $k) {
if ($a[$k]) echo "$k\n";
}
if($pole[kluc])
bude ak neexistuje kľúč generovať varovanie. Okrem toho ak $pole[kluc]
sa vyhodnotí ako false potom to bude vyzerať ako keby kľúč nebol v poli. Celkom schodnou cestou je operátor isset
.
isset
a rve se to tam "natvrdo", má to velmi negativní dopady na výkon.
if($pole[kluc])
je dost kravina (jak bylo už naznačeno).
$a = array(false, NULL, 0); echo "${a[0]} - ${a[1]} - ${a[2]}"; if( $a[0] || $a[1] || $a[2] ) { echo "Aspoň jeden existuje.\n"; }
array_key_exists()
, kjterá by měla být efektivnější než isset()
(i když podle toho, co jsem kdysi zkoušel, v tom velký rozíl nebyl).
Jinak na rozpoznání toho, jestli funkce vrací false
, protože se na to převedla výsledná hodnota, nebo false
, protože nic nenašla, je operátor ===
, viz Comparison Operators.
isset()
u klíče, jehož hodnota je NULL
, vrací false
. Kdežto array_key_exists()
v takovém případě vrací true
! Viděl jsem z toho nepěkné bugy.
Právě z tohoto důvodu je v PHP i funkce array_key_exists(), kjterá by měla být efektivnější než isset() (i když podle toho, co jsem kdysi zkoušel, v tom velký rozíl nebyl).Ve skutečnosti je zřejmě výrazně méně efektivní. Problém u isset() je v tom, že pokud je hodnota v poli NULL, je výsledkem FALSE. V případech, kdy by to vadilo, lze použít array_key_exists() nebo oba přístupy kombinovat, čímž se dosáhne vcelku slušné rychlosti.
!empty()
, což sice nerozlišuje mezi chybějící a nulovou hodnotou, ale pokud chci vědět, zda tam něco je, tak je to dobrá volba (isset(false) == true
, ale !empty(false) == false
).
V případech, kdy se hodí použít array_key_exist()
je často možné místo null
použít false
a pak funguje isset(). Například pokud chci kešovat objekty v poli a je potřeba nakešovat informaci o neúspěšném pokusu o vytvoření.
!empty()
. Těch způsobů je několik a každý se chová trošku jinak.
// $k je hledaný klíč v poli $a. if (array_key_exists($k, $a)) // $k existuje, na hodnotě nezáleží if (isset($a[$k])) // $k je v poli a hodnota není null if (@ $a[$k] !== null) // totéž if (!empty($a[$k])) // $k je v poli a hodnota je neprázdná (není to null, false, 0, '', array()) if (@ $a[$k]) // totéžPřičemž
array_key_exists
je nejpomalejší, neboť je to jediné plné volání funkce a ostatní jsou jazykové konstrukce. (Nejsem si jist, zda to nebylo v posledních verzích optimalizováno; v 5.3 to tak bylo.)
Další docela elegantní konstrukce je toto:
$y = @ $k[$v];Docela rád toto používám při načítání konfigurace např. z JSON, kdy volba nemusí být uvedena a výchozí hodnota je null či false.
$ code='if (isset($a[$i])) { $y += $a[$i]; }' ; time for f in `seq 1 10` ; do php -r '$a = array(); $y = 0; $start = microtime(true); for ($i = 0; $i < 1000000; $i++) { '"$code"' }; echo (microtime(true) - $start), "\n";' 2> /dev/null ; done | awk '{ total += $1 } END { print "code\t" total "s"}' code 0.760216s real 0m1.380s user 0m1.156s sys 0m0.204s
$ code='if (!empty($a[$i])) { $y += $a[$i]; }' ; time for f in `seq 1 10` ; do php -r '$a = array(); $y = 0; $start = microtime(true); for ($i = 0; $i < 1000000; $i++) { '"$code"' }; echo (microtime(true) - $start), "\n";' 2> /dev/null ; done | awk '{ total += $1 } END { print "code\t" total "s"}' code 0.973294s real 0m1.599s user 0m1.356s sys 0m0.220s
$ code='$y += @ $a[$i];' ; time for f in `seq 1 10` ; do php -r '$a = array(); $y = 0; $start = microtime(true); for ($i = 0; $i < 1000000; $i++) { '"$code"' }; echo (microtime(true) - $start), "\n";' 2> /dev/null ; done | awk '{ total += $1 } END { print "code\t" total "s"}' code 13.0701s real 0m13.690s user 0m13.448s sys 0m0.196s
$ code='$y += $a[$i];' ; time for f in `seq 1 10` ; do php -r '$a = array(); $y = 0; $start = microtime(true); for ($i = 0; $i < 1000000; $i++) { '"$code"' }; echo (microtime(true) - $start), "\n";' 2> /dev/null ; done | awk '{ total += $1 } END { print "code\t" total "s"}' code 22.2458s real 0m22.862s user 0m20.560s sys 0m2.252sTedy verze se zavináčem je oproti
isset()
17× pomalejší, ale pořád dvakrát rychlejší než bez zavináče. Na druhou stranu je to v řádu desetin mikrosekund.
Ešte k PHP-čku tak pozerám v histórii svojho PHP shellu túto perlu:
$premenna = false; if (premenna && "a" == 0) { echo "Vypíšem sa!\n"; }
Mimochodom tento konkrétny kód sa u mňa vypíše bez varovania (jedine notice ale to kvôli istým "super" projektom mám vypnuté.
To není moc hezké, ale je to tak, nedefinovaná konstanta je brána jako "text" a neprázdný text je true
, což umožňuje taky chod některých aplikací píšících array[my_text_key]
.
No a 'a' se implicitně na číslo převede jako 0, chce to přidat jedno rovná se.
template<class Tint> static Tint randInteger(Tint max){ Tint v; rand(reinterpret_cast<unsigned char *>(&v), sizeof(Tint));//get uchar random array if(v < 0) v=static_cast<Tint>(v*(-1));//positive only assert(v >= 0); return static_cast<Tint>(v % (max)); }, která valila jednou za uherák s
randInteger<int64_t>(cca_INT64_MAX);
(nebo s unsigned typy) a dobré, ale nedávno jsme ji použil s randInteger<int8_t>(42);
a najenou to začalo sem tam lítat na tom assert-u - hledíš jak čáp do trubky a nedocvakne ti to (teda já a mně array()
a []
je totéž. Tedy lze zapsat [1, 2, 3]
a ['a' => 4, 'b' => 5, 'c' => 6]
. Od PHP 5.4.
$output = array_filter($p, function($p) { return ($p['cena'] < 10); });
To s kolekciami moc nesúvisí. Inak je to jedna zo syntaktických blbostí v pythone ktorej som dlho nevedel prísť na chuť. Ale tak po pár mesiacoch písania viacej v pyhtone sa mi to zdá už celkom prirodzené ale používam tak raz za uhorský rok. Pre PHP-čkárov ak by teda chceli vedieť je tento kód v PHP:
$cena = $produkt["cena"] == 0 ? "Nepredajné" : $produkt["cena"];
Je ekvivalentný tomuto v pythone:
cena = "Nepredajné" if produkt["cena"] == 0 else produkt["cena"]
alebo
cena = produkt["cena"] or "Nepredajné"
$cena = $produkt["cena"] ? : "Nepredajné";
cena = produkt["cena"] or "Nepredajné"Toto funguje stejně i v Pythonu.
Ako sa to tak vezme, kvôli určitým (v istých situáciách dosť nepríjemným) vlastnostiam pythonu je to veľmi veľmi veľmi užitočná konštrukcia (samozrejme v rozumnej miere). Ako príklad uvediem defaultné argumenty funkcie. Povedzme chcem napísať niečo takéto:
def funkcia(argument=[]): ...
Python však pracuje s referenciami (aj defaultný argument je referencia), takže pridanie prvku vo volaní funkcie by pri ďalšom volaní spôsobil, že by už defaultný argument bol [prvok]. Dá sa to vyriešiť 2 bežnými spôsobmi:
def funkcia(argument=None): if argument is None: argument = [] # vytvorenie nového listu ...
alebo:
def funkcia(argument=None): argument = argument or [] ...
Pomerne často túto konštrukciu používam aj v djangu kde namiesto odporúčaného zápisu spracovania formulárov v dokumentácii:
def view(request): if request.method == "POST": form = Formular(request.POST) if form.is_valid(): return HttpResponseRedirect(form.save().get_absolute_url()) else: form = Formular() return TemplateResponse(request, "sablona.html", {"form": form})
používam takto:
def view(request): form = Formular(request.POST or None) if form.is_valid(): return HttpResponseRedirect(form.save().get_absolute_url()) return TemplateResponse(request, "sablona.html", {"form": form})
def funkcia(argument=None): argument = argument or []Zrovna toto se mi moc nelíbí, protože to prázdný seznam argumentu (při volání
funkcia([])
) nahrazuje novým prázdným seznamem a z kódu není zjevné, zda je to úmysl nebo chyba. Z toho důvodu bych zde dal přednost explicitnímu zápisu pomocí argument is None
.
form = Formular(request.POST or None)Toto mi naopak přijde fajn, protože jde jen o nahrazení prázdného request.POST za None.
[produkt["cena"], "Nepredajné"][produkt["cena"] == 0]Ale to už je docela prasárna.
?:
Prvně se na něco ptáš, tak tam dáš otazník:
cena == 0 ?
A když jo, tak hned odpověď. Když ne, tak alternativní odpověď, která něčím musí být oddělená, tak proč ne dvojtečkou?
otázka ? odpověď : alternativa
Zas tak složité to není :)
$arg = 'T'; $vehicle = ( ( $arg == 'B' ) ? 'bus' : ( $arg == 'A' ) ? 'airplane' : ( $arg == 'T' ) ? 'train' : ( $arg == 'C' ) ? 'car' : ( $arg == 'H' ) ? 'horse' : 'feet' ); echo $vehicle;Vysledkem je dle php "horse"
echo func()[1];nešlo, zatímco následující kód fungoval:
$a = func(); echo $a[1];To se na první pohled nemusí zdát jako nic tak kritického, ale pokud jste si někdy psali vlastní jazyk, tak vám to nejspíš napoví, jak moc velká prasárna vevnitř musí dynamický jazyk být, aby mohl mít problémy tohohle typu.
empty($riadok1.$riadok2);
Parse error: syntax error, unexpected '.', expecting ')' in php shell code on line 1
empty()
není funkce. Na první pohled je to trošku divné, ale když si uvědomíš, co ta konstrukce dělá, tak to dává smysl.
funkcia()[]
.
const char * arg_to_string(char arg) { switch (arg) { case 'B': return "bus"; case 'A': return "airplane"; ... default: return "feet"; } } int main(int argc, char **argv) { int arg = 'T'; const char *vehicle = arg_to_string(arg); printf("%s", vehicle); }
switch
(PHP bere i řetězce na rozdíl od C, byť tady je to jen znak):
switch($arg){ case 'B': $vehicle='bus'; break; case 'A': $vehicle='airplane'; break; ... default : $vehicle='feet'; break; }nebo to prdnout do fce a return, jak jsi napsal…
vehicle = {"B": "bus", "A": "plane", …}.get(arg, "feet")To snad jde v php napsat taky ne?
switch
a toto je asi nějaký Pythoní zápis nějaké kolekce (odpusť mou neznalost jazyka Python, nelíbí se mí a nepotřebuji jej), což bych do PHP asi přepsal takto (už to ale není funkční, ale datové):
$a = Array("B" => "bus", "A" => "plane", …); $vehicle = isset($a[$arg])?$a[$arg]:"feet";
{}
v pythonu bežně označují asociativní pole (může to být i set, ale to teď vynechme).
To co jsi popsal je ekvivalent:
a = {"B": "bus", "A": "plane", ..} vehicle = a[arg] if isinstance(a, dict) else "feet"(to
isset()
má imho brát jen $a
)
V pythonu jsou ale operace s asociativními polemi velmi běžné, proto mají taky metodu .get()
, která funguje stejně jako indexování přes hranaté závorky, ale zároveň má další argument, který se vrátí pokud není prvek nalezen.
Ten příklad se dá tedy zkrátit do:
a = {"B": "bus", "A": "plane", ..} vehicle = a.get(arg, "feet")
Řekl bych tedy, že fčul máme 4× téměř to samé (3× Python, 1× PHP), ale ne úplně související s if else if else…, což je ten původní zápis přes ?:
nebo také swicth
, který se obvykle||někdy takto rozkládá).
Ne, to isset($a[$arg])
je rozhodně správně (na dvou řádcích nepochybuji o předchozím :), tedy oprávněně očekávám, že to pole existuje…) a mohlo by být zaměněno na in_array($a,$arg)
, pokud by to pole obsahovalo i NULL.
isset()
z mojí strany. V PHP už jsem nějaký pátek nedělal (a doufám ani nebudu).
PHP je to asi buřt výkonově, ale pokud v C/C++, tak je se třeba někdy rozhodovat, jestli to udělat konstantně funkčně, nebo universálně dynamicky a je spoustu případů, kde není třeba a je to spíš na závadu do toho tahat nějaké kolekce či fce a může to mít zbytečný dopad na výkon. Nebo představa, že třeba getopt
pojedu např. přes map-u se mi vůbec nelíbí, ten switch je takový jasný a čitelný (a to platí i pro PHP).
Ah ľudia, už tu nepíšte o výkone lebo ma z toho písania benchmarkov porazí Ale teraz vážne, trochu som sa teda pozrel na výkon týchto vecí v PHP a pythone, v prílohe malé benchmarky. Je to akože časť syntetizátora prirátávajúca amplitútu kanálov s predvypočítanou tabuľkou sinusovky. Teraz k výsledkom:
PHP
Pripočítanie referenčnej hodnoty (0.47): 0.96903800964355 s Sekvencia if/elseif: 1.35397815704350 s Asociatívne pole: 0.98258900642395 s Zreťazený zoznam: 0.97372603416443 s Switch: 1.00940108299260 s
Python
Pripočítanie referenčnej hodnoty (0.47): 1.2208540439605713 s Sekvencia if/elseif: 2.0121259689331055 s Dict: 2.0311729907989500 s List: 1.4741299152374268 s
A teraz trochu nerovný súboj s alterantívnym interpretom pythonu - PyPy
Pripočítanie referenčnej hodnoty (0.47): 0.04258298873901367 s Sekvencia if/elseif: 0.26957798004150390 s Dict: 0.07034182548522949 s List: 0.04564189910888672 s
Dobrý, a kde máš C/C++, kde se s polem dostaneš tak na 0.002 .
Shrňme to, pokud by toho bylo 10000×, tak:
Na takové věci jako v testu se switch určitě nehodí…
-O3
.
Python: PHP: C++
test_ref 0.7845039 0.7905121 0.0020001
test_if 1.8836648 1.6659939 0.0065734
test_dict 1.6601350 1.0982060 0.0428780
test_list 1.2716641 1.6805291 0.0020001
test_switch 1.7170250 0.0029277
test_array 0.0020000
time
(bash) pro první 4 testy:
5.663 5.296 0.048
PS: U C++ je pochopitelně procentní odchylka při opakovaných testech výrazná (je to moc malý vzorek a málo iterací)
a není to ani průkazné pro srovnání jednotlivých testů.
test_list() $this->test_list()
a v test_switch() $test->test_switch()
A co teprve Java 8, která mi při 100 000 opakováních dávala poloviční časy oproti 7
Tak jo, já začnu viz příloha (je to jen jednoduchý přepis toho PHP bez invence).
Dej (dejte oba) Javu
Python: PHP: C++: IMSE: test_ref 0.7845039 0.7905121 0.0020001 0.317491 (0.330483) test_if 1.8836648 1.6659939 0.0065734 1.076216 (1.087590) test_dict 1.6601350 1.0982060 0.0428780 test_list 1.2716641 1.6805291 0.0020001 0.356221 viz popis test_switch 1.7170250 0.0029277 test_array 0.0020000 0.356221 (0.366114) time (bash) pro první 4 testy: 5.663 5.296 0.048
Evidentně je třeba u scrip. jazyků stále tlačit na vývoj a optimalizaci .
$sin_list = [
a nesežralo mi to, ale je fakt, že nemám kdovíjak novou verzi PHP.
Tiskni
Sdílej: