Rovná čára v Gimpu

Gimp je výborný grafický editor, ale nemohl jsem přijít na to, jak v něm nakreslit rovnou čáru. Řešení je jednoduché. Stačí zvolit kreslící nástroj (ať už tužku nebo štětec), kliknout na plátno do výchozího bodu, stisknout a držet klávesu Shift, kliknou na koncové místo a pustit klávesu Shift.

gimp_kresleni_rovne_cary

Pokud budete stále držet klávesu Shift, můžete dále pokračovat v kreslení rovných čar. Stačí jen klikat na další místa na plátně. Tímto způsobem se dá vytvořit i objekt a to tím způsobem, že kreslení ukončíte ve výchozím bodu.

gimp_kresleni_rovne_cary_02

Vytvořený objekt je pak možné vybarvit pomocí plechovky.

gimp_kresleni_rovne_cary_03

České online kurzy

Ve světě již nějakou dobu fungují servery, nabízející různé druhy vzdělávacích kurzů. Jako příklad uvedu udemy. Na tomto webu naleznete tisíce kurzů na různá témata. Kurzy jsou jak zdarma tak placené. Většina kurzů až na drobné výjimky je v angličtině. Zajímalo mě, jak jsme na tom v naší české kotlině. Věnoval jsem tedy nějaký čas vyhledávání a zde je výsledek:


e-akademia.cz

Naleznete zde video přednášky, video tutoriály a testy týkající se převážně matematiky. Prozatím to vypadá jako projekt jednoho člověka.

Cílem našeho projektu je zpřístupnit vzdělání všem lidem v ČR, kteří o něj mají zájem. Chceme, aby vzdělání bylo dostupné lidem, jak po stránce geografické, tak po stránce finanční. Řešení této myšlenky vidíme v organizování online video kurzů zaměřených na nějaké konkrétní téma.


kurzyproradost.cz

Aktuálně (1. 1. 2016) nabízí okolo 60 kurzů. Příliš technických kurzů jsem v nabídce nenalezl a vadilo mi, že nebylo možno kurzy vyhledávat dle zaměření. Někdo jiný si tam ale možná vybere.


kurzomanie.cz

Web je graficky velmi hezký. Bohužel ke dnešnímu dni (1. 1. 2016) nenabízí žádný kurz, i když uvádí:

Spuštění portálu je naplánováno na prosinec 2015. Momentálně jednáme s více jak 30 lektory a instruktory na spuštění prvních 50+ vzdělávacích kurzů.

V každém případě bude zajímavé tento web po nějakém čase znovu navštívit a zjistit, zda skutečně splnili to, co slibovali.


seduo.cz

Na tento web jsem velmi zvědavý. Tvrdí totiž o sobě, že je podporován job.cz. Ke dni publikace tohoto příspěvku je v nabídce 15 kurzů z toho 10 zdarma. Určitě se na tento web ještě v budoucnu podívám.


naucmese.cz

Aktuálně (1. 1. 2016) je v nabídce téměř 300 kurzů. Je možné kurzy vyhledávat dle kategorie a též dle města. Vypadá to ale, že se jedná převážně o kurzy, na které je třeba se dostavit osobně, a nikoliv o online kurzy.


onlinekurzyzdarma.cz

K 1. 1. 2016 zde naleznete přes 50 online kurzů zdarma. Kurzy jsou rozděleny do několika kategorii a lze mezi nimi vyhledávat. Tak jako většina zmíněných webů nabízí možnost nechat si na email zasílat novinky.


khanovaskola.cz

Na tomto webu naleznete videolekce k předmětům jako matematika, fyzika, chemie, biologie, ekonomie, dějepis a informatika. Web je graficky velmi povedený a měli byste na něm nalézt více než 2.700 videolekcí zadarmo a pro všechny.

Khanova škola je vzdělávací portál pro děti i dospělé. Jádro tvoří výuková videa, která skládáme do promyšlených návazností tak, abyste si mohli užít souvislou výuku od úplných základů až po komplexní oborové znalosti. Vše zdarma a z pohodlí vašich domovů. 


