• Nie Znaleziono Wyników

Języki skryptowe ­ Python

N/A
N/A
Protected

Academic year: 2022

Share "Języki skryptowe ­ Python"

Copied!
35
0
0

Pełen tekst

(1)

Języki skryptowe ­ Python

Wykład 2 ­ Pierwsze kroki

Janusz Szwabiński

Plan wykładu:

Uruchamianie programów Typowanie dynamiczne Interpreter i kompilacja Narzędzia

Python w pigułce Kilka słów o składni

Uruchamianie programów

Poniżej znajduje się prosty program (skrypt) napisany w Pythonie:

In [1]:

# symbolem "#" oznaczamy komentarz (wiersz ignorowany przez interpreter Pythona)

# Lista instrumentów muzycznych

instruments = ['Saksofon', 'Perkusja', 'Gitara']

# dla każdej nazwy na liście for item in instruments:

# wypisz tę nazwę na ekranie print(item)

W powyższym przykładzie instruments to nazwa zmiennej, której przypisano listę nazw instrumentów.

Słowo kluczowe for oznacza pętlę po elementach listy ­ w każdym powtórzeniu zmiennej instrument przypisana jest inna nazwa z tej listy.

Saksofon Perkusja Gitara

(2)

Tryb skryptowy

Przedstawiony kod został uruchomiony bezpośrednio w notatniku IPythona, który wykorzystuję do prezentacji w ramach wykładu. Inna możliwość to zapisanie programu do pliku tekstowego z rozszerzeniem .py i

uruchomienie go bezpośrednio z wiersza poleceń:

W systemach z rodziny Windows rozszerzenia plików .py, . pyw, . pyc i . pyo są przypisane automatycznie do interpretera Pythona podczas instalacji. Dlatego klikając w ikonę pliku, również go uruchomimy (pliki .pyw uruchamiane są z alternatywną wersją interpretera, który nie otwiera okna konsoli).

Tryb interaktywny

Interpretera Pythona możemy używać w trybie interaktywnym. Interpreter zachęca wtedy do podania kolejnej instrukcji za pomocą znaku zachęty, zwykle w postaci >>>. Znak zmienia się na ..., gdy interpreter wymaga od nas kontynuacji instrukcji w następnej linii.

W systemach Windows można ponadto uruchomić interpreter Pythona w trybie interaktywnym korzystając z ikony Python (command line).

Trybu interaktywnego używa się do:

obliczeń matematycznych testowania hipotez

operacji na danych i wizualizacji danych

testowania i modyfikowania wycinków kodu przed wstawieniem ich do wiekszych programów analizowania stanu obiektów w pamięci

i wielu innych

(3)

Wbudowane typy danych (wybrane)

numeryczne

int ­ liczby całkowite

float ­ liczby zmiennopozycyjne (rzeczywiste) complex ­ liczby zespolone

sekwencyjne list ­ listy

tuple ­ krotki (tzn. listy, których nie można zmieniać)

range ­ niezmienne sekwencje liczb, wykorzystywane w pętlach for tekstowe

str ­ ciągi znaków Unicode zbiory

set ­ nieuporządkowane kolekcje elementów

frozenset ­ j.w., ale nie można zmieniać ich zawartości mapowania

dict

In [2]:

importsys

In [3]:

sys.float_info

In [4]:

sys.int_info

In [6]:

sys.maxsize

In [7]:

sys.maxsize +10 Out[3]:

sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_ex p=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, round s=1)

Out[4]:

sys.int_info(bits_per_digit=30, sizeof_digit=4)

Out[6]:

9223372036854775807

Out[7]:

9223372036854775817

(4)

Typowanie dynamiczne

Jedną z ważnych cech Pythona jest typowanie dynamiczne

(https://pl.wikipedia.org/wiki/Typowanie_dynamiczne), które polega na tym, że typy przypisywane są do wartości przechowywanych w zmiennych dopiero w trakcie działania programu. Interpreter ustala typy na podstawie samych wartości oraz metod udostępnionych przez obiekt. W języku angielskim takie typowanie określa się czasami jako Duck Typing. Nazwa wywodzi się z tzw. testu kaczki, który przypisywany jest J. W.

Rileyowi (źródło: Wikipedia (https://en.wikipedia.org/wiki/Duck_typing)):

When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.

Warto wspomnieć również o tym, że typowanie w Pythonie jest silne

(https://pl.wikipedia.org/wiki/Typowanie_silne), tzn. interpreter wykonuje automatyczną konwersję jedynie między typami, które są silnie ze sobą powiązane (np. int i long int). Wszelkie operacje między

niekompatybilnymi typami mogą się odbyć jedynie po jawnej konwersji zmiennej lub zmiennych do jednego typu.

In [9]:

1+3

In [10]:

1+3.0

In [11]:

"Hello"+" world"

In [12]:

"Hello"*3 Out[9]:

4

Out[10]:

4.0

Out[11]:

'Hello world'

Out[12]:

'HelloHelloHello'

(5)

In [13]:

"Hello"+3

Dla porównania zobaczmy, jak ten ostatni przykład będzie wyglądał w JavaScripcie:

O takim języku mówimy, że jest słabo typowany.

--- ---

TypeError Traceback (most recent ca ll last)

<ipython-input-13-888f0e761d75> in <module>() ----> 1"Hello"+3

TypeError: Can't convert 'int' object to str implicitly

(6)

Interpreter i kompilacja

Kod źródłowy jest parsowany i tłumaczony do kodu bajtowego (ang. bytecode) Pythona, czyli ciągu instrukcji do wykonania zapisanych w formacie binarnym. Kod bajtowy można przenosić między różnymi systemami operacyjnymi i uruchamiać bez wyjściowego pliku źródłowego.

Kod bajtowy jest domyślnie zapisywany na dysku. Dlatego przy następnym uruchomieniu programu nie ma konieczności ponownego parsowania skryptu i kompilowania go. W ten sposób skrócony zostaje czas uruchomienia programu.

Kod bajtowy przechowywany jest w plikach .pyc (wersja normalna) lub .pyo (wersja zoptymalizowana).

Wersja zoptymalizowana wymaga uruchomienia interpretera z flagą -O.

(7)
(8)

Narzędzia

Istnieje bardzo dużo narzędzi, które ułatwiają programowanie w Pythonie. Można wśród nich znaleźć programy zastępujące powłokę, edytory wspierające składnię czy też zintegrowane środowiska programistyczne (ang. Integrated Development Environments, IDEs).

Zamiast powłoki

Do pracy interaktywnej, zamiast oryginalnej powłoki Pythona, możemy użyć programów PyCrust (w nowszej wersji Py (http://www.wxpython.org/py.php)) lub IPython (http://ipython.org/) .

PyCrust to graficzna powłoka, która między innymi oferuje uzupełnianie składni, podgląd przestrzeni nazw i historię poleceń. Po włączeniu programu do projektu WxPython w najnowszych dystrybucjach można go znaleźć pod nazwą Py.

IPython ma możliwości podobne do PyCrust, jednak może pracować w trybie tekstowym. Powłoka oferuje m.in. kolorowanie składni, uzupełnianie składni, historię. Do wersji 3.0 IPython oferował również uruchamiane w przeglądarce WWW notatniki, które pozwalały na mieszanie wykonywalnego kodu źródłowego z tekstem o dość zaawansowanym formatowaniu. Od wersji 4.0 IPython to głównie powłoka interaktywna Pythona, a cała funkcjonalność związana z notatnikami została przeniesiona do projektu Jupyter (https://jupyter.org/).

(9)

Edytory tekstowe

Decydując się na pracę z Pythonem w trybie "skryptowym", potrzebujemy w zasadzie tylko edytora

tekstowego. Dobrze, gdyby wspierał on składnię Pythona. W systemach linuksowych możemy korzystać z praktycznie każdego edytora w trybie tekstowym (np. vi, emacs, nano) lub graficznym (gedit, kate,  geany).

(10)
(11)

Ostatni ze przedstawionych powyżej edytorów, Geany, dostępny jest również w wersjach dla Windows i Mac OS. Innym edytorem dostępnym pod Linuksem i na Windows jest SciTE (http://www.scintilla.org/SciTE.html).

Bardzo dobrym edytorem dla programistów pod Windowsem jest Notepad++ (http://notepad­

plus.sourceforge.net/br/site.htm). Jeśli spodoba się nam ten edytor, a pod innymi systemami chcielibyśmy mieć podobny, można pomyśleć o zainstalowaniu Notepadqq (http://notepadqq.altervista.org/wp/).

IDE

Zintegrowane środowiska programistyczne (ang. Integrated Development Environment) to pakiety oprogramowania oferujące wiele narzędzi przydatnych programiście ­ od edytorów z kolorowaniem i uzupełnianiem składni, poprzez przeglądarki kodów źródłowych, zintegrowaną powłokę po debugger (lub przynajmniej nakładkę graficzną na niego). Poniżej znajdują się wybrane IDEs dla Pythona:

Idle (https://docs.python.org/2/library/idle.html) PyScripter (http://code.google.com/p/pyscripter/)

SPE (http://pythonide.blogspot.com/) (Stani's Python Editor) Eric (http://eric­ide.python­projects.org/)

PyDev (http://pydev.org/) (plug­in do Eclipse)

(12)
(13)

Budowanie pakietów binarnych

Jeżeli myślimy o dystrybucji programów napisanych w Pythonie, warte uwagi mogą okazać się programy służące do budowania pakietów binarnych, złożonych z kodu bajtowego, interpretera i wszystkich

potrzebnych zależności. Stworzenie takiego pakietu umożliwia uruchomienie naszego programu na komputerze bez zainstalowanego Pythona. Dodatkowo (do pewnego stopnia) chroni kod źródłowy.

Wśród tego typu aplikacji mamy do wyboru m.in.:

py2exe (tylko dla Windows) cx_Freeze (przenośne)

Platformy programistyczne (ang. frameworks)

Platformy programistyczne to szkielety do budowy aplikacji. Definiują strukturę aplikacji oraz ogólny

mechanizm jej działania, a także dostarczają zestawy komponentów i bibliotek ogólnego przeznaczenia do wykonywania określonych zadań.

Najbardziej znane platformy dla Pythona:

aplikacje webowe: Django, TurboGears, Zope i web2py GUI: wxPython, PyGTK i PyQt

obliczenia naukowe: NumPy i SciPy przetwarzanie obrazów: PIL

wizualizacje 2D: Matplotlib i SVGFig

wizualizacje 3D: Visual Python, PyOpenGL i Python Ogre mapowanie obiektowo­relacyjne: SQLAlchemy i SQLObject

(14)

Python w pigułce

Liczby całkowite

Zacznijmy od prostych działań na liczbach całkowitych:

In [14]:

2+2

In [15]:

(50-5*6)/4#w pythonie 2.7 wynik byłby całkowity!!!

In [16]:

(50-5*6)//4

In [17]:

7/3# w pythonie 2.7 wynik będzie 2

In [18]:

-7/3

In [19]:

7//3 Out[14]:

4

Out[15]:

5.0

Out[16]:

5

Out[17]:

2.3333333333333335

Out[18]:

-2.3333333333333335

Out[19]:

2

(15)

In [21]:

szer =10 wys =30.0

pole = szer * wys print(pole)

In [22]:

type(szer)

In [23]:

type(wys)

In [24]:

a = b = c =0 print(a, b, c)

In [25]:

a, b, c =1, 2, 3# pythonowy idiom print (a,b,c)

In [26]:

9**2

In [27]:

_/3# _ to ostatni wynik

Funkcje użytkownika

Możliwości Pythona możemy rozszerzać, definiując własne funkcje:

300.0

Out[22]:

int

Out[23]:

float

0 0 0

1 2 3

Out[26]:

81

Out[27]:

27.0

(16)

In [28]:

defsilnia(x):

if x<=1: return1

return x*silnia(x-1)

In [29]:

silnia(4)

In [30]:

silnia(17)

In [31]:

silnia(100)

I jeszcze raz, informacja systemowa dotycząca typu całkowitego:

In [39]:

sys.maxsize

W przeciwieństwie do Pythona 2.7, w wersji 3.5 nie mamy największej liczby w typie int. Jest ona w praktyce ograniczona jedynie możliwościami komputera. Powyższa liczba stanowi maksymalny rozmiar sekwencji i odpowiada największej możliwej do przedstawienia liczbie naturalnej w typie int w Pythonie 2.7.

Liczby zmiennoprzecinkowe

In [32]:

7/3 Out[29]:

24

Out[30]:

355687428096000

Out[31]:

9332621544394415268169923885626670049071596826438162146859296389521 7599993229915608941463976156518286253697920827223758251185210916864 000000000000000000000000

Out[39]:

9223372036854775807

Out[32]:

2.3333333333333335

(17)

In [33]:

7.0/3

In [34]:

float(7)

In [35]:

x =1.1*10**308

In [36]:

2*x

In [37]:

y =2*x

In [38]:

1/y

Kilka informacji systemowych o liczbach zmiennoprzecinkowych:

In [37]:

importsys sys.float_info

Liczby zespolone Out[33]:

2.3333333333333335

Out[34]:

7.0

Out[36]:

inf

Out[38]:

0.0

Out[37]:

sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_ex p=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, round s=1)

(18)

In [40]:

1j *1J

In [41]:

complex(1,2)

In [42]:

complex(1,2)*complex(2,1)

In [43]:

(1+2j)*(2+j) #nie do końca jak na papierze

In [44]:

(1+2j)*(2+1j)

In [45]:

a =1.5+0.5j

In [46]:

a.real Out[40]:

(-1+0j)

Out[41]:

(1+2j)

Out[42]:

5j

--- ---

NameError Traceback (most recent ca ll last)

<ipython-input-43-ce6b82197b42> in <module>() ----> 1(1+2j)*(2+j)#nie do końca jak na papierze NameError: name 'j' is not defined

Out[44]:

5j

Out[46]:

1.5

(19)

In [47]:

a.imag

In [48]:

float(a)

In [49]:

abs(a) #sqrt(a.real**2 + a.imag**2)

Wbudowana pomoc Out[47]:

0.5

--- ---

TypeError Traceback (most recent ca ll last)

<ipython-input-48-93d25633ffc4> in <module>() ----> 1float(a)

TypeError: can't convert complex to float

Out[49]:

1.5811388300841898

(20)

In [50]:

help(a)

(21)
(22)

Help on complex object:

class complex(object)

| complex(real[, imag]) -> complex number |

| Create a complex number from a real part and an optional imagin ary part.

| This is equivalent to (real + imag*1j) where imag defaults to 0.

|

| Methods defined here:

|

| __abs__(self, /) | abs(self) |

| __add__(self, value, /) | Return self+value.

|

| __bool__(self, /) | self != 0 |

| __divmod__(self, value, /) | Return divmod(self, value).

|

| __eq__(self, value, /) | Return self==value.

|

| __float__(self, /) | float(self) |

| __floordiv__(self, value, /) | Return self//value.

|

| __format__(...)

| complex.__format__() -> str |

| Convert to a string according to format_spec.

|

| __ge__(self, value, /) | Return self>=value.

|

| __getattribute__(self, name, /) | Return getattr(self, name).

|

| __getnewargs__(...) |

| __gt__(self, value, /) | Return self>value.

|

| __hash__(self, /) | Return hash(self).

|

| __int__(self, /) | int(self) |

| __le__(self, value, /) | Return self<=value.

|

| __lt__(self, value, /) | Return self<value.

|

(23)

| __mod__(self, value, /) | Return self%value.

|

| __mul__(self, value, /) | Return self*value.

|

| __ne__(self, value, /) | Return self!=value.

|

| __neg__(self, /) | -self

|

| __new__(*args, **kwargs) from builtins.type

| Create and return a new object. See help(type) for accurat e signature.

|

| __pos__(self, /) | +self

|

| __pow__(self, value, mod=None, /) | Return pow(self, value, mod).

|

| __radd__(self, value, /) | Return value+self.

|

| __rdivmod__(self, value, /) | Return divmod(value, self).

|

| __repr__(self, /) | Return repr(self).

|

| __rfloordiv__(self, value, /) | Return value//self.

|

| __rmod__(self, value, /) | Return value%self.

|

| __rmul__(self, value, /) | Return value*self.

|

| __rpow__(self, value, mod=None, /) | Return pow(value, self, mod).

|

| __rsub__(self, value, /) | Return value-self.

|

| __rtruediv__(self, value, /) | Return value/self.

|

| __str__(self, /) | Return str(self).

|

| __sub__(self, value, /) | Return self-value.

|

| __truediv__(self, value, /) | Return self/value.

|

| conjugate(...)

| complex.conjugate() -> complex |

(24)

Biblioteka standardowa

In [51]:

importmath#importujemy moduł matematyczny z biblioteki standardowej | Return the complex conjugate of its argument. (3-4j).conjug ate() == 3+4j.

|

| --- ---

| Data descriptors defined here:

| | imag

| the imaginary part of a complex number |

| real

| the real part of a complex number

(25)

In [52]:

dir(math) #zawartość modułu

(26)

Out[52]:

['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e',

'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

(27)

In [53]:

help(math.ceil)

In [54]:

math.pi

In [55]:

math.cos(math.pi/2) #powinno być zero

Help on built-in function ceil in module math:

ceil(...) ceil(x)

Return the ceiling of x as an int.

This is the smallest integral value >= x.

Out[54]:

3.141592653589793

Out[55]:

6.123233995736766e-17

(28)

In [56]:

math.e

In [57]:

math.log(math.e) #logarytm naturalny

In [58]:

math.sqrt(8)

In [59]:

math.sqrt(-8)

In [60]:

importcmath cmath.sqrt(-8) Out[56]:

2.718281828459045

Out[57]:

1.0

Out[58]:

2.8284271247461903

--- ---

ValueError Traceback (most recent ca ll last)

<ipython-input-59-d928edca9d4e> in <module>() ----> 1math.sqrt(-8)

ValueError: math domain error

Out[60]:

2.8284271247461903j

(29)

In [61]:

dir(cmath)

Listy

In [4]:

numbers = [1, 2, 3, 4, 5] Out[61]:

['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cos', 'cosh', 'e', 'exp', 'isfinite', 'isinf', 'isnan', 'log', 'log10', 'phase', 'pi', 'polar', 'rect', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']

(30)

In [5]:

numbers[3]

In [6]:

numbers[1:3]

In [7]:

numbers.append(6)

In [8]:

numbers

In [9]:

squares = [i**2for i in numbers]

In [10]:

squares

Pętle

In [11]:

for i in numbers:

print(i,i**2)

Wyrażenia warunkowe Out[5]:

4

Out[6]:

[2, 3]

Out[8]:

[1, 2, 3, 4, 5, 6]

Out[10]:

[1, 4, 9, 16, 25, 36]

1 1 2 4 3 9 4 16 5 25 6 36

(31)

In [12]:

for i in numbers:

if(i%2==0):

print(i)

Zbiory

In [13]:

z1 =set('banan') z2 =set('ananas')

In [14]:

print(z1,z2)

In [16]:

z1 | z2

In [17]:

z1 - z2

In [18]:

z1 & z2

In [19]:

z1 ^ z2

Łańcuchy znaków 2

4 6

{'b', 'a', 'n'} {'s', 'a', 'n'}

Out[16]:

{'a', 'b', 'n', 's'}

Out[17]:

{'b'}

Out[18]:

{'a', 'n'}

Out[19]:

{'b', 's'}

(32)

In [20]:

tekst ="To jest przykład zdania w języku polskim."

In [21]:

tekst.split()

In [22]:

slowa = tekst.split()

In [23]:

'&'.join(slowa)

Operacje na plikach

In [24]:

f =open('mojplik.txt','w')

In [25]:

f.write('Pierwszy wiersz.\n')

In [26]:

f.write('Drugi wiersz.')

In [27]:

f.close()

In [28]:

f =open('mojplik.txt','r') for line in f:

print(line) f.close() Out[21]:

['To', 'jest', 'przykład', 'zdania', 'w', 'języku', 'polskim.']

Out[23]:

'To&jest&przykład&zdania&w&języku&polskim.'

Out[25]:

17

Out[26]:

13

Pierwszy wiersz.

Drugi wiersz.

(33)

Formatowanie wyjścia

In [29]:

template ='{0}{1}{0}'

In [30]:

template.format('abra','cad')

In [31]:

coord = (3,5)

'X: {0[0]}; Y: {0[1]}'.format(coord)

Kilka słów o składni

Program (skrypt) w Pythonie składa się z wierszy, które zawierają sekwencje elementów języka. Ze wzgledu na czytelność kodu źródłowego najczęściej umieszcza się jedno wyrażenie w jednym wierszu. Czasami jednak zdarzają się sytuacje, kiedy lepiej takie wyrażenie rozciągnąć na wiele linii kodu. W tym celu używamy:

ukośnika wstecznego \ (ang. backslash), jeżeli wyrażenie nie zawiera nawiasów lub dzielimy je pomiędzy nimi

nawiasów, jeżeli wyrażenie ich wymaga

In [63]:

a =7*3+ \ 5/2

print(a)

In [65]:

b = [1,2,3, 4,5,6] print(b) Out[30]:

'abracadabra'

Out[31]:

'X: 3; Y: 5'

23.5

[1, 2, 3, 4, 5, 6]

(34)

In [66]:

c =range(1, 11) print(c)

Znak # oznacza początek komentarza. Tekst pojawiający się po tym znaku aż do końca linii będzie ignorowany. Wyjątek stanowią komentarze funkcjonalne:

informacja o kodowaniu znaków w kodzie źródłowym, np.:

# -*- coding: utf-8 -*-

informacja o programie interpretującym kod, np.:

#!/usr/bin/env python

Bardzo ważnym elementem Pythona są wcięcia w kodzie ­ nie tylko zwiększają czytelność całego programu, ale definiują zawartość bloków kodu.

range(1, 11)

(35)

In [67]:

#pętla po liczbach od 1 do 99 for i inrange(1,100):

#jeśli reszta z dzielenia równa 0:

if i%3 ==0:

#wyświetl na ekranie print(i, '/3 =', i/3)

Dla danego bloku głębokość wcięcia musi być stała. Jednak do dobrych praktyk należy używanie zawsze tej samej głębokości wcięcia. Należy również unikać naprzemiennego używania tabulatorów i spacji do wcięć, ponieważ to rodzi problemy przy przenoszeniu kodu między różnymi systemami operacyjnymi. Najlepiej jest używać edytorów, które zamieniają tabulatory na określoną liczbę spacji w "locie".

3 /3 = 1.0 6 /3 = 2.0 9 /3 = 3.0 12 /3 = 4.0 15 /3 = 5.0 18 /3 = 6.0 21 /3 = 7.0 24 /3 = 8.0 27 /3 = 9.0 30 /3 = 10.0 33 /3 = 11.0 36 /3 = 12.0 39 /3 = 13.0 42 /3 = 14.0 45 /3 = 15.0 48 /3 = 16.0 51 /3 = 17.0 54 /3 = 18.0 57 /3 = 19.0 60 /3 = 20.0 63 /3 = 21.0 66 /3 = 22.0 69 /3 = 23.0 72 /3 = 24.0 75 /3 = 25.0 78 /3 = 26.0 81 /3 = 27.0 84 /3 = 28.0 87 /3 = 29.0 90 /3 = 30.0 93 /3 = 31.0 96 /3 = 32.0 99 /3 = 33.0

Cytaty

Powiązane dokumenty

Spójrz

BEHAVIOR=SCROLL powoduje, że tekst porusza się od jednego brzegu strony w kierunku drugiego, znika za nim i wypływa ponownie zza pierwszego brzegu. BEHAVIOR=SLIDE powoduje, że

Jednak dopiero w 2002 roku udało się zidentyfikować receptory smakowe odpowiedzialne za jego odczuwanie i umami oficjalnie dołączył do grona smaków podstawowych.. Z

W tym kontekście ciężar oceny tego co jest możliwe z medycznego punktu widzenia i co jest sensowne, szczególnie w przypadkach kontrowersyjnych czy spornych, jest w pewnym.

[r]

[r]

[r]

Prawo wykonywania pliku pozwala na uruchomienie pliku wykonalnego, a w przypadku katalogu oznacza prawo dostępu do plików wewnątrz katalogu.. Minimalne prawa wymagane do