Archiv pro rubriku: Programování

Scheme

Scheme

Tento článek představuje základní konstrukty jazyka Scheme. Uvedené informace se skvěle hodí k získání povědomí o některých dostupných procedurách a vybraných rysech jazyka.

Quote a quasiquote

Quote zabrání vyhodnocení výrazu. Lze zkráceně zapsat jako uvozoku . Zápisy ‚szj.cz a (quote szj.cz) jsou tedy naprosto totožné. Quasiquote se chová shodně jako quote, můžeme si ale vyžádat vyhodnocení vybrané části výrazu. Ke zkrácení se používá symbol `.

‚szj.cz => szj.cz

(quote szj.cz) => szj.cz

`szj.cz => szj.cz

(quasiquote szj.cz) => szj.cz

Unquote a unquote-splicing

Z předchozího se může zdát, že mezi quote a quasiquote neexistuje rozdíl. Tak tomu však není. U výrazu uzavřeného v quasiquote vynutí unquote (zapisovano jako čárka „,„) vyhodnocení následující části.

`(szj.cz (+ 1 1) cz.szj) => (szj.cz (+ 1 1) cz.szj)

`(szj.cz ,(+ 1 1) cz.szj) => (szj.cz 2 cz.szj)

Quasiquote tedy označuje úsek, jenž se nikdy nezmění. Naopak tomu unquote symbolizuje přesný opak.

Dále lze využít unquote-splicing (symbol ,@) chovající se jako unquote, ale s výraznou změnou – výsledný seznam ztratí své vnější závorky.

`(,@`(1 2 3)) => (1 2 3)

Všechny dosud uvedené konstrukty obsahující ve svém názvu quote lze vzájemně vnořovat a kombinovat.

`(szj.cz `cz.szj 10) => (szj.cz `cz.szj 10)

`(szj.cz ,`cz.szj 10) => (szj.cz cz.szj 10)

Povšimněte si, že v následujícím zápisu nedojde k sečtení čísel 1 a 1.

`(szj.cz `(,(+ 1 1) cz.szj) 10) => (szj.cz `(,(+ 1 1) cz.szj) 10)

Unquote zde nebude fungovat, protože se nachází uvnitř druhého quasiquote nikoliv prvního. Po drobné úpravě však dosáhneme kýženého výsledku. Povolíme funkci druhého quasiquote a vše se již chová dle našeho přání.

`(szj.cz ,`(,(+ 1 1) cz.szj) 10) => (szj.cz (2 cz.szj) 10)

Seznam

Každý seznam se skládá ze dvou složek. K té první se přistupuje s pomocí car, druhou část vrátí cdr.

(car ‚(1 . 2)) => 1

(cdr ‚(1 . 2)) => 2

Pokud je druhá složek seznam, vypouští se tečka a závorky příležící k tomuto seznamu. Oba následující zápisy jsou proto totožné.

‚(((1))) => (((1)))

‚(((1).()).()) => (((1)))

O konstrukci páru se stará cons (bere v parametrech první a druhou složku).

(cons (cons (cons 1 ‚()) ‚()) ‚()) => (((1)))

(cons (cons 1 2) (cons 3 4)) => ((1 . 2) . (3 . 4)) => ((1 . 2) 3 . 4)

Car a cdr lze vzájemně sdružovat s pomocí předdefinovaných zkratek – např. cadr nejprve vykoná cdr a poté car, postupuje se tedy obráceně.

(cadr (cons (cons 1 2) (cons 3 4))) => 3

Build-list

Jako první parametr je očekávána délka budovaného seznamu, druhý parametr symbolizuje procedura, jenž bude aplikována na každý prvek nově vznikajícího seznamu, přičemž indexování začíná od nuly.

(build-list 5 -) => (0 -1 -2 -3 -4)

List-ref

Ze zadaného seznamu vrátí prvek na dané pozici. Indexování začíná od nuly.

(list-ref ‚(a b c d) 1) => b

Reverse a length

Jak již název napovídá, length zjišťuje délku seznamu, zatímco reverse provádí obrácení pořadí prvků.

(reverse ‚(a b c d)) => (d c b a)

(length ‚(a b c d)) => 4

Append

Vytváří nový seznam spojením libovolného množství zadaných seznamů.

(append ‚(1 2) ‚(3 4) ‚(5 6)) => (1 2 3 4 5 6)

Map

Aplikuje danou proceduru na každý prvek seznamu a vrátí výsledný seznam.

(map – ‚(1 2 3 4 5)) => (-1 -2 -3 -4 -5)

Pokud je zadáno více seznamů, prochází se postupně od začátku.

(map + ‚(1 2 3 4 5) ‚(1 2 3 4 5)) => (2 4 6 8 10)

Tento výčet nesymbolizuje to jediné, co jazyk Scheme nabízí. Jeho možnosti jdou totiž mnohem dál. K vyzkoušení uvedených příkladů potřebujete vhodný interpret, například Racket.

Detekce rozšíření AdBlock

Plugin AdBlock určený pro populární webové prohlížeče umí automaticky skrývat reklamní plochy. To je sice pro návštěvníka webu potěšující zpráva, majitel portálu však již tak jásat nebude, protože přichází o zisky z reklamy, které častokrát umožňují udržovat projekt v chodu. Říká se proto, že používáním rozšíření AdBlock škodíte svému oblíbenému webu.

My se nyní podíváme na detekci aktivního pluginu. Pokud zjistíme, že uživatel bannery blokuje, můžeme ukázat informační hlášku nebo vykonat zcela jinou akci. První zmíněnou cestou se vydala například Edna – podívejte se, co se zobrazí, když budete AdBlock používat.

Edna

Dost bylo teorie, přistupme k tvorbě skriptu. Nejprve vdechnu život volavce, jenž se bude tvářit jako reklama a dostane za úkol lákat AdBlock. Do nového souboru s názvem advertisement.js vložím tento řádek:

document.write('ad');

Pojmenování souboru je klíčové, aby AdBlock na lest skutečně skočil a domníval se, že se potkal s reklamou.

Do stránky výše uvedený javascriptový fragment klasicky vložím:

<script src="advertisement.js" type="text/javascript"></script>

Pochopitelně nechci volavkou mást návštěvníky, a proto ji s pomocí CSS skryji:

#test {
display:none;
}