Na závěr ještě zmíním stránku mimoskolu.cz/katalog-zdroju/ kde je seznam českých i zahraničních vzdělávacích zdrojů.

Java Optional efektivně

Klíčem k efektivnímu využití Optional je používání metod, které dokáží s Optional pracovat. Tyto metody buď zpracují hodnotu zabalenou v Optional, nebo, v případě, že není přítomna, vytvoří náhradní hodnotu (objekt).

Metoda Optional.ifPresent() jako parametr bere funkci java.util.function.Function a v případě, že Optional obsahuje hodnotu (referenci na objekt), je tato hodnota (reference) předána funkci. Pokud hodnotu neobsahuje, nic se nestane.

Stream<Integer> is1 = Stream.of(5, 7, 1, 8, 2);
Optional<Integer> max = is1.max(Integer::compareTo);
Stream<Integer> is2 = Stream.empty();
Optional<Integer> min = is2.min(Integer::compareTo);

Výpis výsledků do konzole (vypíše 8):

max.ifPresent((i) -> System.out.println(i));
min.ifPresent((i) -> System.out.println(i));

Přidání výsledků do listu:

List<Integer> results = new ArrayList<>();
max.ifPresent((i) -> results.add(i));
min.ifPresent((i) -> results.add(i));

Metoda Optional.ifPresent() zpracovává hodnotu v případě, že je přítomna. Dalším způsobem je použít metody, které vytvoří hodnotu (nebo něco provedou) v případě, že hodnota není přítomna. Pro tento případ se hodí metody optionalVariable.orElse(), optionalVariable.orElseGet(), optionalVariable.orElseThrow().

Stream<String> ss1 = Stream.of("lokomotiva", "auto", "letadlo", "raketa", "vzducholoď");
Optional<String> firstWithL = ss1.filter((word) -> word.startsWith("l")).findFirst();
Stream<String> ss2 = Stream.of("lokomotiva", "auto", "letadlo", "raketa", "vzducholoď");
Optional<String> anyWithQ = ss2.filter((word) -> word.startsWith("q")).findAny();

String withL = firstWithL.orElse("");
String withQ1 = anyWithQ.orElse("");

System.out.println(withL);
System.out.println(withQ1);

try {
	String withQ2 = anyWithQ.orElseThrow(Exception::new);
} catch (Exception e) {
	e.printStackTrace();
}

Výpis:

lokomotiva

java.lang.Exception
	at java.util.Optional.orElseThrow(...)

Metoda Optional.orElse() vrátí v případě, že Optional obsahuje null, náhradní hodnotu zadanou jako parametr. Pokud Optional obsahuje referenci, vrátí objekt. Metoda Optional.orElseThrow() vyhodí danou výjimku (pokud Optional obsahuje null).


Zdroj: HORSTMANN, Cay S. Java SE 8 for the really impatient. Upper Saddle River, NJ: Addison-Wesley, 2014, xv, 215 pages. ISBN 0321927761.

Proč používat Java Optional?

Není příliš velký rozdíl mezi:

Optional<T> op = ...;
op.get().someMethod();

vs

T val = ...;
val.someMethod();

Pokud se chceme vyhnout výjimce:

if (op.isPresent()) {
    T val = op.get();
    val.someMethod();
}

vs

if (val != null) {
    val.someMethod();
}

Pokud programátor Optional nepoužívá, ušetří dokonce pár znaků při psaní (nemusí volat get()). Proč tedy používat Optional?

Předchozí příspěvek na téma Optional se týkal třídy Optional z knihovny Guava. Tento příspěvek se věnuje třídě java.util.Optional, která je dostupná od Javy 8. Důvody pro jejich použití jsou ale obdobné. Guava Optional se používá v případě, že máte starší verzi Javy. V případě, že používáte Javu 8, knihovnu Guava nepotřebujete. 

Důvodem pro používání Optional je to, že null může mít více významů. Null může být prázdná hodnota, může představovat chybu, může to být též neinicializovaná proměnná. Pokud ale máme Optional<T> (Optional vlastně zabaluje hodnotu T), tak buď máme referenci na objekt typu T (Optional.isPresent() == true) a nebo referenci nemáme (Optional.isPresent() == false). V případě, že referenci nemáme, odpovídalo by to případu, kdy null vyjadřuje prázdnou hodnotu.

Další výhodou Optional je to, že bychom si při použití Optional měli uvědomit, že se jedná o hodnotu, která nepovinná (proto název optional) a podle toho se k ní chovat. U běžné proměnné nás nemusí napadnout, že je třeba provést kontrolu na to, zda třeba není null. To je důvod, proč některé metody vrací Optional. Dávají tím najevo, že nemusí vrátit žádnou hodnotu. Je to bezpečnější způsob práce než s null. Optional například vrací některé metody pracující s Stream (java.util.stream.Stream).

Stream<Integer> is1 = Stream.of(5, 7, 1, 8, 2);
Optional<Integer> max = is1.max(Integer::compareTo);

Stream<Integer> is2 = Stream.empty();
Optional<Integer> min = is2.min(Integer::compareTo);

Stream<String> ss1 = Stream.of("lokomotiva", "auto", "letadlo", "raketa", "vzducholoď");
Optional<String> firstWithL = ss1.filter((word) -> word.startsWith("l")).findFirst();

Stream<String> ss2 = Stream.of("lokomotiva", "auto", "letadlo", "raketa", "vzducholoď");
Optional<String> anyWithQ = ss2.filter((word) -> word.startsWith("q")).findAny();

Stream<String> ss3 = Stream.of("lokomotiva", "auto", "letadlo", "raketa", "vzducholoď");
Optional<String> shortest = ss3.min((word1, word2) -> word1.length() - word2.length());

Metody min(), max(), findAny(), findFirst() vrací Optional, protože Stream, který dostanou může být prázdný a tím pádem žádnou hodnotu nemusí najít (viz is2), nebo žádná taková hodnota nevyhovuje podmínkám (viz ss2.filter() na slova začínající na q -> žádné takové tam není).

Vlastní anotace v Javě

Anotace v Javě jsou způsobem, jak do kódu přidat meta informace (metadata, data o datech). Anotace se používají pro:

  • instrukce pro compiler
  • instrukce pro build-time
  • instrukce pro run-time

Java umožňuje vytvořit si vlastní anotace pomocí klíčového slova @interface.

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

	String value();
	int version() default 1; 
}

Použitá anotace @Retention(RetentionPolicy.RUNTIME) určuje, že tato anotace (@MyAnnotation) má být přístupná i v run-time. Anotace @MyAnnotation má dva elementy (value a version). Element version má nastavenu výchozí hodnotu na 1.

public @interface MyOtherAnnotation {

}

Anotace @MyAnnotation žádné elementy neobsahuje.

@MyOtherAnnotation
@MyAnnotation(value = "abcd")
public class MyClass {

}

Třída MyClass je anotována oběma anotacemi. Anotace @MyAnnotation má nastavenu hodnotu elementu value na „abcd“ a hodnotu version na 1 (default).

import java.lang.annotation.Annotation;

public class App {

	public static void main(String[] args) {
		
		Class clazz = MyClass.class;
		if (clazz.isAnnotationPresent(MyAnnotation.class)) {
			System.out.println("Je anotován: " + MyAnnotation.class.getSimpleName());
			
			MyAnnotation myAnnotation = (MyAnnotation) clazz.getAnnotation(MyAnnotation.class);
			System.out.println(myAnnotation.value());
			System.out.println(myAnnotation.version());
		}
		if (clazz.isAnnotationPresent(MyOtherAnnotation.class)) {
			System.out.println("Je anotován: " + MyOtherAnnotation.class.getSimpleName());
		}
	}
}

Výstup:

Je anotován: MyAnnotation
abcd
1

Díky tomu, že @MyAnnotation je anotováná @Retention(RetentionPolicy.RUNTIME) je možné k ní pomocí reflexe přistupovat i v run-time. Lze zjistit nejen to, zda daná třída je pomocí určité anotace anotována, ale také hodnoty elementů. Anotace @MyOtherAnnotation v runtime přítomna není.


Zdroj: tutorials.jenkov.com/java/annotations.html

Nekonečný Stream v Javě

Java 8 představila Stream, což je posloupnost hodnot, nad kterou je možné provádět operace. Je možné vytvořit i nekonečný Stream.

Stream<String> stringStream = Stream.generate(() -> UUID.randomUUID().toString());
Stream<String> constantStream = Stream.generate(() -> "word");
Stream<Double> doubleStream = Stream.generate(Math::random);
Stream<Integer> integerStream = Stream.iterate(0, (i) -> i + 1);
Stream<BigDecimal> bigDecimalStream = Stream.iterate(BigDecimal.ZERO, (bd) -> bd.add(BigDecimal.ONE));

Metoda Stream.generate() požaduje parametr typu Supplier<T>, což je funkční rozhraní obsahující metodu T get(). Metoda Stream.iterate() požaduje parametr typu T seed (počáteční element) a UnaryOperator<T>, což je funkční rozhraní dědící z funkčního rozhraní Function (místo typů <R, T> používá <T, T>, metoda apply(T) tedy nevrací typ R ale T).

Pokud nám stačí jen několik prvků streamu, můžeme použít operaci limit(n), která vezme n prvních prvků streamu.

System.out.println(Arrays.toString(stringStream.limit(5).toArray()));
System.out.println(Arrays.toString(constantStream.limit(5).toArray()));
System.out.println(Arrays.toString(doubleStream.limit(5).toArray()));
System.out.println(Arrays.toString(integerStream.limit(5).toArray()));
System.out.println(Arrays.toString(bigDecimalStream.limit(5).toArray()));

Výstup:

[cb2f9562-e468-4409-bd61-cc7f153adbc9, 45582575-fda8-48a4-9ecd-bd8e9ca87f42, 6338c4d5-7b67-4fff-b1ec-6a86e2bacec8, 9ba3c6b0-700a-4e78-b633-e6a8da9fb946, 04951054-8c43-43a6-a177-aeb2da7c7320]
[word, word, word, word, word]
[0.9250003903085224, 0.912794982359122, 0.8636553602757563, 0.5809828517176208, 0.002178508953346925]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]

Pozor na datový typ (na přetečení rozsahu), který je použit v nekonečném proudu.

Stream<Integer> is = Stream.iterate(1, (i) -> i * 10).limit(15);
Stream<BigDecimal> bds = Stream.iterate(BigDecimal.ONE, (bd) -> bd.multiply(new BigDecimal("10"))).limit(15);

System.out.println(Arrays.toString(is.toArray()));
System.out.println(Arrays.toString(bds.toArray()));

Výstup:

[1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 1410065408, 1215752192, -727379968, 1316134912, 276447232]
[1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000]

Práce s historií v Bash

Velikost historie (počet uchovávaných příkazů) se nastavuje v souboru .bashrc v home adresáři (proměnné HISTSIZE a HISTFILESIZE). Historie v Bash se dá procházet pomocí šipek. Celou historii zobrazíme příkazem history. Výpis historie můžeme omezit přepínačem, pomocí kterého určíme, kolik příkazů z historie chceme zobrazit.

history 10 (zobrazí posledních 10 záznamů)

Pokud chceme provést nějaký příkaz z historie a nechce se nám dlouho listovat, stačí si historii zobrazit (u každého příkazu je číslo) a napsat !číslo_příkazu.

$ history
1 ls /etc
2 nano host
3 ls
4 ls -al
5 nano /etc/host
6 cd apt
7 pwd
8 cd /etc/apt
9 ls
10 nano sources.list
11 exit
12 history

V příkladu výše mám v historii celkem 12 příkazů. Pokud chci rychle provést příkaz nano /etc/host stačí mi napsat !5. Pokud chci vykonat poslední příkaz stačí napsat !!. Pro příkaz nano /etc/host jsem zapomněl uvést sudo. Stačí mi tedy napsat sudo !!.

Zdroj: digitalocean.com/community/tutorials/…

Otevření cmd ve složce

Program Příkazový řádek (cmd.exe) se dá otevřít v určité složce (programy v dané složce je možné rovnou spouštět bez zadání cesty). Otevřít v průzkumníkovi daný adresář -> stisknout klávesu Shift + pravým tlačítkem myši -> vybrat volbu „Zde otevřít příkazové okno“.

windows_otevreni_cmd

Pořadí při použití metody equals

V případě, že máme konstantu a tu porovnáváme s objektem, je vhodnější použít konstrukci konstanta.equals(objekt) než naopak. Důvod je jednoduchý. Vyhneme se tak možnosti chyby NullPointerException.

String MY_CONSTANT = "AB9922";
            
System.out.println(MY_CONSTANT.equals(MY_CONSTANT));
System.out.println(MY_CONSTANT.equals("ABCDEF"));
System.out.println(MY_CONSTANT.equals(null));

Výsledek.

true
false
false

Pokud to zkusíme opačně, kód nepůjde zkompilovat.

System.out.println(MY_CONSTANT.equals(MY_CONSTANT));
System.out.println("ABCDEF".equals(MY_CONSTANT));
// Unresolved compilation problem:  Cannot invoke equals(String) on the primitive type null
// System.out.println(null.equals(MY_CONSTANT));

Vědomě bychom konstrukci null.equals() určitě nepoužili, ale nevědomě se používá docela často. Zde je metoda, která vrací náhodný String. Vrácená hodnota tedy může být i null.

 private static String generateString() {
       int randomNumber = gen.nextInt(3);
      
       switch(randomNumber) {
              case 0:
                     return "AB9922";
              case 1:
                     return "XX8811";
              default:
                     return null;
       }
 }

Pokud budeme porovnávat objekty tímto způsobem,

 private static final String MY_CONSTANT = "AB9922";

 public static void main(String[] args) {
      
       for (int i = 0; i < 100; i++) {
              System.out.println(generateString().equals(MY_CONSTANT));
       }
 }

kód nám pravděpodobně bude nějakou chvíli fungovat, ale časem se určitě objeví NullPointerException.

true
true
false
Exception in thread "main" java.lang.NullPointerException

Předejít tomu můžeme změnou objektu, na kterém metodu equals() voláme.

for (int i = 0; i < 100; i++) {
      System.out.println(MY_CONSTANT.equals(generateString()));
}

Rychlé spuštění programu ve Windows

Operační systém Windows nabízí několik možností jak rychle spustit program (ať už pomocí klávesové zkratky či jinak). Uvádím zde několik způsobů:

Připnutí ikony programu na hlavní panel

Pravým tlačítkem na program -> Připnout na hlavní panel. Pokud z hlavního panelu chcete program odstranit, pravým tlačítkem na program na panelu -> Odepnout tento program z  hlavního panelu. Tímto způsobem je možné si upravit hlavní panel tak, aby obsahoval ty nejpoužívanější programy a ty díky tomu byly lehce přístupné.

Spuštění programu na hlavním panelu pomocí klávesové zkratky

Všechny programy připnuté k hlavnímu panelu mají své pořadové číslo (zleva doprava od jedničky). Tlačítko Start, ikona Prohledat Windows a Zobrazení úkolů se nepočítá.

windows_spusteni_programu

Na tomto snímku je můj hlavní panel. Pokud budu chtít pustit průzkumníka souborů, stisknu klávesu Windows + 1 (průzkumník Windows lze spustit i klávesovou zkratkou Win + E). Pokud budu chtít spustit Eclipse IDE, stisknu klávesu Windows + 4. Pokud program ZimNotes tak klávesu Windows + 2.

Přiřazení klávesové zkratky zástupci

Pokud máte na ploše zástupce programu, je možné mu přiřadit klávesovou zkratku. Klikněte pravým tlačítkem na ikonu programu -> Vlastnosti -> umístěte kurzor do textového pole s popiskem Klávesová zkratka a tiskněte nějaké písmeno. Automaticky se předvyplní Ctrl + Alt.

windows_spusteni_programu02

Na obrázku je programu (zástupci programu) PuTTY přiřazena klávesová zkratka Ctrl + Alt + Y.

Zdroje: