Posts from 2010

le ba’urtadji be lo valsi be fi la lojban.

2010-07-20 15:51

Wymowa słów w lojbanie.

Moje trwające już kilka miesięcy zainteresowanie lojbanem pewnie nie przetrwałoby tak długo, gdyby był on czymś w typie esperanto – a tym, jak wiemy, na pewno nie jest. Przeglądanie jego “formalnej definicji” (czyli The Lojban Reference Grammar) sprawia raczej wrażenie czytania dokumentacji języka programowania, biblioteki lub innego API. Jest to więc całkiem przyjemna lektura :)
Nie zapominajmy jednak, że lojban jest mimo wszystko pomyślany jako język (również) dla ludzi, i to także do – szok! horror! – mówienia. Posiada więc również określone reguły wymowy wyrazów. Są one zresztą określone bardzo dobrze, gdyż niewielki poziom ich skomplikowania nijak ma się do złożonych i nie zawsze jasnych niuansów wymowy języków naturalnych. Można to łatwo zauważyć, kiedy przyjrzymy się im z bliska.

Tags: ,
Author: Xion, posted under Culture » 6 comments

Wtyczki do programów w .NET

2010-07-18 12:01

Rozszerzalność od dawna jest w modzie: praktycznie żadna poważniejsza aplikacja nie obywa się bez jakiegoś systemu pluginów, czyli “wtyczek” zwiększających jej funkcjonalność. Niektóre robią to przy okazji (acz ze słusznych powodów), inne czynią z elastyczności i rozszerzalności swój główny oręż (patrz np. uniwersalne komunikatory w typie Mirandy). Wszystko to kojarzy się trochę linuksiarsko, jednakże obecnie także wiele programów stricte pod Windows zachęca (a przynajmniej umożliwia) swoich użytkownika do zakasania rękawów i zakodowania im nowych funkcji.
Dotyczy to także aplikacji na platformę .NET. Co więcej, sama jej natura ułatwia budowanie programów wspierających koncepcję rozszerzalności. Rzecz opiera się na pojęciu assembly, czyli czegoś w rodzaju pakietu (javowe skojarzenia wskazane) zawierającego kod, a więc klasy. Ze względu na to, że .NET Framework zawiera wbudowany kompilator, jest zupełnie możliwe, by nasz program udostępniał całe środowisko do pisania do niego pluginów, a następnie przerabiania ich na kod wykonywalny i podłączania ich do aplikacji. Nie twierdzę, że znam program, który rzeczywiście tak robi, ale przynajmniej w teorii jest to możliwe :)

Powszechniejsze wydaje mi się prostsze podejście, w którym assembly dostarcza się w postaci skompilowanej. Zazwyczaj jest to biblioteka .NET-owych, zapisana jako plik .dll, niemający przy tym zbyt wiele wspólnego z natywnymi czy COM-owymi DLL-ami. Wczytanie go jest bardzo proste, gdy wykorzystujemy do tego klasę System.Reflection.Assembly:

  1. Assembly assembly = Assembly.LoadFrom("ścieżka\do\pliku");

Wskazana jest tutaj ostrożność np. w postaci zapewnienia, że każde assembly ładujemy tylko raz. Najlepiej jest wyznaczyć osobny podkatalog na wtyczki do naszego programu i ładować je jednokrotnie, zapewne podczas uruchamiania samej aplikacji.

