W prosty sposób o trudnych sprawach.

Czy o trudnych sprawach można pisać w prosty sposób? Jasne, że tak. Stephena Hawking udowadnia to każdą swoją książką. Dla osób takich jak ja, ciekawych świata a jednocześnie dysponujących zaledwie podstawową wiedzą z zakreu fizyki i astronomii, lektura [„Jeszcze krótszej historii czasu”](http://www.empik.com/jeszcze-krotsza-historia-czasu-ksiazka,2612671,p) to prawdziwa przyjemność. Książka ta – podobnie jak jej pierwowzór – w cudownie przejrzysty i interesujący sposób traktuje o naprawdę trudnych zagadnieniach.

Amerykańscy naukowcy pojęli już dawno, że ilość trudnych słów użytych w treści nie gwarantuje merytorycznie wysokiej wartości wykładu, za to z pewnością utrudnia przyswajanie przedstawianego materiału. [„Jeszcze krótsza historia czasu”](http://www.empik.com/jeszcze-krotsza-historia-czasu-ksiazka,2612671,p) to pozycja popularno naukowa, ale już „Wywieranie wpływu na ludzi. Teoria i praktyka.” Roberta Cialdini czy książki Eliota Aronsona o psychologii społecznej spokojnie można włączyć w poczet literatury naukowej, a czyta się dobrze i przyjemnie.

W tym tygodniu sięgnąłem też po książkę pt. [„Erystyka czyli o Sztuce Prowadzenia Sporów”](http://ksiegarnia.pwn.pl/produkt/7400/erystyka-czyli-o-sztuce-prowadzenia-sporow.html). Agnieszka Budzyńska-Daca i Jacek Kwosek w pierszym rozdziale zapowiadają, iż książka ta jest niejako odpowiedzią na liczne głosy osób, które narzekają na trudność wykładu Schopenhauera. Komentują dzieło niemieckiego filozofa i wyjaśniają istotę poszczególnych technik erystycznych – również tych nie omawianych przez Schopenhauera – posiłkując się przy tym licznymi zaczerpniętymi z życia, literatury i polityki przykładami. Szczerze polecam niniejszą pozycję. Przeczytałem ją z prawdziwym zainteresowaniem jednak w świetle wyżej poruszonego problemu – łatwości odbioru tekstów naukowych – nie mogę jej zaliczyć do najprostszych. Lektura wymaga dużego skupienia. Po 50 stronicowej sesji z Erystyką, dla rozluźnienia chętnie zagłębiłem się w teorii względności Alberta Einsteina w ujęciu S. Hawkinga.

Posted in Priv byZbigniew Heintze

Automatyczna kopia bezpieczeństwa

Bezpieczeństwo danych to sprawa kluczowa. Jednym z ważniejszych zabiegów jest systematyczne tworzenie kopii bezpieczeństwa czyli tzw. backup. W ramach ćwiczeń w bashu postanowiłem napisać sobie taki mały skrypcik, który po odpaleniu przekopiuje cały katalog domowy mojego użytkownika na zewnętrzny dysk USB.

#!/bin/sh
 
#ustawienia sciezek
DEST_PATH="/path/to/my/external/disk"
BACKUP_DIR=$DEST_PATH/$(date +%Y-%m-%d-%H:%M)
SOURCE_PATH="/home/myuser"
 
#ustawienia domyslne
MODE="full"
TYPE="tar"
 
#wyswietlenie informacji jezeli bedzie mniej niz 2 argumenty.
if [ $# -lt 2 ]; then
    echo "Usage: `basename $0` <TAR|COPY> <FULL|incremental X days ago>"
fi
 
#jezeli podany jest drugi argument w linii polecen, to przystap do analizy
if [ ! -z "$2" ]; then
    case "$2" in
        FULL|full)
            MODE=full
            ;;
        *)
            MODE=$2
            ;;
    esac
fi
 
#jezeli pierwszy argument nie jest pusty do nalezy go przeanalizowac
if [ ! -z "$1" ]; then
    case "$1" in
        TAR|tar)
            TYPE=tar
            ;;
        copy|COPY)
            TYPE=copy
            ;;
    esac
fi
 
#jezeli katalog docelowy backupu nie istnieje, to nalezy go stworzyc
if [ ! -e $BACKUP_DIR ]; then
    mkdir -p $BACKUP_DIR;
fi
 
#funkcja robiaca backup za pomoca tara
make_tar_backup ()
{
    if [ "$MODE" = "full" ]; then
        echo "Full backup as archive TAR"
        tar -zcp -f $BACKUP_DIR/full.tgz $SOURCE_PATH
    else
        echo "Incremental backup as archive TAR. $MODE days ago"
        tar -zcp --newer-mtime "$MODE days ago" -f $BACKUP_DIR/incremental_$MODE.tgz $SOURCE_PATH
    fi
}
 
