Michał Moroz

Abecadło smoczątka, dziennik niecodzienny

Na stronie i blogu README miej

Natchnęło mnie i obejrzałem kilka nowych joggerów. Mają już ze dwa wpisy, więc jest co czytać. ;)

Przy okazji zauważyłem pewną prawidłowość, o której jest ten wpis. A mianowicie brak zapewnionej informacji o tym, co taki blog będzie sobą reprezentować.

Ten problem można rozszerzyć do każdej strony internetowej. Musimy pamiętać, że aby zjeść owada, drapieżnik musi go zwabić. I w ten sam sposób autor strony internetowej musi uwić sobie swój kawałek sieci, żeby czytający chętnie się do niej przyklejali.

Należy założyć, że trafiając na stronę X, czytający nie ma żadnego rozeznania w tym, co się tam znajduje, znajdowało, czy też będzie znajdować. A autor powinien mu zapewnić swoiste README. Leżące w dobrze widocznym miejscu, aby czytający nie tracił czasu na szukanie. Dobrze, gdyby nie było większe, niż dwadzieścia, trzydzieści słów. W końcu stały czytelnik nie chce się przebijać przez wielki nagłówek, aby dotrzeć do treści.

Nikt nie broni, aby w tym malutkim README zawrzeć link do czegoś większego - strony z informacjami o autorze/stronie. W ten sposób będzie można zapewnić komfortowe rozwiązanie i dla tych, którzy przybyli tu pierwszy raz, i dla tych, którzy przyklejeni oczekują na schrupanie. Z drugiej strony nie wolno zostawiać samego linka, bo i tak nikt nie zada sobie tyle trudu, aby kliknąć i poczekać, aż nowa strona się załaduje.

I jeszcze drobna uwaga dla bloggerów - zostawianie informacji o treści bloga w pierwszym wpisie generalnie nie jest dobrym pomysł. Jeśli uważasz, że każdy nowy czytelnik będzie z chęcią do niego zaglądał z własnej woli, to masz zbyt wielkie mniemanie o sobie. A ci, którzy mogą sobie na coś takiego pozwolić, zazwyczaj i tak mają krótkie README gdzieś w widocznym miejscu.

Zobacz komentarze Trackback dodajdo.com Zobacz pełne metadane

drukujf

Wątek na pl.rec.humor.najlepsze jako pomysł.

better.c
#define calkow int
#define glowna main
#define zwroc return
#include <stdio.h>

#define drukujf printf

calkow glowna()
{
        drukujf("Witaj swiecie!\n");
        zwroc 0;
}

Kompilujemy! ;)

$ gcc better.c
$ ./a.out
Witaj swiecie!
$

Bpnmsp.

Zobacz komentarze Trackback dodajdo.com Zobacz pełne metadane

Świątecznie

Życzę wam wszystkim, aby wieczór wigilijny nie zakończył się na jedzeniu i gapieniu w telewizor.

A tu kilka niezwykłych kolęd (10MB), aby choć troszkę wczuć się w świąteczny nastrój.

Zobacz komentarze Trackback dodajdo.com Zobacz pełne metadane

Krótki podręcznik użycia zasilaczy ATX

Masz działający zasilacz ATX, który kurzy się w szafie? Wykorzystaj go. Mocy wystarczy na zasilenie różnych zasobożernych projektów, a ilość napięć standardowo dostarczonych przez taki zasilacz zadowoli miłośników układów cyfrowych, wypełni potrzebę uruchomienia większości przenośnych urządzeń, a nawet pomoże po części przy hybrydach analogowo-cyfrowych i urządzeniach analogowych.

  1. Historia, czyli na co mi to było...
  2. Metody - zbuduj swój własny miniaturowy sterownik zasilacza ATX.

Historia

Pewnego razu zapragnąłem, aby odtwarzanie płyt CD-Audio nie wiązało się z koniecznością włączania komputera. Nie miałem żadnego przenośnego odtwarzacza, a kupować nowego też nie chciałem. Pomysł ten odsunął się na jakiś czas za sprawą odtwarzacza Creative - Zen Touch 20GB. Model posiada jedną wadę - jego wyświetlacz pewien czas temu odmówił współpracy. Z drugiej strony, to dzięki tej usterce byłem w stanie go kupić. Założyłem, że nie ma się co martwić - odtwarzać muzykę da się i bez wyświetlacza, choć jest to nieco bardziej skomplikowane. Ostatecznie, póki dysk sprawny, zawsze będzie można go wykorzystać w jakiś inny sposób.

Jednak mp3 nie da tego, co ma CD-Audio. ;)

