3. Powoli wchodzimy do konsoli, czyli nasze pierwsze kodu wiersze

Zgodnie z zapowiedziami w poprzednim wpisie, napiszemy dzisiaj pierwsze linie działającego oprogramowania.

Wybór jakiego narzędzia użyć, jakiego języka się uczyć, nigdy nie jest prosty, jednak jeśli mówimy o możliwie komfortowym działaniu początkujących użytkowników korzystających z czytnika ekranu, ten wybór jest przede wszystkim determinowany przez dostępność.

Nasze pierwsze kodu wiersze wpiszemy więc w Eltenie, środowisku stworzonym z myślą o dostępności dla użytkowników czytników ekranu, które ponadto:

  • Daje wygodny i łatwy dostęp do możliwości tworzenia oprogramowania używającego przestrzennego audio,
  • umożliwia prostą wymianę informacji między zalogowanymi użytkownikami (aplikacje sieciowe),
  • posiada międzynarodową społeczność użytkowników,
  • jest oprogramowane w języku Ruby i udostępniane na licencji otwartego kodu.

Konsola, o której mówi tytuł, to narzędzie spotykane w przeglądarkach internetowych, czytniku ekranu NVDA, a także w Eltenie. Pozwala szybko uruchamiać krótkie fragmenty oprogramowania, można jej więc użyć do różnych celów: od prostego kalkulatora, poprzez pierwsze wprawki w tworzeniu kodu, na bardziej zaawansowanej diagnostyce kończąc.

W Eltenie konsolę znajdziemy w menu Narzędzia.

Składa się z dwóch pól edycyjnych: w pierwszym umieszczamy polecenia do wykonania, drugie będzie zawierało ich rezultat po naciśnięciu przycisku “Wykonaj”. Zamiast przycisku “Wykonaj” możemy nacisnąć Control+Enter.

Konsolę można też umieścić we własnym menu szybkich akcji i przypisać do niej skrót klawiaturowy, aby mieć do niej jeszcze szybszy dostęp.

Kalkulator

Zacznijmy zatem od użycia konsoli w roli kalkulatora, wpisując:

2+2

Po naciśnięciu Ctrl+Enter, otrzymamy wynik

:   #=> 4

Znaczki “#=>” poprzedzają w konsoli linie wygenerowane przez interpreter języka Ruby. To wpisane przez nas 2+2 nie było żadnym poleceniem, nie przypisywało wyniku do żadnej zmiennej, nie zawierało też instrukcji, aby wyświetlić gdziekolwiek wynik. Wyświetlenie wyniku zostało wykonane przez interpreter języka, jako element obsługi trybu konsoli.

Możemy oczywiście dokonać znacznie bardziej złożonych obliczeń:

2+(2*3)**4

: #=> 1298

Skąd taka duża liczba? Z kolejności wykonywania działań: Wyrażenie w nawiasie (2*3) to 6. 6 do potęgi czwartej (operator podwójnej gwiazdki „**”) to 1296. Wreszcie dodając do tego 2 z przed nawiasu, otrzymujemy wynik końcowy.

Pierwsza funkcja

Wspominaliśmy wcześniej o różnicy między procedurą i funkcją, oraz podobieństwami i różnicami funkcji w programowaniu i funkcji matematycznej. Zdefiniujmy zatem prostą funkcję matematyczną w konsoli:

def f(x)
return x*2
end

Słowo kluczowe “def” oznacza, że będziemy definiować funkcję lub procedurę. “f” oznacza nadaną przez nas nazwę, mogłaby się ona nazywać dowolnie. x w nawiasie to parametr, który przyjmuje nasza funkcja.

Polecenie “return” mówi, że to co nastąpi po nim, to będzie wartość zwracana przez funkcję. W naszym przypadku jest to 2*x, czyli funkcja zwróci podwójną wartość x.

I wreszcie “end” oznacza zakończenie funkcji.