#funkcja robiaca backup za pomoca cp
make_copy_backup ()
{
    if [ "$MODE" = "full" ]; then
        echo "Full backup as save copy"
        for source_files in $SOURCE_PATH; do
            echo -e "\tDirectory $source_files"
            cp --parents -a $source_files $BACKUP_DIR
        done
    else
        echo "Incremental backup as save copy. $MODE days ago"
        for s in $SOURCE_PATH; do
            items_list=`find $s -ctime -$MODE`
            echo -e "\tDirectory $s"
            if [ ! -z "$items_list" ]; then
                for item_file in $lista; do
                    cp --parents -a $item_file $BACKUP_DIR
                done
            fi
        done
    fi
}
 
#start pomiaru czasu
time_start=$(date +%s);
 
#w zaleznosci od sposobu przechowywania backupu, uruchamiamy odpowiednie funkcje.
case "$TYPE" in
   tar)
      make_tar_backup
      ;;
   copy)
      make_copy_backup
      ;;
esac
 
time_end=$(date +%s);
exec_time=`expr $time_end - $time_start`
echo "Backup successfull. Execution time $exec_time seconds"

Proste ale działa 🙂

Sortowanie tablicy wielowymiarowej w php

Zdecydowałem się wreszcie opublikować mój artykuł na temat wzorca projektowego DTO (Data Transfer Object), który napisałem już jakiś czas temu. Przy okazji parę akapitów poprawiłem i dopisałem nowe przykłady zastosowania. Przygotowując przykład dotyczący Recordset-u odkopałem przydatną funkcję ułatwiającą [sortowanie tablicy wielowymiarowej](http://php.net/manual/pl/function.array-multisort.php#87268). Jest uniwersalna i moim zdaniem warto zwrócić na nią uwagę. Ponad to wbrew pozorom nie musi służyć jedynie do sortowania wyników zapytań SQL-owych.

<?php
/**
 * Sort DB result
 *
 * @param array $data Result of sql query as associative array
 *
 * Rest of parameters are optional
 * [, string $name  [, mixed $name or $order  [, mixed $name or $mode]]]
 * $name string - column name i database table
 * $order integer - sorting direction ascending (SORT_ASC) or descending (SORT_DESC)
 * $mode integer - sorting mode (SORT_REGULAR, SORT_STRING, SORT_NUMERIC)
 *
 * <code>
 * <?php
 * // You can sort data by several columns e.g.
 * $data = array();
 * for ($i = 1; $i <= 10; $i++) {
 *     $data[] = array( 'id' => $i,
 *                      'first_name' => sprintf('first_name_%s', rand(1, 9)),
 *                      'last_name' => sprintf('last_name_%s', rand(1, 9)),
 *                      'date' => date('Y-m-d', rand(0, time()))
 *                  );
 * }
 * $data = sortDbResult($data, 'date', SORT_DESC, SORT_NUMERIC, 'id');
 * print_r($data);
 * $data = sortDbResult($data, 'last_name', SORT_ASC, SORT_STRING, 'first_name', SORT_ASC, SORT_STRING);    
 * print_r($data);
 * ?>
 * </code>
 *
 * @return array $data - Sorted data
 */
function sortDbResult(array $data /*$name, $order, $mode*/) {
    $_argList = func_get_args();
    $_data = array_shift($_argList);
    if (empty($_data)) {
        return $_data;
    }
    $_max = count($_argList);
    $_params = array();
    $_cols = array();
    $_rules = array();
    for ($_i = 0; $_i < $_max; $_i += 3)
    {
        $_name = (string) $_argList[$_i];
        if (!in_array($_name, array_keys(current($_data)))) {
            continue;
        }
        if (!isset($_argList[($_i + 1)]) || is_string($_argList[($_i + 1)])) {
            $_order = SORT_ASC;
            $_mode = SORT_REGULAR;
            $_i -= 2;
        } else if (3 > $_argList[($_i + 1)]) {
            $_order = SORT_ASC;
            $_mode = $_argList[($_i + 1)];
            $_i--;
        } else {
            $_order = $_argList[($_i + 1)] == SORT_ASC ? SORT_ASC : SORT_DESC;
            if (!isset($_argList[($_i + 2)]) || is_string($_argList[($_i + 2)])) {
                $_mode = SORT_REGULAR;
                $_i--;
            } else {
                $_mode = $_argList[($_i + 2)];
            }
        }
        $_mode = $_mode != SORT_NUMERIC
                    ? $_argList[($_i + 2)] != SORT_STRING ? SORT_REGULAR : SORT_STRING
                    : SORT_NUMERIC;
        $_rules[] = array('name' => $_name, 'order' => $_order, 'mode' => $_mode);
    }
    foreach ($_data as $_k => $_row) {
        foreach ($_rules as $_rule) {
            if (!isset($_cols[$_rule['name']])) {
                $_cols[$_rule['name']] = array();
                $_params[] = &$_cols[$_rule['name']];
                $_params[] = $_rule['order'];
                $_params[] = $_rule['mode'];
            }
            $_cols[$_rule['name']][$_k] = $_row[$_rule['name']];
        }
    }
    $_params[] = &$_data;
    call_user_func_array('array_multisort', $_params);
    return $_data;
}
?>
Posted in PHP | Tagged , byZbigniew Heintze