Później - podobnie jak w przypadku Zena, nadarzyła się okazja i zostałem właścicielem mikrozestawu głośniczków 2.1 ze wzmacniaczem oczywiście. Jakość... jakoś, ale nie narzekałem, bo własne. Inaczej - cieszyłem się bardzo, bo dało mi to możliwość odsłuchiwania muzyki z Zena bez ograniczania się słuchawkami.

Ostatnio wróciła chęć odtwarzania płyt CD, ale już z konkretnym pomysłem. W końcu niedawno kupowałem Tagana TG330-U01, a wcześniej NECa ND-3540. A stare, sprawne urządzenia kurzyły się w szafce!

Poprzednia nagrywarka CD-RW (której już nagrywanie się przestać podobało), była idealnym napędem na CD-Audio dzięki przyciskowi odtwarzania umieszczonemu na przednim panelu. Na dodatek z przodu miałem wyjście słuchawkowe. Nie musiałem więc zgłębiać tajników działania napędu, ani dorabiać specyficznych przejściówek, by skorzystać z funkcjonalności napędu.

Problem doprowadzenia energii został rozwiązany dzięki obejrzeniu manuala do Tagana, gdzie opisano wyprowadzenia 20/24-pinowego molexa i (pośrednio) pokazano, jak uruchamiać zasilacz.

Metody

Najpierw warto przedstawić wyprowadzenia naszego molexa:

       +---------+
 +3.3V | 1  11/13|  +3.3V
 +3.3V | 2  12/14|  -12V
   COM | 3  13/15|  COM
   +5V | 4  14/16|  PS_ON
   COM | 5  15/17|] COM
   +5V | 6  16/18|] COM
   COM | 7  17/19|  COM
PWR_OK | 8  18/20|  -5V
 +5Vsb | 9  19/21|  +5V
  +12V |10  20/22|  +5V
       +---------+
  +12V |11     23| +5V
 +3.3V |12     24| COM
       +---------+

Pin 14/16 to PS_ON, który, kiedy zwarty do masy, wybudza nasz zasilacz z trybu wstrzymania. Od niego trzeba zacząć. Prowizorka użyta do testów w postaci przewodu wtykanego w piny sprawdza się znakomicie i zasilacz startuje. Oczywiście, nasz mały sterownik będzie potrzebował czegoś więcej, niż kawałka drutu. Można zastosować proste rozwiązanie - sam włącznik, nieco lepiej - włącznik z układem tłumienia drgań lub zastosować bardziej skomplikowane metody załączania układu.

Do tych bardziej skomplikowanych zadań będziemy potrzebować dopływu energii niezależnego od trybu, w jakim znajduje się zasilacz. Zagwarantuje to nam wyprowadzenie 9, czyli +5Vsb.

PWR_OK zmienia swój stan na wysoki (5V, oczywiście), gdy zasilacz ustabilizuje napięcia. Można więc dołożyć diodę LED jako wskaźnik stanu naszego zasilacza, lub wykorzystać w dowolny inny sposób.

Cała reszta wyprowadzeń to najzwyklejsze linie zasilające. Przydałoby się wyprowadzić je na zewnątrz - np. do jakichś zacisków czy gdziekolwiek indziej.

Zobacz komentarze Trackback dodajdo.com Zobacz pełne metadane

Nawyki komputerowca

Aktualna konfiguracja mojego serwerka wygląda tak, że dysk leży na kartce papieru i pochrumkuje w zależności od stopnia użycia. A jak mnie pozytywnie zaskoczy, to zdarzy mi się nawet pogłaskać go po radiatorze na procesorku. Tym właśnie skutkuje czas i praca włożone w jego rozwój.

Przywiązanie do maszyny... To chyba dlatego nieinformatyczni tak patrzą na nas spode łba. :)

A jakie są wasze nawyki?

Zobacz komentarze Trackback dodajdo.com Zobacz pełne metadane

Wnioski z Ubuntu

Wniosek pierwszy. Nie próbuj kompilować jądra na Ubuntu, szczególnie, gdy Twój system chodzi poprawnie od dłuższego czasu. Nie jest to ani user-friendly, ani szybkie, ani przyjemne.

Wniosek drugi. Gdy już to zrobisz, trzymaj ręce z dala od nadpisywania starego kernela lub jego modułów. Inaczej będziesz krzyczeć: kernel jego panic mać!

Wniosek trzeci - Wreszcie, gdy po twardym resecie nawet BIOS nie będzie chciał odpalić, nie próbuj podpinać niechronionego Windowsa do sieci.

Wniosek czwarty. Potrzebujesz antywirusa i firewalla nawet wtedy, kiedy myślisz, że ich nie potrzebujesz.

Wniosek piąty. Kup większy dysk i postaw na zniszczonej maszynie Gentoo. I dopiero wtedy się baw.

Serwer będzie pewnie niedostępny przez jakiś czas...

Mord..., mord...

Zobacz komentarze Trackback dodajdo.com Zobacz pełne metadane

Myślenie warstwowe

We wpisie “Programistyczna kanapka, czyli wprowadzenie do warstw abstrakcji” wymieniłem możliwości płynące z projektowania warstwowego. Dziś skupię się na metodach, dzięki którym łatwo będzie nam tworzyć nowe projekty w tym trybie.

Wyobraź sobie warstwę

Warstwa abstrakcji charakteryzuje się tym, że nie zależy od innego kodu. W wolnym tłumaczeniu oznacza to mniej więcej tyle, że możesz wydzielić ją spośród kodu i korzystać z jej możliwości w innym środowisku.

Doskonałym przykładem na zobrazowanie powyższego jest system operacyjny. Jeżeli potraktować go jako pojedynczą, wielką warstwę abstrakcji, daje nam ogromną zaletę - nie musimy zastanawiać się, w jaki sposób zapisuje się plik na dysku, a jak w pamięci USB Flash, aby go zapisać. Jednocześnie projektant aplikacji nie musi obsługiwać procesora ręcznie, aby napisać kolejny edytor tekstu. A jeśli chcemy posłuchać muzyki, nie patrzymy na zapis nutowy piosenki i nie próbujemy zagrać go na instrumencie (mimo to polecam), a wrzucamy mptrójkę na listę odtwarzania i nie martwimy się, że ta mptrójka nie wie, jaki typ karty dźwiękowej posiadamy.

Komputer składa się ze sprzętu, zer i jedynek. Dziś jednak odnotowuję, że moja klawiatura nie ma dwóch klawiszy. A przecież tyle by wystarczyło, aby komunikować się z komputerem. Więc po co ich tyle?

Aby upraszczać. Tak samo, jak komunikacja za pomocą zer i jedynek była dla ówczesnych naukowców bardzo niewygodna, tak dzisiejsza klawiatura łacińska i zestaw klawiszy pozwala mi pisać ten tekst, abym nie potrzebował sprawdzać, jak prezentuje się poszczególna litera w zapisie bitowym. Czyli jakiś miły i mądry człowiek wprowadził zamianę liter na bity (a więc i nową warstwę abstrakcji), abym ja nie musiał się męczyć, używając dwóch klawiszy.

Podmień swą kanapkę na realny problem

Problem pierwszy - zapis danych

Każdy program od czegoś się zaczyna. Tym czymś w prawie każdym przypadku jest wczytanie danych. Wczytanie danych różni się w zależności od tego, skąd je wczytujemy i jak je chcemy wykorzystać. Do tego dochodzi ich zapis - w jakiś sposób chcemy przecież odzyskać przetworzone dane z naszego programu.

Przypuśćmy, że operujemy jednym, prostym typem danych, pochodzącym z kilku źródeł. Źródłem może być najzwyczajniejszy plik, baza danych, czy odległy serwer, z którym komunikujemy się poprzez sieć. Wszystkie te źródła wykazują jedną cechę wspólną. Nadal zapisywane do nich i odczytywane z nich są dane tego samego rodzaju.

Jedno z rozwiązań pozwala wbudować obsługę wszystkiego w główny kod, ale co, jeśli zapragniemy wykonywać podprogram przekazując mu te dane? Nagle okaże się, że wprowadzenie wszystkich potrzebnych zmian stanie się dość niewygodne. Nie dość, że będziemy musieli dodać naszą funkcjonalność w kilku miejscach, to na dodatek będziemy poprawiać wszystkie funkcje sprawdzające, aby uznały nową metodę za poprawną.

Spróbujmy inaczej. Dla każdego ze źródeł zdefiniujmy ten sam zestaw metod. W naszym przykładzie będzie to: zapisz i wczytaj. Zapisowi przekażemy porcję danych, od operacji wczytania będziemy wymagać porcji danych. Teraz stworzymy funkcję, która będzie odpowiedzialna za pobieranie wszystkich danych, niezależnie od źródła. W niej to odniesiemy się do poszczególnych “wczytaj”. Zwracać będzie całkowite dane gotowe do przetwarzania. Dla globalnej funkcji zapisania podamy przetworzone dane z listą celów, do których powinny się one udać. Funkcja ta będzie odwoływać się do odpowiedniej podfunkcji “zapisz”, zależnie od celu.

W tym wypadku część przetwarzająca nie będzie musiała zastanawiać się, jak zapisać dane, a całość kodu odpowiedzialnego za wczytywanie i zapis danych wewnątrz niej skróci się do oczekiwanych kilku linijek. Dodanie nowej funkcjonalności nie będzie dla nas trudne, a jeśli w kodzie warstwy abstrakcji stworzymy wykrywacz nowych funkcjonalności, to i tego kodu nie będziemy musieli zmieniać.

Problem drugi - interfejs

Dobrym pomysłem, aby przeprowadzić szybkie testy na nowej funkcjonalności jest usunięcie jak największej ilości niepotrzebnych bajerów i uruchomienie jej w minimalnej konfiguracji. Wtedy jesteśmy w stanie precyzyjniej określić problem i rozprawić się z nim szybciej.

Inaczej - tworzymy narzędzie X. Narzędzie X jest domyślnie w trybie okienkowym, bo tak ładniej i klikalniej. Po pewnym czasie potrzebujemy wersji konsolowej, bo możemy odpalić X w skrypcie i ustawić automatyczne uruchamianie co jakiś czas.

Jeszcze inaczej - narzędzie tworzymy pod biblioteką graficzną X, która nie jest dostępna na systemie Y, na którym pracuje nasz przyjaciel i właśnie pisze, że bardzo przydałoby mu się nasze narzędzie...

Rozwiązaniem na to jest użycie warstwy abstrakcji. Jądro aplikacji przestanie się martwić o wyświetlanie okienka, a Ty zbudujesz tyle interfejsów, ile zechcesz.

Inne przykłady

Używanie pluginów łączy się z warstwami abstrakcji - każdy z nich może zwiększyć możliwości naszego programu, a wszystkie korzystają z jednego zestawu funkcji.

Korzystanie z kilku podobnych struktur (na przykład kolejki i stosu) można łatwo uprościć tworząc odpowiednie funkcje, które będą pobierać obiekty ze struktur niezależnie od tego, o którą poprosisz.

Rozszerzanie działania aktualnie istniejących obiektów. Taka niedokładna, nieprzemyślana, lub błędna (#) alokacja pamięci w języku C często kończy się wyciekami pamięci, czy, w gorszym przypadku podwójnym zwolnieniem, lub używaniem niezaalokowanej pamięci. Zestaw funkcji, które sprawdzałyby te problemy, w mniejszym, czy w większym stopniu zabezpieczyłyby program, szczególnie ten w wersji rozwojowej.

Wniosek

Zakładając, że dany kod będziemy (my lub inni) rozwijać, warto jest wykorzystać ideę warstwy abstrakcji. Jeśli nie przydadzą się one nam, to osobom, która będą korzystać z naszego programu kiedyś.

Zobacz komentarze Trackback dodajdo.com Zobacz pełne metadane

GTK+/mtrace

Wraz z kolegą przygotowujemy sobie treningowo (a zarazem na zaliczenie) kalkulator. Podzieliliśmy się w ten sposób, że ja projektuję rdzeń (przetwarzanie ONP, ładowanie pluginów z funkcjami róznego rodzaju i takie tam bajery) i opiekuję się projektem (poznając autotoolsy), a on robi interfejs graficzny używając GTK+ 2.x i Glade.

Nadeszła już faza projektu odpowiednia na poważne programowanie GUI (patrz - rdzeń w większości działa, a Google potwierdza wyniki) i powoli, powoli zaczyna się budowa tegoż interfejsu.

Aktualnie udało nam się scalić kawałek okienka z rdzeniem i po wpisaniu wyrażenia w TextEdit i naciśnięciu przycisku się oblicza.

Chcąc sprawdzić, czy są memleaki, skorzystałem z funkcji mtrace, dzięki której automagicznie można sprawdzić, czy gdzieś nie cieknie.

$ MALLOC_TRACE="./mtrace.log" ./wyswtekstu
$ ls -l mtrace.log
-rw-r--r-- 1 dragonee dragonee 10951417 gru  4 23:41 mtrace.log

Samo wypluwanie wyjścia komendy mtrace, która przetwarza powyższy log i wyświetla adresy pamięci, które nie zostały zwolnione, zabrało mi jakąś minutę.

Zastanawiam się teraz, czy GTK+ tak ma, czy to tylko niezapisanie jakiejś magicznej komendy czyszczącej...

Zobacz komentarze Trackback dodajdo.com Zobacz pełne metadane
Wcześniejsze wpisy Na górę Późniejsze wpisy
Reklamy Google