Użycie polskich liczebników w polskich programach

Artykuł do PC-Kuriera - rok 1993

Romuald Żyłła

BLIŻEJ POLSKI

Używanie języka polskiego w programach to nie tylko problem nieśmiertelnych polskich liter. Wiele programów dalekich od dziedziny lingwistyki potrzebuje poprawnie zbudowanych zdań. Język angielski używany w "komputerystyce" jest bardzo uproszczony i część użytkowników przyzwyczaiło się do tych uproszczeń i już ich nie zauważa, druga część uważa ten język za prymitywny slang lub rodzaj folkloru.

Przenoszenie angielskiego slangu na polski slang przynosi, jak widać z niekończących się polemik, jeszcze gorsze potworki językowe. "Lokalizatorzy" są w sytuacji tłumaczy poezji, muszą wybierać między Scyllą wierności a Harybdą piękności przekładu. Proszę zwrócić uwagę na fakt, że w angielskim dużo jest krótkich wyrazów - łatwo je umieszczać w "MENU". Polski język jest gorszy pod tym względem; jakże trudno się zdecydować przetłumaczyć angielski "USER" na "KLIENT" zamiast dłuższego nasuwającego się wyrazu "UŻYTKOWNIK". A jak przetłumaczyć "SAVE", i w jakiej formie? "ZAPIS", "URATOWANIE", "ZACHOWAJ", "ZAPISZ". Mnie się wydaje, że powinny być tłumaczone w trybie rozkazującym. Natomiast formy typu "ZAPISYWANIE" powinny być zarezerwowane dla "MENU"-"OPCJE".

Powrót do poprawności języka w programach komputerowych może/mogą uratować tylko Windows, właśnie lokalizowane, w których przewidziano w "interfejsie użytkownika" dostęp do "Helpa" o dość swobodnej budowie wg zasad "Hypertekstu".

Aby nowe programy były strawne dla nowych ludzi w tej dziedzinie język w nich używany powinien być pozbawiony slangu technicznego i być bardziej naturalny. Jeśli piszę program dla siebie to wszystko jedno jak napiszę komunikaty o błędach i inne teksty, ale programy komercyjne np. TAG lub spolonizowana wersja WINDOWS i WINWORD powinna chyba mieć wbudowane oprócz polskiego słownika także niektóre reguły gramatyki. Od programistów nie wymagam (na razie) sprawdzania poprawności gramatycznej tekstów pisanych przez użytkowników, ale komunikaty wpisane w programy powinny być poprawne gramatycznie. Jak dalej pokażę, nie jest to zadanie skomplikowane.

W wielu polskich programach obserwuję wygibasy gramatyczne wynikające z prób obejścia reguł fleksyjnych przy odmianach wyrazów. Sam nie jestem święty i często piszę w programie np. "liczba bajtów w pliku : 12324", zamiast bardziej naturalnego "w pliku są 12324 bajty" lub, przy innej ich liczbie np. "w pliku jest 955 bajtów".

Oto przykłady z roku 2014: Facebook


Widać, że powinna być użyta forma "Masz 4 nowe powiadomienia" i

Oto przykład z roku 2014: http://www.avaaz.org/pl/

Widać, że spolszczacz z angielskiego skryptu przyjął: jak 1 to minuta, a w przeciwnym przypadku minuty, bo w angielskim mamy tylko dwie formy. Dla zera przyjeto całkiem osobny napis.

Dalszy tekst będzie dotyczył rozwiązania tego problemu.

Zajrzyjmy najpierw do kompetentnego źródła. Dla zainteresowanych podaję cytat z paragrafu 580, "Gramatyki Języka Polskiego" Stanisława Szobera: "... liczebniki główne nie zawsze łączą się z rzeczownikami za pomocą 'zgody'. Deklinacja liczebnika 'cztery' i 'tysiąc' wykazuje dwa krańcowe przeciwieństwa: w jednej mamy we wszystkich przypadkach połączenia za pomocą 'zgody', w drugiej wszędzie połączenia za pomocą 'rządu'.

Deklinacja liczebnika 'pięć' podaje stan pośredni - w mianowniku i bierniku ma połączenie za pomocą 'rządu', w innych przypadkach - za pomocą 'zgody'."

Po tym cytacie być może zrozumiemy dlaczego informatycy nie mogą się zrozumieć z polonistami. Dalej następuje:

"Tak jak 'cztery' łączą się z rzeczownikami liczebniki od 'jednego' do 'czterech' włącznie; jak 'pięć' - liczebniki od 'pięciu' do 'tysiąca' wyłącznie, wreszcie jak 'tysiąc' łączą się z rzeczownikami liczebniki 'tysiąc', 'milion', 'bilion' itd.".

Powyższe fragmenty są jedynymi, które można by nazwać przepisem lub algorytmem na ten temat.

Algorytm określający reguły wyboru właściwej końcówki do czasownika poprzedzającego i następującego rzeczownika, którego dotyczy liczba wymaga określenia dla liczby całkowitej jej dwóch ostatnich cyfr oraz ostatniej cyfry, wymagana jest także obsługa wyjątku gdy liczba równa się 1. W niektórych aplikacjach trzeba uwzględnię sytuację wyjątkową gdy liczba równa jest 0 (zero).

Dla przykładu można stwierdzić, że rzeczownik 'komputer' występuje w trzech formach:
      1 komput-er     2 komput-ery     5 komput-erów.
Dla innych liczb całkowitych jest to zawsze tylko jedna z tych form.

N       rzeczownik       rzeczownik    rzeczownik
--------------------------------------------------
0       komputerów       dyskietek     ksiąg
1       komputer         dyskietka     księga
2,3,4   komputery        dyskietki     księgi
5...21  komputerów       dyskietek     ksiąg
22..24  komputery        dyskietki     księgi
25..31  komputerów       dyskietek     ksiąg
32..34  komputery        dyskietki     księgi
itd do 99.   

Powyżej 100 trzeba wydzielić dwie ostatnie cyfry i według nich zastosować ten sam schemat.

Jak widać, da się wyróżnić specjalny przypadek N = 1, (forma jak dla 1) oraz zakres 5 do 21 (forma jak dla 5). W pozostałych przypadkach, jeśli ostatnia cyfra jest z zakresu 2 do 4, stosuje się formę jak dla 2, w przeciwnym przypadku daje się formę jak dla 5.

W rzeczownikach wyróżnia się rdzeń i końcówkę. W naszym przykładzie rdzeniem jest 'komput', a trzema możliwymi końcówkami 'er', 'ery', 'erów'. Jeśli nazwiemy końcówkę występującą po 1, 2, 5 odpowiednio KONC1, KONC2, KONC5 to każdą z form można złożyć z rdzenia i jednej z końcówek. Warto zauważyć, że podział jest czysto umowny bo mogą to być : 'komputer', ' '(pusta końcówka), 'y', 'ów'. W tym szczególnym przypadku jedna z końcówek jest pusta.

Ponieważ musi następować zgodność gramatyczna czasownika i rzeczownika przedzielonych liczbą to tym samym regułom podlegają czasowniki np.: 'zost', 'ał', 'ały', 'ało', albo: '', 'jest', 'są', 'jest', (w tym przypadku rdzeń jest pusty).

Powyższy schemat pokazuję w języku BASIC-EXT dla MERY-400 oraz w Turbo Pascalu aby uświadomię łatwość jego implementacji. Jest to wystarczająca dokumentacja żeby zrealizować go w dowolnym języku programowania baz danych (Clipper, PROGRESS, DataFlex). Pokazuję także przykłady stosowania w postaci funkcji i fragmentu programu.

Oczywiście funkcja ZGODNOSC nie ma wbudowanych reguł na odmianę końcówki dla słów w zależności od rodzaju męskiego, żeńskiego i nijakiego. Złe lub dobre użycie funkcji ZGODNOSC zależy od piszącego aplikację (teraz programiści powinni się nazywać chyba "aplikatorami"?) i jego znajomości polskiego. Jeśli programista sam nie wie czy się pisze prawidłowo "są 2 klienci" czy "jest 2 klientów", to funkcja ZGODNOSC za niego nie zadecyduje.

Na zakończenie zapytanie do firm lokalizujących produkty Microsoftu. Czy posiadają one dostęp i możliwości zmiany w kodzie programów lokalizowanych aby wprowadzić proponowane funkcje? Czy może, tylko zmieniają teksty w programach a wielki wujek sam kompiluje te teksty w komputerach w Redmont na drugiej półkuli?

Wydruk 1

100 REM  MERA-400  BASIC-EXT 
. 
540 LET N0=N ; N1=MOD(N0,10) ; N2=MOD(N0,100) 
550 IF N0=1 LET W$=" " GOTO 590
560 IF 4 < N2 IF N2 < 22 LET W$="OW" GOTO 590
570 IF 1 < N1 IF N1 <= 4 LET W$="Y" GOTO 590
580 LET W$="OW"
590 PRINT #4: "WYKRES OBEJMUJE ";N0;" PUNKT";W$ 

600 REM  WYJSCIE

(* TURBO PASCAL v 5.5 *)
uses DOS;
function ZGODNOSC( i : longint; RDZEN: DirStr;
                   KONC1,KONC2,KONC5: NameStr): PathStr;
var   N0, N1, N2 : longint;   {jeśli zajdzie potrzeba to}
      R0 : NameStr;  {można zadeklarować dłuższy łańcuch}
begin
  N0:=I;  N1:= N0 MOD 10;  N2:= N0 MOD 100;
  IF N0=1
    then R0:=KONC1
    else IF (N2>4) AND (N2<22)
            then R0 := KONC5
            else IF (N1>1) AND (N1<=4)
                   then R0 := KONC2
                   else R0 := KONC5;
  ZGODNOSC := RDZEN + R0
end; { fun ZGODA }


function PokazILE( i : longint ): PathStr;
var  Lstr : string;
begin
  Str( i, Lstr );
  Lstr := ZGODNOSC( i,'','jest','są','jest') + 
          ' ' + LStr + ' ' +
          ZGODNOSC( i,'pozycj','a','e','i');
  PokazILE:=  ' W bazie danych ' + Lstr;
end; { PokazILE }

var  p, k, s : integer;
begin

  repeat
    write('Ile jest sprzedawczyń w sklepie : '); readln(s);
    write('Ile jest parasoli w magazynie   : '); readln(p);
    write('Ile jest klientów przed sklepem : '); readln(k);
    writeln(ZGODNOSC(s,'W sklepie ','jest','są','jest') +
             ' ', s, ' ' +
            ZGODNOSC(s,'sprzedawczy','ni','nie','ń') );
    writeln(ZGODNOSC(p,'W magazynie ','jest','są','jest') +
             ' ', p, ' ' +
            ZGODNOSC(p,'parasol','','e','i') );
    writeln(ZGODNOSC(k,'Przed sklepem ','jest','są','jest') +
             ' ', k, ' ' +
            ZGODNOSC(k,'klien','t','ci','tów') );
    writeln( 'Przykład komunikatu : ', PokazIle( s+p+k ) );
  until FALSE;
end.

Polecam dydaktykom informatyki używanie powyższego algorytmu jako przykładu budowy algorytmu, który opiera się na potocznej znajomości języka polskiego przez każdego studenta i nie wymaga znajomości fizyki, matematyki lub metod numerycznych. Od etapu sformułowania problemu, poprzez analizę, schemat blokowy i jego implementację w konkretnym języku jest to problem do 'strawienia' przez laika informatycznego. W moich zajęciach z Turbo Pascala stosuję go jako przykład budowy funkcji, pojęcia parametru aktualnego i formalnego oraz zagłębienia instrukcji warunkowej.