Gdy mamy już gotowy obiekt klasy Assembly (niezależnie od tego, czy skompilowaliśmy go sami czy wczytaliśmy go z gotowej binarki tak, jak powyżej), chcielibyśmy pewnie jakoś wykorzystać zawarty w nim kod. Są nim oczywiście jakieś klasy, które możemy pobrać metodą GetExportedTypes. Zwróci nam ona metody tablicę obiektów Type, czyli znanej zapewne metaklasy należącej do .NET-owego systemu refleksji. Z nimi zaś zrobić możemy… no, prawie wszystko :) Do interesujących w kontekście pluginów czynności należy przede wszystkim sprawdzenie, czy dana klasa implementuje jakiś ustalony przez nas interfejs “wtyczkowy”, a następnie utworzenie jej obiektu:

  1. List<IPlugin> plugins = new List<IPlugin>();
  2. foreach (Type type in assembly.GetExportedTypes())
  3.     if (type.IsClass && !type.IsAbstract
  4.         && type.GetInterface(typeof(IPlugin).FullName) != null)
  5.     {
  6.         plugins.Add ((IPlugin)Activator.CreateInstance(type));
  7.     }

Takie beztroskie, dynamiczne tworzenie obiektów z binarnego kodu wczytanego już w trakcie działania programu jest jak najbardziej możliwe i, jak widać wyżej, całkiem proste – stosujemy do tego metodę CreateInstance klasy o wdzięcznej nazwie Activator. Wymogiem jest obecność w klasie wtyczki odpowiedniego konstruktora. W powyższym kodzie zakładamy na przykład najprostszy przypadek, iż dostępna jest jego wersja bezparametrowa.

To w sumie wszystko, jeśli chodzi o wczytywanie. To, w jaki sposób plugin może rozszerzać możliwości naszej aplikacji, zależy głównie od zawartości interfejsu, który nazwałem tutaj umownie IPlugin. Projektując go, powinno się zadbać o jego elastyczność i prostotę, a także wziąć pod uwagę chociażby kwestie bezpieczeństwa.

Tags: , , , ,
Author: Xion, posted under Programming » 2 comments

Triki z PowerShellem #15 – Puff, jak gorąco!

2010-07-13 23:03

Obecne temperatury są uciążliwe nie tylko dla nas – organizmów opartych o białka i węgiel, ale też dla naszych półprzewodnikowych, krzemowych gadżetów. Dotyczy to również komputerów oraz ich procesorów. Jak każde układy scalone, mają one tendencję do nagrzewania się – czasem nadmiernego. Dlatego dobrze jest monitorować temperaturę procesora.
Istnieje oczywiście wiele gotowych aplikacji, które na to pozwalają, ale przecież zawsze fajniej jest zakodować coś samemu, nieprawdaż? :) A już zupełnie świetnie jest wtedy, gdy użyjemy do tego naszego ulubionego narzędzia do administrowania systemem, czyli PowerShella.

Przy jego pomocy pobranie aktualnej temperatury procesora nie jest trudne. Posługujemy się do tego WMI – Windows Management Instrumentation – które to jest rozszerzeniem modelu sterowników systemu Windows, pozwalającym m.in. na monitorowanie różnego rodzaju informacji diagnostycznych. PowerShell zawiera wbudowane komendy, pozwalające na tworzenie obiektów WMI – wśród nich również takich, które udostępniają informacje na temat temperatury procesora:

  1. # cpu-temp.ps1
  2. # Pokazywanie temperatury procesora
  3.  
  4. $tzt = Get-WmiObject -Class "MSAcpi_ThermalZoneTemperature"
  5.     -Namespace "root\WMI" -ErrorAction SilentlyContinue
  6. if ($tzt -ne $null)
  7. {
  8.     $rawTemp = $tzt.CurrentTemperature
  9.     $tempC = ($rawTemp - 2732) / 10
  10.     "Temp. procesora: " + $tempC.ToString() + " st. C" | Out-Host
  11. }
  12. else { "Pomiar temperatury niemożliwy." | Out-Host }

Z bliżej nieokreślonych powodów wartość temperatury podawana jest w dziesiątych częściach kelwinów, więc konieczne jest ich przeliczenie na stopnie Celsjusza. Ponadto istnieje też prawdopodobieństwo, że używana tutaj klasa WMI o nazwie MSAcpi_ThermalZoneTemperature nie jest dostępna na naszym komputerze – zależy to prawdopodobnie od modelu jego płyty głównej. W moim przypadku powyższy kod działał bez problemu na komputerze stacjonarnym, lecz nie na laptopie. Może to i dobrze… Mam bowiem uzasadnione przeczucie, że temperatura tamtejszego procesora wcale by mi się nie spodobała ;)

Tags: , , ,
Author: Xion, posted under Programming » 8 comments

Znak wodny w polu tekstowym

2010-07-10 13:16

Panuje obecnie moda na to, aby strony WWW jak najskuteczniejszej udawały, że nimi nie są i zamiast tego mieniły się ‘aplikacjami internetowymi’. Duża w tym zasługa możliwości JavaScriptu w nowoczesnych przeglądarkach. Jeśli potrafimy przeboleć pisanie w nim, to możemy osiągnąć całkiem efektowne rezultaty. Albo takie nieco mniej imponujące, ale też zgrabne :)
Do tej drugiej kategorii należy efekt znany jako watermark textbox, niemający wbrew pozorom żadnego związku ze znakami wodnymi w obrazkach. Trik ten – z którym zapewne tutejsza większość się zetknęła – polega na wyświetlaniu nieco przyszarzonego komunikatu w polu tekstowym, który następnie znika, gdy użytkownik umieści w nim kursor. Oprócz sprawiania wrażenia, że “strona żyje”, ta prosta sztuczka ma też wymiar praktyczny: pozwala oszczędzić na zbędnej etykiecie textboxa.

Chcąc “wodne” pole tekstowe umieścić na swojej stronie, możemy skorzystać z jednego z gotowych rozwiązań. Wiele z nich używa jQuery – darmowej biblioteki ułatwiającej pisanie w JS. Jeśli jednak nie korzystamy z niej w innych miejscach strony, to wymaganie jej obecności nie musi się nam podobać. A ponieważ watermark textbox jest efektem łatwym do zakodowania, spokojnie możemy napisać go własnoręcznie. Prześledźmy zatem, jak da się to zrobić.

Tags: , , , ,
Author: Xion, posted under Internet, Programming » 14 comments

Pętla z wyróżnionym startem

2010-07-07 13:57

Jednym z powodów, dla których nie lubię diagramów blokowych, jest ich prymitywna notacja przedstawiania instrukcji sterujących. Jedyne, czym się tam dysponuje, to if i skok. Jak przy pomocy tylko tego można w klarowny sposób przedstawić jakikolwiek nietrywialny algorytm? To trochę tak, jakby w programowaniu używać tylko pętli nieskończonych i instrukcji break.
Można to robić, oczywiście, ale konsekwencje nie są zbyt ciekawe. Jeśli kryterium opuszczenia pętli jest tak skomplikowane, że trzeba je rozbić na kilka konstrukcji ifbreak i żadna z nich “nie zasługuje” na wyciągnięcie do warunku w samym while/for, to coś tu brzydko pachnie. Nie chciałbym być w skórze tego, kto będzie musiał później takie dzieło debugować.

W bardziej rozsądnych przypadkach da się uniknąć pętli nieskończonych, nawet jeśli od razu nie widać, jak można by to zrobić. I tak odkryłem na przykład, jak można to ładnie zrobić w sytuacji podobnej do poniższej:

  1. T foo;
  2. for (;;)
  3. {
  4.     foo = SomeFunction(sth);
  5.     if (!foo.IsOK()) break;
  6.  
  7.    // (Reszta pętli, zmieniająca sth na podstawie foo)
  8. }

Nazywam to pętlą z wyróżnionym startem, bo typowa jej postać, która nie zawiera (pozornie) nieskończonego kręcenia się w kółko, wygląda tak:

  1. for (T foo = SomeFunction(sth); foo.IsOK(); foo = SomeFunction(sth))
  2.     { /* Reszta pętli, jw. */}

Cała zabawa polega na tym, że pierwsze wywołanie SomeFunction może dać niepoprawną wartość w foo. (Może to być jakieś wyszukiwanie w pojemniku i element odpowiadający kluczowy sth nie został w ogóle znaleziony). Sama treść pętli nie może być wtedy wykonana, bo zdarzy się zapewne jakieś nieszczęście. Dlatego trzeba wyodrębnić to pierwsze wywołanie, i oczywiście zadbać także o kolejne. A to daje, jak widać, dublowanie kodu. Chciałoby się to zrobić lepiej.

I można, na szczęście. Możemy za to podziękować feature‘owi C++, który często bywa krytykowany jako ułatwiający popełnianie błędów. Bowiem to dzięki temu, że instrukcja przypisania zwraca wartość przypisywaną, możemy to wszystko zapisać tak:

  1. for (T foo; (foo = SomeFunction(sth)).IsOK(); /* nic */)
  2.     { /* Reszta pętli */ }

Zdaję sobie sprawę, że dla wielu fakt ten jest równie oczywisty jak pisanie return a == b; zamiast:

  1. if (a == b) return true; else return false;

ale dla niektórych taka postać pętli for może być zupełnie zaskakująca. Pamiętajmy, że kiedyś (prawie) każdy pisał też i takie ify jak powyżej ;-)

Tags: ,
Author: Xion, posted under Programming » 1 comment

W obronie π

2010-07-05 11:32

Doprawdy ciekawe pomysły można czasami znaleźć w Internecie. Na pierwszy rzut mogą wydawać się zupełnie szalone, lecz po bliższym przyjrzeniu daje się w nich zauważyć pewien sens… Ale zwykle tylko pewien, tj. niewielki :) Tak właśnie jest z ideą “nowej stałej okręgu” – liczbą \tau (równą 2\pi), której to propozycja zawarta jest tekście o intrygującym tytule The Tau Manifesto.

Postulat zastąpienia liczby \pi – chyba najbardziej znanej stałej, występującej w matematyce, fizyce, grafice komputerowej i generalnie każdej dziedzinie wiedzy, mającej cokolwiek wspólnego z liczeniem czegokolwiek – wygląda zrazu na zupełnie szalony. Tym niemniej Manifest Tau zawiera naprawdę sporo argumentów przemawiających za tezą, że jednak \tau jest bardziej użyteczną liczbą i lepiej spełnia funkcję “stałej okręgu” niż jej połówka, czyli \pi. Ich podsumowanie wygląda mniej więcej tak:

  1. Definicja \pi jest nienaturalna, bo wykorzystuje pojęcie średnicy okręgu zamiast jego promienia. Promień jest tu lepszy w tym sensie, że okrąg można zdefiniować jako zbiór punktów w równej odległości od swojego środka – odległości równej właśnie promieniowi.
  2. \pi we wzorach matematycznych występuje często z czynnikiem 2 – na tyle często, że można stwierdzić, iż właśnie 2\pi jest ważniejszą wartością niż samo \pi.
  3. Standardowa miara kątów płaskich w radianach przypisuje 2\pi kątowi pełnemu, czyli kątowi jednego obrotu po okręgu. Przy użyciu \tau kąt ten wyraża się jako 1\tau, co wydaje się znacznie bardziej intuicyjne. Łatwiej jest też podobno wytłumaczyć, że np. ćwiartka okręgu to \tau/4, a nie \pi/2.
  4. Słynna tożsamość Eulera ( e^{i\pi}+1=0 ), łącząca pięć ważnych stałych matematycznych, ma też swój odpowiednik w postaci wykorzystującej \tau: e^{i\tau}=1+0.
  5. Wzór na pole koła ( \pi r^2 ), w którym występuje \pi z czynnikiem 1, po przepisaniu na \frac{1}{2}\tau r^2 staje się podobny do niektórych wzorów fizycznych (zwanych tutaj formami kwadratowymi), jak np. \frac{1}{2}gt^2 czy \frac{1}{2}mv^2.

W oryginalnym artykule argumenty te przedstawione są rzecz jasna w sposób znacznie bardziej pomysłowy, elokwentny i trącący przekazywaniem “oczywistej oczywistości”, że się tak kolokwialnie wyrażę :) Trąci też jednak nadmiernym zamiłowaniem do numerologii i przywiązywaniem wagi to takich rzeczy jak czynnik przy jakiejś stałej w tym czy innym wzorze. Lecz nawet jeśli przyjmiemy tę konwencję, to znalezienie przekonujących kontrargumentów wcale nie jest trudne.

Tags: ,
Author: Xion, posted under Math » 13 comments

Split

2010-07-02 17:44

Tytuł dzisiejszej notki nie ma nic wspólnego z miejscowością wypoczynkową na południu Chorwacji, chociaż pewnie obecne temperatury nasuwają takie skojarzenia :) Zamiast tego chodzi o split łańcucha znaków, czyli bardzo często potrzebną w praktyce operację na stringach.
Danymi dla niej są najczęściej dwa napisy, zaś wynikiem jest tablica podciągów pierwszego z nich, powstała poprzez podzielenie go względem wystąpień drugiego (tzw. separatora). Ponieważ jak zwykle przykład będzie mówił najwięcej, niniejszym podaję nawet kilka:

  1. Split("Ala ma kota", " ") == { "Ala", "ma", "kota" };
  2. Split("1, 2, 3, 4", ",") == { "1", " 2", " 3", "4" };
  3. Split("<point x='23' y='14' z='-3' />", " ")
  4.     == { "<point", "x='23'", "y='14'", "z='-3'", "/>" }

Zwłaszcza ostatni pokazuje, że split jest rzeczywiście użyteczną funkcją, mogącą ułatwiać parsowanie formatów tekstowych (zwłaszcza, jeśli daje się ją zastosować wielokrotnie). Warto więc mieć takową w swoim języku/bibliotece. Jak więc przedstawia się jej dostępność na różnych platformach?

Tradycyjnie w .NET i Javie jest dobrze, a nawet lepiej. W obu przypadkach funkcja (a właściwie metoda) Split/split klasy String dodaje nawet trochę więcej możliwości niż to opisałem wyżej. I tak w .NET można podać więcej niż jeden oddzielacz, natomiast w Javie domyślnie może być nim również wyrażenie regularne.
Niektóre języki skryptowe i skryptopodobne też mają się w tym względnie całkiem dobrze. W Pythonie jest metoda split w klasie napisu, natomiast PHP ma funkcję explode, która mimo innej nazwy działa bardzo podobnie.

Ale nie wszędzie funkcja typu split jest od razu dostępna; niekiedy trzeba ją sobie samemu napisać. Przykładem języka, gdzie może być to koniecznie, jest Lua oraz – jakżeby inaczej – C++ :) Ze względu na użyteczność splita często znajdowałem się w sytuacji, gdzie konieczne/wygodne było jego napisanie. Po kilku(nastu?) takich przypadkach doszedłem wreszcie do czegoś podobnego do poniższego kodu:
typedef std::vector StringArray;
StringArray Split(const std::string& text, const std::string& delim)
{
StringArray res;
if (delim.empty()) { res.push_back(text); return res; }

std::string::size_type i = 0, j;
while (i < text.length() && (j = text.find(delim, i)) != std::string::npos) { res.push_back (text.substr(i, j - i)); i = j + delim.length(); } res.push_back (text.substr(i)); return res; }[/cpp] Na koniec zwrócę jeszcze uwagę na to, że czasami trzeba ostrożnie postępować z rezultatem splitu. Zdecydowana większość wersji tej operacji dopuszcza, by w wynikowej tablicy występowały puste ciągi. Odpowiadają one kilku kolejnym wystąpieniom separatora lub jego obecnością na początku bądź końcu ciągu. Jeśli nie są one nam potrzebne (a rzadko są), to należy je zignorować lub usunąć.

Tags: , , , , ,
Author: Xion, posted under Programming » 5 comments
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.