A nyní zbývá poslední krok. Otestuji, zda se div s falešnou reklamou skutečně na stránce nachází. Pokud ne, zablokoval falešný banner AdBlock.

if (document.getElementById("test") == undefined) {
//AdBlock je povolen, zde provedeme další kroky
}

Hotové řešení pak může vypadat například takto:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title></title>

	<style>
	#test {
   display:none;
	}
	</style>
	
</head>
<body>

<script src="advertisement.js" type="text/javascript"></script>

<script type="text/javascript">
if (document.getElementById("test") == undefined) {
//AdBlock je povolen, zde provedeme další kroky
alert("Prosím, vypněte si AdBlock");
}
</script>

</body>
</html>

Tento návod vychází z tohoto článku.

Závěrem si ještě dovolím varovat před hotovým skriptem, jenž lze nalézt na adblockdetector.com. Zastávám názor, že není třeba znovu programovat něco, co už bylo dávno vymyšleno, ovšem uvedené řešení prakticky nefunguje. V mém případě při použití prohlížeče Firefox detekce úplně selhala a při načtení stránky v Chrome byl povolený AdBlock odhalen jen několikrát z řady případů. Nabízený zdrojový kód navíc není v čitelné podobě, takže případnou chybu ani vlastní princip fungování nejsem schopen odhalit.

MySQL: Řazení sloupce s NULL hodnotami

MySQL - řazeníNedávno jsem potřeboval seřadit tabulku podle sloupce, jenž zastupoval cenu. Ne vždy však byl tento údaj vyplněn a objevovaly se proto i hodnoty NULL. To by nevadilo, pokud bych vyžadoval sestupné pořadí, tedy od největší ceny po nejmenší. Řádky s NULL by se v tomto případě ukázaly poslední. Já však toužil po přesném opaku. Jako první se měla projevit nejmenší cena. Tvrdohlavě však tuto příčku okupovaly hodnoty NULL a donutily mě začít hledat chytré řešení.

Vše lze pohodlně vyřešit s pomocí dotazu. Ten vypadá následovně:

SELECT cena FROM tabulka ORDER BY case when cena is null then 1 else 0 end, cena

Nejzajímavější je pochopitelně klauzule ORDER BY. S pomocí case vytvořím jednoduchou podmínku, jenž nahradí NULL za 1. Vyplněné ceny naopak zaměním za 0. Nyní jsem docílil toho, že řádky s NULL se ve výpisu objeví jako poslední. To odpovídá seřazení nul a jedniček dle defaultního (neuvedeného) vzestupného pořadí. Následně již zbývá vykonat poslední krok. Postarat se o správné začlenění řádků s uvedenou (neprázdnou) hodnotou. To je již velmi jednoduché, stačí do klauzule ORDER BY dosadit druhý sloupec (v mém konkrétním případě pojmenovaný jako cena). Ten si rovněž automaticky vyžádá vzestupné pořadí. Výsledkem je kýžený seznam s nejnižším číslem na svém počátku.