Odpowiedź w konsoli:

:   #=> nil

oznacza, inaczej niż w poprzednim przypadku, że nie otrzymaliśmy żadnego liczbowego wyniku. Brak wiadomości o błędzie, to dobra informacja, bo oznacza, że nasza funkcja została przyjęta.

Sprawdźmy teraz, czy działa, wpisując:

f(4)

Otrzymujemy, zgodnie z oczekiwaniami:

:   #=> 8

Sprawdźmy dla innej wartości:

f(12)

otrzymujemy:

:   #=> 24

A zatem, zgodnie z oczekiwaniami, rezultatem, czyli zwróconym przez funkcję f wynikiem, jest podwojona wartość x, którą podajemy jako parametr.

Dozwolone nazwy

Tworzone przez programistę zmienne, funkcje, klasy itp., muszą mieć jakieś nazwy. Nazwy te muszą spełniać poniższe warunki: – Zaczynać się od litery. – Zawierać litery (duże lub małe), cyfry, niektóre znaki specjalne, np. znak podkreślenia, lub znak zapytania. – być inne niż używane słowa kluczowe języka programowania. – Być inne niż jakieś elementy już wcześniej zdefiniowane w programie. – Uwaga: w Ruby nazwy zmiennych zaczynające się z dużej litery, to stałe.

Sprowokujmy jakiś błąd

Co by było, gdybyśmy utworzyli funkcję o nazwie def? Jak wiemy, jest to słowo zarezerwowane przez język Ruby do definiowania funkcji, ale spróbujmy:

def def(x)
return x*2
end

O dziwo, interpreter przyjął naszą definicję, zwracając znane już “#=> nil”, ale czy to zadziała?

def(4)

otrzymujemy:

:   #=> SyntaxError (compile error
Console:1: can't define singleton method for literals
def(4)

A zatem istotnie, nasza nazwa się interpreterowi języka nie spodobała.

Konwencje nazw w projekcie

Każda aplikacja czy program, posiada też jakieś własne konwencje nazw, których warto przestrzegać, modyfikując go. Wśród nich, warto wymienić:

  • Język nazw: polski czy angielski? Angielski jest zdecydowanie lepszym pomysłem, skoro słowa kluczowe języka też są po angielsku, a w przyszłości nasz kod mógłby chcieć zmieniać ktoś nieznający polskiego.
  • Nazwy złożone z wielu słów: czy rozdzielać słowa podkreśleniem, skoro spacja jest niedozwolona, a może każde słowo pisać z dużej litery, czy wreszcie może pierwsze z małej, a każde następne z dużej (tzw. camel-case)?

Osobne zagadnienia, to konwencje tworzenia komentarzy, formatowania kodu (wcięcia), ale nie będziemy się nimi w tym miejscu zajmować.

Powiedzmy wreszcie coś.

Mamy w konsoli sprytnie działający kalkulator, nawet z możliwością definiowania funkcji matematycznych, jednak chyba nie całkiem o to nam chodziło. Chcemy przecież, żeby do nas komputer przemówił… W Eltenie do generowania wypowiedzi służy procedura alert, która jako parametr przyjmuje tekst do wypowiedzenia. W języku Ruby podobnie jak większości innych, teksty w programie zamyka się w cudzysłowach lub apostrofach.

Wpiszmy zatem w konsoli:

alert("To jest nasz pierwszy wypowiedziany tekst.")

Usłyszymy tę wypowiedź, a w polu z wynikami pojawi się standardowe “#=> nil” oznaczające, że funkcja alert nie zwróciła żadnej wartości (a dokładniej – zwróciła wartość nil, czyli nic).

Instrukcja warunkowa

Chcemy napisać program, który będzie wypowiadał aktualny dzień tygodnia.

Najpierw przygotujemy funkcję, która dla liczby z zakresu 1 do 7 (numer dnia) zwróci nam nazwę tego dnia tygodnia. Następnie, zwróconą nazwę przekażemy do funkcji alert, aby ją wypowiedzieć. Na koniec, parametrem dla funkcji uczynimy aktualny dzień tygodnia zwracany przez system.

Jak powinna wyglądać funkcja dayName (nazwa dnia)?

Dla podanego parametru dayNumber (numer dnia), jeżeli jest równy 1, to zwróć “poniedziałek”, jeśli równy 2 – zwróć “wtorek” i tak dalej…

Czyli kluczowa będzie tu instrukcja warunkowa, która w Ruby ma postać:

if warunek
  akcja
else
  inna_akcja
end

If to z angielskiego “jeżeli”, a else – “w przeciwnym wypadku”. Słowo end (“koniec”), które wcześniej kończyło definicję funkcji, kończy też blok instrukcji warunkowej.

Warunkiem jest coś, co chcemy sprawdzić, np. czy wartość zmiennej x jest równa 1? Przypiszmy więc zmiennej x wartość 1, a później sprawdźmy, czy tak została ustawiona.

x=1
if x == 1
  alert("x jest jeden")
else
  alert("x nie jeden.")
end

Usłyszymy, zgodnie z oczekiwaniem, że x jest jeden.

Porównanie i przypisanie

Warto teraz zauważyć dwie rzeczy.

  1. Pojedynczy znak równości, przypisuje wartość do zmiennej (x=1).
  2. Podwójny znak równości, porównuje to co jest po lewej stronie z tym co po prawej, czyli np. czy a jest równe 1.

Sprawdźmy jeszcze, czy program zachowa się zgodnie z oczekiwaniem, gdy do x przypiszemy coś innego niż 1.

x=2
if x == 1
  alert("x jest jeden")
else
  alert("x nie jeden.")
end

Usłyszymy, że x nie jeden.

A co by było, gdybyśmy omyłkowo wpisali tylko jeden znak równości w sprawdzeniu? Jest to dramatycznie częsty błąd, który czasem zdarza się popełnić nawet doświadczonym programistom.

x=2
if x = 1
  alert("x jest jeden")
else
  alert("x nie jeden.")
end

Usłyszymy, że x jest jeden, a przecież nie tego się spodziewaliśmy.

Dlaczego tak się dzieje? Wpisując w sprawdzeniu pojedynczy znak równości, zamiast podwójnego, zamieniamy instrukcję porównania na instrukcję przypisania. Instrukcja przypisuje x wartość 1, a ponieważ to przypisanie się powiodło i zmienna została przestawiona, to warunek if, jest uznany za spełniony. Dzieją się dwie złe rzeczy: wartość zmiennej jest nieoczekiwanie przestawiona na inną, a program uznaje za spełniony warunek, którego za taki nie powinien uznać.

Wartość zmiennej w tekście

Czy jednak na pewno wartość x została przestawiona na 1? Moglibyśmy powtórzyć w naszym programie prawidłowe sprawdzenie tego jeszcze raz po tym błędnym, ale możemy też po prostu wypowiedzieć wartość zmiennej x.

alert(x)

Usłyszymy “1”.

A co, gdybyśmy chcieli przedstawić tę wartość w trochę bardziej sensowny sposób, jako część większej wypowiedzi?

W Ruby składnia pozwalająca umieścić zmienną jako część tekstu (łańcucha) jest następująca:

alert("Teraz a jest #{a}")

Usłyszymy, że teraz a jest 1.

Instrukcja puts

Dotychczas generowaliśmy komunikaty za pomocą alert, która jest funkcją Eltena, wypowiadającą jakiś tekst. Tekst jest wypowiadany, ale nie trafia do pola wyników konsoli.

Gdybyśmy chcieli uruchomić jakiś program w zewnętrznej konsoli Ruby, poza Eltenem, też nam to alert nie zadziała.

Funkcją wbudowaną w Ruby służącą do wyprowadzania tekstu na ekran konsoli, jest puts:

puts("Teraz a jest #{a}")

Informacja pojawiła się w polu wyników konsoli Elten.

Bardziej złożona instrukcja warunkowa

Dotychczas dokonywaliśmy jednego sprawdzenia przy pomocy if i else, gdybyśmy jednak chcieli sprawdzać dalej, kolejne wartości x?

Według naszej aktualnej wiedzy, musiałoby to wyglądać tak:

x=2
if x == 1
  alert("x jest jeden")
else
  if x == 2
    alert("x jest dwa.")
  else
    alert("x nie jeden i nie dwa.")
  end
end

Wygląda trochę skomplikowanie, zagnieżdżenie drugiej instrukcji if w obszarze else pierwszej, spowodowało konieczność zakończenia ich obu osobnymi endami. Jeśli wyobrazimy sobie, że to samo musimy wykonać jeszcze sześciokrotnie dla otrzymania funkcji zwracającej nazwę dnia tygodnia, a na końcu będziemy mieć do czynienia z sześciokrotnie zagnieżdżonymi instrukcjami warunkowymi, to można się zniechęcić.

Na szczęście, ten problem wynika wyłącznie z naszej niewiedzy i dość łatwo mu zaradzić.

Instrukcja elsif

elsif to zbitek słów “else” i “if”, oznaczający, że jeśli zawiodło poprzednie sprawdzenie i wykonany zostałby jego blok “else”, to tu musi zostać wykonane od razu kolejne sprawdzenie. Bardzo to upraszcza cały kod i zwalnia nas z konieczności zagnieżdżania następnych instrukcji warunkowych w obszarze “else” poprzednich.

x=2
if x == 1
  alert("x jest jeden")
elsif x == 2
  alert("x jest dwa.")
  else
    alert("x nie jeden i nie dwa.")
end

Dużo prościej, ale i tak mogłoby być lepiej.

Jednoliniowa instrukcja warunkowa

Ruby umożliwia konstruowanie prostych instrukcji warunkowych, jeśli dotycząca ich akcja i warunek znajdują sie w jednej linii.

Taki zapis ma następującą składnię:

akcja if warunek

Czyli w naszym przypadku:

x=2
alert("x jest jeden") if x == 1
  alert("x jest dwa.") if x == 2

Taki uproszczony zapis nie umożliwia utworzenia gałęzi else, czyli w naszym przypadku musieliśmy zrezygnować z opisu sytuacji, że x nie 1 i nie 2. Do pewnych prostych przypadków, sprawdza się nie źle, więc warto go znać.

Instrukcja case

Case, czyli przypadek, to instrukcja analizy różnych przypadków pojedynczej zmiennej.

x=2
case x
  when 1
    alert("x jest jeden")
  when 2
    alert("x jest dwa.")
  else
    alert("x nie jeden i nie dwa.")
end

Teraz już dość łatwo możemy przygotować planowaną wcześniej funkcję zwracającą nazwę dnia tygodnia.

Funkcja dayName

Planowana funkcja ma zwracać 7 wartości tekstowych będących nazwami dnia, zależnie od podanego numeru dnia. Łatwo sobie wyobrazić, że wystarczy użyć 7 razy polecenia return, gdy spełniony będzie warunek, że parametr dayNumber jest równy numerowi dnia.

Niektórzy twierdzą jednak, że prawidłowo napisana funkcja, powinna zwracać wartość tylko w jednym miejscu, a nie w kilku różnych, co z pewnych powodów ma swoje plusy, więc zastosujmy się do tego. W funkcji utworzymy zmienną res (skrót od result, czyli wynik), do której przypiszemy jedną z wartości, a następnie zwrócimy wartość res, jako wynik funkcji.

def dayName(dayNumber)
  case dayNumber
    when 1
      res="poniedziałek"
    when 2
      res="wtorek"
    when 3
      res="środa"
    when 4
      res="czwartek"
    when 5
      res="piątek"
    when 6
      res="sobota"
    when 7
      res="niedziela"
  end
  return res
end

Funkcja została przyjęta przez interpreter, ale czy działa zgodnie z założeniami?

alert(dayName(3))

Usłyszymy “środa”.

alert(dayName(6))

Usłyszymy “sobota”.

Rzeczywisty dzień tygodnia

Aby pobrać rzeczywisty dzień tygodnia, posłużymy się metodą Time.now.wday.

Zabrzmiało ciekawie, prawie jak coś w rodzaju adresu internetowego. Analogia nie jest całkiem chybiona.

Notacja kropkowa jest używana w odniesieniu do obiektów.

Obiekt Time to obiekt klasy czas. Jednym z jego atrybutów jest now, będący obiektem określającym aktualny czas. Jednym z atrybutów obiektu Time.now jest atrybut wday, zwracający aktualny dzień tygodnia.

Jest tylko jeden problem – wartość wday nie jest kompatybilna z parametrem przyjmowanym przez naszą funkcję dayName, gdyż wday zwraca wartość 0 dla niedzieli.

Musimy zatem dokonać prostej przeróbki uwzględniającej ten przypadek.

Następnie wywołamy funkcję dayName z parametrem Time.now.wday jako parametr dla funkcji alert, więc całe to piętrowe wywołanie wyglądać będzie następująco:

alert(dayName(Time.now.wday))

Program odczytujący dzień tygodnia

Aktualnie nasz program odczytujący aktualny dzień tygodnia, wygląda następująco:

def dayName(dayNumber)
  case dayNumber
    when 0
      res="niedziela"
    when 1
      res="poniedziałek"
    when 2
      res="wtorek"
    when 3
      res="środa"
    when 4
      res="czwartek"
    when 5
      res="piątek"
    when 6
      res="sobota"
  end
  return res
end
alert(dayName(Time.now.wday))

Tablica czyli czy nie da się prościej

Napisaliśmy nasz pierwszy program, mający 20 linii kodu. Nie jest to dużo, ale też nie tak całkiem mało.

W programowaniu, podobnie jak w innych dziedzinach, istnieje na ogół wiele sposobów pozwalających osiągnąć określony rezultat.

W oparciu o zmienne numeryczne i łańcuchowe (tekstowe) nie dało się tego zadania zrealizować prościej, ale na pomoc przychodzi nam zmienna tablicowa.

Tablice to zmienne mogące składać się z wielu numerowanych elementów. Każdym z tych elementów może być jakaś wartość, czyli numer, tekst lub tablica. Zapewne także obiekt, skoro o nich już była mowa. Do każdego elementu tablicy można szybko odwołać się przez jego numer podając go w nawiasach kwadratowych. Indeksy, czyli numery elementów tablicy zaczynają się od wartości 0.

Zdefiniujmy zatem tablicę dni tygodnia i wypowiedzmy jej czwarty element.

weekDays=["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"]
alert(weekDays[4])

Usłyszeliśmy “czwartek” co jest zgodne z oczekiwaniami, a weekDays[0] to byłaby niedziela.

Czas uprościć naszą funkcję dayName:

Podsumowanie: gotowy program powiedz dzień tygodnia

def dayName(dayNumber)
  weekDays=["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"]
  return weekDays[dayNumber]
end
alert(dayName(Time.now.wday))

Dawniejsze 20 linii kodu uprościliśmy do całych 5.

17 komentarzy

  1. A więc tak:

    Jak już tutaj Dawid napisał, pojedynczy znak równa się w takich miejscach jak if to sztuczka, która przydaje się czasem zaawansowanym. Podniesiona tutaj uwaga o jej zakazaniu nie jest jednak tak całkiem bezzasadna. Są niektóre języki programowania, które tego owszem zakazują. Zaawansowany programista czasem napisze linijkę kodu więcej, ale z kolei nie spędzi pięciu minut nad głupim błędem, a taki się może zdażyć każdemu. Która z dwóch opcji jest lepsza? To już pytanie dla projektanta języka, który musi rozważyć wszystkie za i przeciw. Dla tego z resztą tyle ich mamy, różni ludzie mają różne opinie, różne gusta i różne zastosowania, podejmóją przez to inne decyzje, więc wychodzą im inne języki. Większość języków, zwłaszcza tych nowszych, ma gdzieś taki zbiór zasad, którymi kierują się ich projektanci. Na przykład dla Rubiego naczelną zasadą jest wygoda dla programisty, nie dla komputera. Oznacza to ni mniej ni więcej, że ważniejszy jest szybki do napisania i łatwy do czytania kod, niż kod w pełni optymalny, który działa w jak najkrutszym czasie. Taka opinia wynika z tego, że w dzisiejszych czasach taniej jest kupić sobie lepszy komputer niż zatrudnić więcej programistów. Inne języki mają inne zasady, np. popularny ostatnio Rust promuje kod wydajny i wolny od błędów, głównie bezpieczeństwa , kosztem trudności pisania programów i legendarnej wręcz niedostępności dla początkujących. Gdy piszemy na przykład system operacyjny, którego używają miliony ludzi i w którym każda luka może sprawić ogromne problemy, taki język staje się zdecydowanie bardziej odpowiednim.

    Co do dni tygodnia. Porównanie z religią jest tutaj bardzo słuszne i zasadne, konwencja traktowania niedzieli jako pierwszego dnia tygodnia przyszła do nas z Ameryki. Nie wiem, kto i jak ją tam ustalił, ale podejrzewam, że z Chrześcijaństwem, choć może nie Katolicyzmem, mogło to mieć wiele wspólnego.

    Co do liczenia od zera, tak, komputery z tego słyną. My, ludzie, też czasem tak robimy. Od, chociażby, licząc przejechany dystans na rowerze, czas okrążenia czy ilość punktów karnych, nie zaczynamy liczyć od jednego kilometra, minuty czy punktu. Wyobraźmy sobie tablice jako długą magnetofonową taśmę, na której zapisane są jakieś dane. Podając indeks w tablicy podajemy, ile centymetrów od początku taśmy powinna znajdować się głowica, które te dane będzie czytać lub zapisywać. Patrząc na to w ten sposób logicznym jest, że aby pierwszy element znajdował się na samym początku, powinien być on 0cm od początku taśmy, stąd jest on elementem zerowym. To porównanie do taśmy podaję nie bez przyczyny, bo pamięć komputera możemy sobie wyobrażać właśnie jako niesamowicie długą taśme podzieloną na jednobajtowe kawałki. Na każdym z tych kawałków możemy sobie zapisać jakieś dane, które z tego kawałka potem będzie można odczytać. Tablica to nic innego, jak pewien blok takich bajtów, w którym elementy (o określonym, znanym nam wcześniej rozmiarze) znajdują się jeden przy drugim. Podając indeks 0 mówimy, że czytaj jakby 0 bajtów od początku tablicy. Tak przynajmniej wyglądało to kiedyś i w starszych językach typu C, ale konwencja liczenia elementów od zera tak przez nie wryła sie programistom w pamięć, że innym językom łatwiej jest za tą konwencją podążać niż wymyśać coś swojego. Są w prawdzie języki liczące od jedynki, ale wielu zaznajomionych z programowaniem ludzi to irytuje. Z ciekawostek, jednym z takich języków jest chociażby LUA, w której z resztą pisane było Klango, przynajmniej w części.

  2. the if x=1 must return a warning, not an error.
    program warning dialog, you wrote: if x=1. is that what you wanted to do: do you want to replace to if x==1? this must show in developer mode

  3. Może i ładniej wygląda, ale gorzej się czyta mową.
    delete_all_files_on_user_hard_drive_immediately if ten_times_confirmed_operation

    1. Też nie przepadam za jedno liniowcami, a jeszcze jak coś robiłem ponad 20 lat temu w zwykłym C, to tam te średniki na końcu wierszy zdaje się. i to one były ważniejsze, niż entery – nowe wiersze. Ale to jednoliniowe „if” mi się spodobało.
      ech. Że wtedy nie miałem takich kursów.

  4. Na pewno dobrą praktyką jest stosowanie jednoliniowców gdzie to tylko możliwe. Dużo ładniej wygląda
    execute if executable?
    niż
    if executable?
    execute
    end

  5. Jest taka zasada, że dobra funkcja ma maksymalnie 30 linijek, ale to luźna wskazówka. Oczywiście niektóre funkcje będą dłuższe, bo mają taki charakter, a inne znacznie krótsze. Ale gdy nam funkcja dochodzi 40-50 linijek, warto się zastanowić, czy jest dobrze. 🙂
    Inna sprawa, że czasem większa ilość wierszy daje efektywniejszy kod od mniejszej.
    Jak trochę poprogramujecie, nauczycie się sami dostrzegać, co warto robić, a czego nie.

  6. Jeżeli coś można zrobić mniejszą ilością czynności, to jest to oszczędność energii i do tego warto dążyć i w programowaniu i w życiu, wiadomo.
    Ale jeśli mniejsza ilość linijek miałaby znaczyć, że upychamy po kilka instrukcji w jednej linii, tracąc przez to czytelność, to nie, tak nie robimy.

  7. No to faktycznie, religijna interpretacja się okazuje prawidłowa, bo pierwszy dzień to niedziela, a że pierwszy element tablicy ma indeks 0, to wszystko się zgadza.

  8. Z czego wynika to 0 dla niedzieli? niemogłoby być 7 po prostu.
    To wo góle jest taka rzecz do przyzwyczajenia, bo często w programowaniu pewne rzeczy liczone są od zera chyba właśnie.

    Cytat:
    Jest tylko jeden problem – wartość wday nie jest kompatybilna z parametrem przyjmowanym przez naszą funkcję dayName, gdyż wday zwraca wartość 0 dla niedzieli.

    MK: IMHO Mylące trochę. Aż sprawdziłem numerację, bo spotkałem się z przeświadczeniem, zapewne wziętym z religii judeochrześcijańskich, jakoby pierwszy dzień tak również po świecku to była niedziela i od niedzieli zaczyna się liczenie dni tygodnia.

  9. To nie może wyrzucać błędu z kilku przyczyn, ale najważniejsza jest taka, że… no… program robi dokładnie to, co mu kazałeś. Nie rolą interpretera jest zastanawianie się, czy to logiczne. 🙂
    przypisanie w instrukcji warunkowej w tym kontekście jest błędem, ale często jest wykonywane świadomie. To jedna z dość użytecznych sztuczek, choć na pewno nie w przytaczanej sytuacji.

  10. a i z ciekawości ktoś od zera totalnego też się uczy?
    Zbierzemy tak z kilkanaście osób, to i zrobimy potem wnioski ile osób się zniechęciło po drodze, byle nie wszyscy 😛

  11. Tak do skracania kodu zrozumiałem, jutro przysiądę dalej 😛
    W każdym razie dobrze się to czyta i testuje w konsoli eltenowej.
    Hm, zastanawiam się tylko nad jednym:
    x=2
    if x = 1
    alert("x jest jeden")
    else
    alert("x nie jeden.")
    end
    Czy nie mogło by to być bardziej inteligentne i wyrzucać błąd jeśli po if jest jedno = anie 2?
    Łatwo taki błąd zrobić. Takie moje narzekania przed snem.
    Jak uda mi się naprawić chociaż 1 błąd z tym poradnikiem, to znaczy, że pół eltena by dała radę na pewno.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *