Od zera do mistrza Big Data i uczenia maszynowego w Pythonie. Część 5. Funkcje

    No Comments

    Dotarliśmy do tego fragmentu kursu, gdzie znamy podstawowe typy zmiennych prostych i sekwencyjnych. Umiemy robić jawne konwersje, rozumiemy zmienne logiczne, potrafimy wykorzystywać warunki logiczne i sterować programem wykorzystując pętle.

    Przyszedł czas by pochylić się nad jednym z ważniejszych elementów , czyli podprogramami zwanymi funkcjami.

    Funkcja to fragment kodu , który może być wielokrotnie wykorzystywany w różnych miejscach naszego programu.

    W języku Python składnia definicji funkcji jest następująca:

    Skupimy się nad:

    • parametrami formalnymi
      zmiennymi aktualnymi
      zmiennymi lokalnymi
      zmiennymi globalnymi.

    Ważne będzie zrozumienie działania przestrzeni nazw, słów kluczowych global, nonlocal.

    Funkcje mogą mieć nieznaną liczbę argumentów. Mogą być budowane rekurencyjnie. Poznamy sposoby przekazywania argumentów  i sprawdzanie ich poprawności.Nauczymy się korzystać z wartości domyślnych i parametrów specjalnych.
    Poznamy również wyrażenia lambda, które pozwalają nam na tworzenie mini-funkcji.

    Dobrą praktyką jest umieszczanie na początku funkcji jej dokumentacji. Ten docstring powinien zawierać listę argumentów i znaczenie i opis działania.

    Kod notatnika Jupiter został jak zwykle umieszczony na Githubie

    Podgląd:

    https://nbviewer.jupyter.org/github/djkormo/PythonForML/blob/master/intro/Kurs_4_funkcje.ipynb

    Uruchomienie:

    https://mybinder.org/v2/gh/djkormo/PythonForML/master?filepath=intro/Kurs_4_funkcje.ipynb

    Po uruchomieniu kontenera należy wyczyścić informacje wyjściowe za pomocą menu Kernel -> Restart & Clear Output.

    Reenredowane wtyczką WP:

    Funcje

    def nazwa( parametry ):

    '''dokumentacja''' #opcjonalne

    logika

    return [wyrażenie] # opcjonalne

    In [1]:
    # nasza pierwsza funkcja.
    # Wyswietlnie wartości parametru. 
    # Funkcja nie zwraca jawnej wartości
    
    def drukuj(napis):
        print(napis)
        
    # wykonanie funkcji
    
    drukuj('Litwo, Ojczyzno moja')    
    
    Litwo, Ojczyzno moja
    
    In [2]:
    #Jeśli nie zwracamy wartości, to niejawnie zwracana jest wartość None.
    
    print("Nie zwracam wartosci") is None
    
    Nie zwracam wartosci
    
    Out[2]:
    True
    In [3]:
    # Wywolanie instrukcji help w przypadku, gdy nasza funkcja nie  zostałą opisana w docstring
    
    help(drukuj)
    
    Help on function drukuj in module __main__:
    
    drukuj(napis)
    
    
    In [4]:
    # dodajemy dokumentację do funkcji
    
    def drukuj(napis):
        '''Funkcja print drukuje podany w parametrze napis'''
        print(napis)
        
    
    In [5]:
    # Wywolanie instrukcji help w przypadku, gdy nasza funkcja   została opisana w docstring
    
    help(drukuj)
    
    Help on function drukuj in module __main__:
    
    drukuj(napis)
        Funkcja print drukuje podany w parametrze napis
    
    
    In [6]:
    # pusta funkcja
    
    def nicnierobie():
       pass # pusta instrukcja, to nie jest komentarz
    
    # wywołanie 
    nicnierobie()
    
    
    # w wersji z dokumentacją
    
    def nicnierobie():
       '''Funkcja leniwa. Nic nie robię i dobrze mi z tym.''' 
       pass
    
    #wywołanie 
    nicnierobie()
    # pomoc 
    help(nicnierobie)
    # typu None
    help(nicnierobie) is None
    
    Help on function nicnierobie in module __main__:
    
    nicnierobie()
        Funkcja leniwa. Nic nie robię i dobrze mi z tym.
    
    Help on function nicnierobie in module __main__:
    
    nicnierobie()
        Funkcja leniwa. Nic nie robię i dobrze mi z tym.
    
    
    Out[6]:
    True
    In [7]:
    # funkcja z parametrem zwrotnym
    
    def sklejnapisy(napis1,napis2):
        '''Funkcja skleja dwa napisy podane w parametrach funkcji'''
        napis3=napis1+napis2 # zmienna lokalna
        return napis3 # slowo k
    
    # pomoc systemowa 
    
    help(sklejnapisy)
    
    # wynik działania funkcji
    
    print(sklejnapisy('Nad rzęczką ','opodal krzaczka.'))
    
    # inny sposob wywołania tej funcji
    
    print(sklejnapisy(napis1='Nad rzęczką ',napis2='opodal krzaczka.'))
    
    Help on function sklejnapisy in module __main__:
    
    sklejnapisy(napis1, napis2)
        Funkcja skleja dwa napisy podane w parametrach funkcji
    
    Nad rzęczką opodal krzaczka.
    Nad rzęczką opodal krzaczka.
    
    In [8]:
    # jeżeli potrzebujemy wyswietlenia wielu wartości output z jednej komorki
    from IPython.core.interactiveshell import InteractiveShell
    InteractiveShell.ast_node_interactivity = "all"
    
    In [9]:
    # Wywolanie argumentów danej funkcji  może być zarówno bez podowania nazwy argumentu, lub w postaci nazwa=wartosc
    
    # Dla powyższej funcji mamy różne sposoby  wywołania
    
    # tylko wartosci argumentow
    
    sklejnapisy('Nad rzęczką ','opodal krzaczka.')
    
    # pierwszy argument przez wartosc, drugi przez postać nazwa=wartosc
    
    sklejnapisy('Nad rzęczką ',napis2='opodal krzaczka.')
    
    # pierwszy argument przez nazwa=wartosc, drugi przez postać nazwa=wartosc
    
    sklejnapisy(napis1='Nad rzęczką ',napis2='opodal krzaczka.')
    
    # pierwszy argument przez nazwa=wartosc, drugi przez postać nazwa=wartosc, ale z przestawieniem kolejnosci
    
    sklejnapisy(napis2='opodal krzaczka.',napis1='Nad rzęczką ')
    
    Out[9]:
    'Nad rzęczką opodal krzaczka.'
    Out[9]:
    'Nad rzęczką opodal krzaczka.'
    Out[9]:
    'Nad rzęczką opodal krzaczka.'
    Out[9]:
    'Nad rzęczką opodal krzaczka.'
    In [11]:
    # parametry funkcji mogą mieć zdefiniowaną wartość domyślną
    
    def sklejnapisy3(napis1,napis2,napis3='...'):
        '''Funkcja skleja trzy napisy podane w parametrach funkcji'''
        napis4=napis1+napis2+napis3 # zmienna lokalna
        return napis4
    
    # jeśli nie podamy wartości trzeciego parametru
    
    print(sklejnapisy3('Nad rzeczką ','opodal krzaczka'))
    
    print(sklejnapisy3(napis1='Nad rzeczką ',napis2='opodal krzaczka'))
    
    # z podaniem tej wartości 
    
    print(sklejnapisy3('Nad rzeczką ','opodal krzaczka','!!!'))
    
    print(sklejnapisy3(napis1='Nad rzeczką ',napis2='opodal krzaczka',napis3='!!!'))
    
    Nad rzeczką opodal krzaczka...
    Nad rzeczką opodal krzaczka...
    Nad rzeczką opodal krzaczka!!!
    Nad rzeczką opodal krzaczka!!!
    
    In [12]:
    # jesli nie podamy patametru, ktory nie ma wartosci domyslnej ?
    print(sklejnapisy3(napis1='Nad rzeczką ',napis3='!!!')) # TypeError: sklejnapisy() missing 1 required positional argument: 'napis2'
    
    # Bedzie zwrócony błąd  TypeError: sklejnapisy3() missing 1 required positional argument: 'napis2'
    
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-12-72ebcfe66dac> in <module>()
          1 # jesli nie podamy patametru, ktory nie ma wartosci domyslnej ?
    ----> 2 print(sklejnapisy3(napis1='Nad rzeczką ',napis3='!!!')) # TypeError: sklejnapisy() missing 1 required positional argument: 'napis2'
          3 
          4 # Bedzie zwrócony błąd  TypeError: sklejnapisy3() missing 1 required positional argument: 'napis2'
    
    TypeError: sklejnapisy3() missing 1 required positional argument: 'napis2'
    In [13]:
    # metadane funkcji
    
    # https://docs.python.org/3/reference/datamodel.html
    
    print ('Nazwa: ',sklejnapisy3.__name__)           # nazwa funkcji
    print ('Opis: ',sklejnapisy3.__doc__ )           # dokumentacja (docstring)
    print ('Wartosci domyslne:',sklejnapisy3.__defaults__ )  # wartości domyślne 
    
    Nazwa:  sklejnapisy3
    Opis:  Funkcja skleja trzy napisy podane w parametrach funkcji
    Wartosci domyslne: ('...',)
    
    In [14]:
    # zen of Python
    import this
    
    The Zen of Python, by Tim Peters
    
    Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases aren't special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    Now is better than never.
    Although never is often better than *right* now.
    If the implementation is hard to explain, it's a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea -- let's do more of those!
    

    Klika słów o zasięgu zmienych

    In [15]:
    #http://www.diveintopython.net/html_processing/locals_and_globals.html
    
    # Zmienne utworzone wewnątrz funkcji mają lokalny zasięg.
    # Funkcja locals() zwraca słownik par klucz-wartość
    
    def loc(arg):
        x = 1
        print ('Locals() : ',locals())
        
    # x lokalny ma wartość 7 tzpu calkowitego 
    
    # x lokalny ma wartość 'Lokalne jest piekne' typu napis
    loc('Lokalne jest piekne') 
    
    Locals() :  {'arg': 'Lokalne jest piekne', 'x': 1}
    
    In [16]:
     #http://www.diveintopython.net/html_processing/locals_and_globals.html
        
    def lokalny(arg):
         x = 1
         # wyswietlamy slownik zmiennych lokalnych
         # zauwazmy, ze pojawia sié klucz o nazwie orgumentu funkcji 
         print (locals() )  
        
         # zmieniamy wartosc slownika o nazwie x   
         locals()["x"] = 2 
         # wyswietlamy slownik zmiennych lokalnych 
         print (locals() ) 
         # wyswietlamy zawartosc zmiennej x
         print ("Zmienna x= ",x)
    
    # nasza zmienna         
    z = 7
    print ("Zmienna z= ",z)
    
    lokalny(3)
    # zmieniany wartosc slownika o nazwie z
    globals()["z"] = 8    
    print ("Zmienna z= ",z)
    
    # To co musimy zapamietac, to informacja o tym, ze locals jest tylko do odczytu 
    # Inaczej jest z odpowiednikiem globals, o czym bedzie pozniej 
    
    Zmienna z=  7
    {'arg': 3, 'x': 1}
    {'arg': 3, 'x': 1}
    Zmienna x=  1
    Zmienna z=  8
    

    Fragment z dokumentacji w Wikipedii

    Kiedy pewna linia kodu pyta się o wartość zmiennej x, Python przeszuka wszystkie przestrzenie nazw, aby ją znaleźć, w poniższym porządku:

    1. lokalna przestrzeń nazw -- określona dla bieżącej funkcji lub metody pewnej klasy. Jeśli funkcja definiuje jakąś lokalną zmienną x, Python wykorzysta ją i zakończy szukanie.
    2. przestrzeni nazw, w której dana funkcja została zagnieżdżona i przestrzeniach nazw, które znajdują się wyżej w "zagnieżdżonej" hierarchii.
    3. globalna przestrzeń nazw -- określona dla bieżącego modułu. Jeśli moduł definiuje zmienną lub klasę o nazwie x, Python wykorzysta ją i zakończy szukanie.
    4. wbudowana przestrzeń nazw -- globalna dla wszystkich modułów. Ponieważ jest to ostatnia deska ratunku, Python przyjmie, że x jest nazwą wbudowanej funkcji lub zmiennej.
    In [17]:
    def funkcja_lokalna():
        x = 1
        
    # Zmienna x jest dostépna tylko wewnátrz funkcji    
    print (x) #NameError: name 'x' is not defined
    
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-17-6ae2f3f26784> in <module>()
          3 
          4 # Zmienna x jest dostépna tylko wewnátrz funkcji
    ----> 5 print (x) #NameError: name 'x' is not defined
    
    NameError: name 'x' is not defined
    In [20]:
    # jesli chcemy skorzystac ze zmiennej utworzonej poza cialem funkcji
    #  Co jesli taka zmienna nie zostala utworzona wczesniej ?
    
    
    def funkcja_globalna_nieutworzona():
        global x
        x = 10
      
    #print ('Zmienna x= ',x)  #NameError: global name 'x' is not defined
    funkcja_globalna_nieutworzona()  
    print ('Zmienna x= ',x)
    
    Zmienna x=  10
    
    In [21]:
    # Wykorzystujemy istniejaca zmienna w funkcji
    def funkcja_globalna_utworzona():
        global x
        x =x+1
    # tworzymy zmienna x     
    x=10    
    print ('Zmienna x= ',x) 
    funkcja_globalna_utworzona()
    print ('Zmienna x= ',x) 
    
    Zmienna x=  10
    Zmienna x=  11
    
    In [22]:
    # jak wygláda struktura locals ?
    def funkcja_globalna_utworzona():
        global x
        x =x+1
        print (locals()) # struktura jest pusta , brakuje zmienny lokalnych
        
    x=10    
    print ('Zmienna x= ',x) 
    funkcja_globalna_utworzona()
    print ('Zmienna x= ',x)    
    
    Zmienna x=  10
    {}
    Zmienna x=  11
    
    In [23]:
    # Do jej pory rozmawialismy o zmiennych lokalnyh i globalnych.
    
    # Jak sobie z tym poradzic, jesli korzystamy z funkcji w funkcji ?
    
    def funkcja_zewnetrzna():
        def funkcja_wewnetrzna():
            nonlocal x
            x = 5
        funkcja_wewnetrzna()
    
    funkcja_zewnetrzna()
    
    # wykonanie powyzszego kodu koñczy sie bledem  no binding for nonlocal 'x' found
    
    # funkcja_wewnetrzna ma zdefiniowana zmienna x jako zmienna nielokalna
    # to oznacza, ze oczekuje istnienia takiej funkcji w przestrzeni nazw , ktorej jest zanurzona
    # czyli w funkcji funkcja_zewnetrzna()
    
      File "<ipython-input-23-66605e0f4d74>", line 7
        nonlocal x
        ^
    SyntaxError: no binding for nonlocal 'x' found
    
    In [24]:
    # W funkcji wewnétrznej difiniujemy zmienna nielokalna x.
    # W funkji wewnétrznej tworzymy zmienna lokalna x
    # Na zewnátrz obu funkcji jest zdefiniowana zmienna x.
    
    def funkcja_zewnetrzna():
        def funkcja_wewnetrzna():
            nonlocal x
            x = 5
            print('funkcja_wewnetrzna()-> Zmienna x= ',x)
        funkcja_wewnetrzna()
        x =10
        print('funkcja_zewnetrzna()-> Zmienna x= ',x)
        
    # zmienna globalna x
    x=-1
    print('Zmienna x= ',x)
    funkcja_zewnetrzna()
    print('Zmienna x= ',x)
    
    Zmienna x=  -1
    funkcja_wewnetrzna()-> Zmienna x=  5
    funkcja_zewnetrzna()-> Zmienna x=  10
    Zmienna x=  -1
    
    In [25]:
    # W ponizszym przypadku zmienna globalna x nie jest zmieniana, gdyæ 
    # w funkcja_zewnetrzna() , gdyz korzysta ze zmiennej lokalnej x
    # w funkcja_wewnetrzna(), gdyz korzysta ze zmiennej nielokalnej x , czyli z lokalnej x funkcja_zewnetrzna()
    
    # Ten przyklad proponuje sobie spokojnie pouklada© w glowie
    
    def funkcja_zewnetrzna():
        def funkcja_wewnetrzna():
            nonlocal x
            x = 1
            print("funkcja_wewnetrzna()-> Zmienna x=", x)  
        x = 3
        print("funkcja_zewnetrzna()-> Zmienna x=", x)
        funkcja_wewnetrzna()
        
        
    print("Globalnie() -> Zmienna x= ", x)    
    x = 2    
    funkcja_zewnetrzna()
    print("Globalnie() -> Zmienna x= ", x)
    
    Globalnie() -> Zmienna x=  -1
    funkcja_zewnetrzna()-> Zmienna x= 3
    funkcja_wewnetrzna()-> Zmienna x= 1
    Globalnie() -> Zmienna x=  2
    
    In [26]:
    # Ten przyklad zostawiam dla chetnych.
    
    # Kiedy zmienna x przyjmuje wartosc 50 ?
    
    def funkcja_zewnetrzna():
        def funkcja_wewnetrzna():
            def funkcja_wewnetrzna2():
                nonlocal x
                x = 100
                print("funkcja_wewnetrzna2()-> Zmienna x=", x)
            x = 50
            funkcja_wewnetrzna2()
            print("funkcja_wewnetrzna()-> Zmienna x=", x)
        x = 10
        funkcja_wewnetrzna()
        print("funkcja_zewnetrzna()-> Zmienna x=", x)
    
    x = 1
    print("Globalnie()-> Zmienna x=", x)
    funkcja_zewnetrzna()
    print("Globalnie()-> Zmienna x=", x)
    
    Globalnie()-> Zmienna x= 1
    funkcja_wewnetrzna2()-> Zmienna x= 100
    funkcja_wewnetrzna()-> Zmienna x= 100
    funkcja_zewnetrzna()-> Zmienna x= 10
    Globalnie()-> Zmienna x= 1
    
    In [27]:
    #### Rekurencja i iteracja na przykladzie ciagu Fibonacciego
    
    def fibo_rekurencja(n):
        '''Funkcja fibo_rekurencja(n) wyznacza wartosc n elementu ciagu Fibonaciego w wersji rekurencyjnej
        '''
        if n<=1:
          return 1
        else:
          return fibo_rekurencja(n-1) + fibo_rekurencja(n-2)
    
    def fibo_iteracja(n):
        '''Funkcja fibo_iteracja(n) wyznacza wartosc n elementu ciagu Fibonaciego w wersji rekurencyjnej
        '''
        x,y=1,0
        for i in range(n):
          x,y=x+y,x
        return x    
    
    
    help(fibo_iteracja)
    print ('Iteracja....')
    for n in range(10):
      print('Fibo_iteracja dla n= ',n,' = ',fibo_iteracja(n)) 
    
    help(fibo_rekurencja)
    print ('Rekurencja....')
    for n in range(10):
      print('Fibo_rekurencja dla n= ',n,' = ',fibo_rekurencja(n)) 
        
    
    Help on function fibo_iteracja in module __main__:
    
    fibo_iteracja(n)
        Funkcja fibo_iteracja(n) wyznacza wartosc n elementu ciagu Fibonaciego w wersji rekurencyjnej
    
    Iteracja....
    Fibo_iteracja dla n=  0  =  1
    Fibo_iteracja dla n=  1  =  1
    Fibo_iteracja dla n=  2  =  2
    Fibo_iteracja dla n=  3  =  3
    Fibo_iteracja dla n=  4  =  5
    Fibo_iteracja dla n=  5  =  8
    Fibo_iteracja dla n=  6  =  13
    Fibo_iteracja dla n=  7  =  21
    Fibo_iteracja dla n=  8  =  34
    Fibo_iteracja dla n=  9  =  55
    Help on function fibo_rekurencja in module __main__:
    
    fibo_rekurencja(n)
        Funkcja fibo_rekurencja(n) wyznacza wartosc n elementu ciagu Fibonaciego w wersji rekurencyjnej
    
    Rekurencja....
    Fibo_rekurencja dla n=  0  =  1
    Fibo_rekurencja dla n=  1  =  1
    Fibo_rekurencja dla n=  2  =  2
    Fibo_rekurencja dla n=  3  =  3
    Fibo_rekurencja dla n=  4  =  5
    Fibo_rekurencja dla n=  5  =  8
    Fibo_rekurencja dla n=  6  =  13
    Fibo_rekurencja dla n=  7  =  21
    Fibo_rekurencja dla n=  8  =  34
    Fibo_rekurencja dla n=  9  =  55
    

    Operator lambda

    In [28]:
    # Wyrazenia Lanbda, czyli funkjce inline lub finkcje atomowe
    # skladania 
    # lambda argumenty: instrukcja_gererujaca_wynik
    
    # funkcja dodawania
    dodawanie = lambda x,y : x+y
    print('1+2 =',dodawanie(1,2))
    
    1+2 = 3
    
    In [29]:
    # Warto poczytac https://www.afternerd.com/blog/python-lambdas/
    
    # kwadrat liczby
    
    kwadrat = lambda x: x * x
    print('3*3 = ',kwadrat(3))
    
    # mnozenie dwoch liczb
    
    mnozenie = lambda x,y: x * y
    print('3*4 = ',mnozenie(3,4))
    
    # zawsze prawda, w wyrazenie bez argumentow na wejsciu
    
    prawda= lambda :True
    print ('Zawsze prawda = ',prawda())
    
    3*3 =  9
    3*4 =  12
    Zawsze prawda =  True
    
    In [30]:
    # operacja list i map
    
    lista_wejsciowa = [1, 2, 3, 4]
    lista_wyjsciowa=list(map(lambda x: x**2, lista_wejsciowa))
    
    print ('lista_wyjsciowa=',lista_wyjsciowa)
    
    lista_wyjsciowa= [1, 4, 9, 16]
    
    In [31]:
    # operator lambda w wersji rekurencyjnej
    
    silnia = lambda x: x * silnia(x-1) if x != 0 else 1
    print('Silnia z 6 =',silnia(6))
    
    Silnia z 6 = 720
    

    Obsluga wyjatkow

    In [32]:
    x = [1,2]
    # probujemy siagnac po nieistniejacy element
    print(x[2]) #IndexError: list index out of range
    
    ---------------------------------------------------------------------------
    IndexError                                Traceback (most recent call last)
    <ipython-input-32-10465f1c6562> in <module>()
          1 x = [1,2]
          2 # probujemy siagnac po nieistniejacy element
    ----> 3 print(x[2]) #IndexError: list index out of range
    
    IndexError: list index out of range
    In [33]:
    try:
      x = [1,2]     
      print(x[2])
    except Exception as e:
        print ('Nie widzimy bledu')
    
    Nie widzimy bledu
    
    In [35]:
    try:
      x = [1,2]     
      print(x[2])
    except Exception as e:
        print ('Cos sie wydarzylo: ',e) #wyswietlamy blad
    
    Cos sie wydarzylo:  list index out of range
    
    In [36]:
    # Mozemy wykorzystac predefiniowane rodzaje wyjatkow
    try:
      x = [1,2]     
      print(x[2])
    except ZeroDivisionError as e0:
        print ('Cos sie wydarzylo: ',e0) #blad nie zostanie wyswietlony
    except Exception as e:
        print ('Cos sie wydarzylo: ',e) #wyswietlamy blad        
    
    Cos sie wydarzylo:  list index out of range
    
    In [37]:
    try:
      1/0
    except ZeroDivisionError as e0:
      print ('Cos sie wydarzylo: ',e0) #blad  zostanie wyswietlony
    except Exception as e:
      print ('Cos sie wydarzylo: ',e) # blad nie zostanie wyswietlamy
    
    Cos sie wydarzylo:  division by zero
    
    Categories: migawka, Python

    Uczenia maszynowe dla ubogich. Od trenowania modelu do dedykowanej usługi. Część 2

    No Comments

    W poprzednim wpisie starałem się pokazać, jak  w prosty sposób uruchomić model uczenia maszynowego do klasyfikacji zdjęć.

    Przygotowanie modelu odbyło się w aplikacji https://www.customvision.ai/

    Do uruchomienia gotowego modelu  w postaci REST API wykorzystałem darmową piaskownicę https://labs.play-with-docker.com/.

    Każda z tych usług ma swoje ograniczenia. Tak pierwsza pozwala na budowę jedynie dwóch modelu w planie darmowym. Tak druga ma czasowe ograniczenie do czterech godzin działania. Na początek to może wystarczyć, ale postanowiłem zająć się drugą częścią, czyli uruchomieniem gotowego modelu uczenia maszynowego w chmurze publicznej Azure. Wykorzystam dwie usługi ACR (Azure Container Registry) i ACI (Azure Container Instances).  Wdrożenie odbędzie się przy wykorzystaniu poleceń cli, albo z poziomu Visual Studio Code, albo z poziomu Azure Cloud Shell. Nie będzie potrzeby instalacji narzędzi typu Docker for Windows.

    Będziemy głównie wykorzystywać linię komend, od czasu do czasu spoglądając w Portal.

    Na początku definiujemy globalne zmienne

    Tworzymy prywatny rejestr ACR w ramach grupy zasobów ACR_GROUP. W tym przypadku nazwałem ją rg-machinelearning. Zasoby zostaną umieszczone w jednej lokalizacji northeurope  ( Dublin w Irlandii). Rejestr zasobów zostanie nazwany djkormoacrml , a utworzona instancja aplikacji djkormoaciml.

     

    Wszelkie zasoby, będą celowo umieszczone w jednej grupie. W ten sposób łatwiej się zarządza kosztami. Dodatkowo dzięki ustawieniu domyślnej nazwy grupy i domyślnej lokalizacji nie musimy przy budowie usług podawać

    Na początku pobieramy z publicznego repozytorium na Githubie kod naszej aplikacji i umieszczamy na dysku lokalnym (lub na dysku Cloud Shella). W tej wersji skryptu wykorzystałem laptop z Windows 7.

    Tak wygląda konfiguracja naszej aplikacji zawarta w pliku Dockerfile. Więcej szczegółów można znaleźć w pierwszej części artykułu.

    Tworzymy nasz rejestr obrazków, na potrzeby tego demo wystarczy najtańsza wersja (Basic). Pozwala ona na umieszczenie zbioru obrazów od łącznej pojemności nie przekraczającej 10GB. To repozytorium otrzymuje wpis w DNS $ACR_NAME.azurecr.io

    Uchomienie nslookup po zdbudowaniu rejestru…

    Rozpoczynamy budowę naszego rejestru, zanim umieścimy w nim jakikolwiek obraz.

    Uruchamiamy proces budowy naszego obrazu, potrwa to do około dwóch minut. Świeżo przygotowany obraz zostanie umieszczony w prywatnym repozytorium ACR.. Jako nazwę obrazu przyjąłem ai-customvision , a po : umieszczam numer wersji, w tym przypadku v1. Zawartość pliku Dockerfile  zawiera przepis z jakich komponentów i w jakiej kolejności  będzie przebiegał proces. Kod uruchamiamy w bieżącym katalogu (stąd kropka po nazwie obrazu).

    Informacje zwracane przez ostanie polecenie:

    Jak widać, obraz może być zaktualizowany, wylistowany, usunięty, odczytany i zapisany.
    Istnieje też możliwość zbudowania obrazu bez umieszczania go w repozytorium. Wystarczy dodać

    w linii poleceń.

    Po zbudowaniu naszego obrazu i umieszczeniu w prywatnym repozytorium ACR przyszedł czas na uruchomienie jednej instancji naszej aplikacji. Wykorzystamy do tego ACI (Azure Container Instances) .

    Aplikacja jest dostępna pod adresem http://ai-customvision.northeurope.azurecontainer.io, ważne by dodać parametr –dns-name-label, inaczej będziemy skazani na wygenerowany przez Azure numer IP, Usługa będzie pracować na porcie 80. Wykorzystane jest REST API i metoda POST. Wystawiony zostanie publiczny adres IP Do pobrania obrazu z ACR potrzebne są odpowiednie uprawnienia. Dlatego też przekazywana jest para zmiennych $ACR_USERNAME i $ACR_PASSWORD. Pilnujmy  tych poświadczeń, istnieje możliwość ponownego wygenerowania, co jest zresztą zalecaną praktyką. Tego typu dane nie powinny nigdy znaleźć się w repozytorium kodu.

    Wykorzystaliśmy do tej pory dwie usługi umieszczone w jednej grupie zasobów. Dobrze widać to z poziomu Portalu.

    To samo możemy obejrzeć, do czego zachęcam, z poziomu linii komend:

    Wynik w postaci tabeli (-o table)

    Widok instancji z poziomu Portalu

    Nadeszła pora, by zweryfikować, czy nasz program działa, tak jak został zaprojektowany.

    Przetestujemy naszą uruchomioną aplikację przez API REST, wykorzystując curl i przygotowane w repozytorium Gituba zdjęcia.

    Pliki ze zdjęciami znajdują się w podkatalogu images.

    Zwracane rezultaty są w formacie JSON.

    Jeden z obrazów (horse1) został błędnie sklasyfikowany jako pies i to na dodatek z prawdopodobieństwem 100%. Czy można coś z tym zrobić ? Można, ale to temat na kolejne wpisy autora.

    Pamiętajmy o ostatniej linii, która usuwa wszelkie zasoby w obrębie grupy. Usługi w chmurze są ulotne, pamiętajmy o tym, że jeśli nie są potrzebne, nie powinny być aktywne, gdyż z reguły generują niepotrzebne koszty.
    Tutaj użyłem wersji bez potwierdzania (-y) i czekania aż się zakończy proces (–no-wait).

    Poniżej pełny kod skryptu umieszczony w repozytorium.

     

    Literatura:

    https://markheath.net/post/build-container-images-with-acr

     

     

    Uczenia maszynowe dla ubogich. Od trenowania modelu do dedykowanej usługi. Część 1

    2 komentarze

    Jeden z pierwszych  moich wpisów na blogu dotyczył  uczenia maszynowego według wujka Google.

    Od tego czasu pojawiły się nowe usługi , które znacznie ułatwiają rozpoczęcie pracy z modelami uczenia maszynowego.

    Postanowiłem przybliżyć jedną z usług Microsoftu, którą można przetestować za darmo.

    https://www.customvision.ai/

     

    Spróbujmy przygotować model, który potrafi klasyfikować zdjęcia. Na zdjęciach będziemy rozpoznawać różne zwierzęta.

    Serwis wymaga zalogowania się na konto Microsoft, ja wykorzystałem swój LiveID.

    Po zalogowaniu tworzymy nowy projekt:

     

    Wypełniamy nazwę projektu, jego opis, projekt typu klasyfikatora (Classification) i typ klasyfikacji (MultiClass). W ten sposób każdy z obrazów będzie otagowany jedną cechą. Jako domenę użyłem (General compact). Ustawienie modelu jako przenośnego będzie ważne dla dalszej części naszej przygody, gdy będziemy eksportować gotowy model.

    Jako zbioru treningowego dla trzech kategorii (kot, pies, koń) użyłem zdjęć z poniższych adresów:

    a) psy i koty

    https://www.floydhub.com/fastai/datasets/cats-vs-dogs/2/train

    b) konie:

    https://jamie.shotton.org/work/data.html

    Dla każdego z gatunków zwierząt załadowałem odpowiednio po sto zdjęć. To jest nasz zbiór treningowy, który zawiera trzysta przypadków oznakowanych “cat”, “dog” lub “horse”. Ten zbiór zawiera poprawnie przypisane otagowanie i jest bazą do przygotowania modelu uczenia maszynowego, który będzie potrafił odpowiedzieć na pytanie: Czy na zdjęciu (którego model nie zna, gdyż nie ma go w bazie treningowej) jest widoczny kot, pies, czy koń? Budujemy klasyfikator, który jest jednym z głównych algorytmów uczenia nadzorowanego. To my dostarczamy bazę wiedzy i w niej zawieramy cechę, która jest dla modelu prawdą.

    Po załadowaniu wszystkich zdjęć przystępujemy do trenowania danych.

    Parametrami tak wytrenowanego modelu są precyzja (precision) i czułość (recall).

    Co oznaczają te dwie liczby?

    Zacznijmy od tego czym jest  macierz pomyłek

    Image result for "macierz pomyłek"

    Na obrazie pokazano macierz pomyłek dla modelu uproszczonego do dwóch stanów.

    Załóżmy, że na zdjęciu może być kot (prawda, T(rue)) lub nie-kot (fałsz, F(false)). Nasz model predykcyjny wykrywa, tylko te dwa przypadki.

    Mamy cztery możliwości:

    1. Na zdjęciu jest kot, model wykrywa kota, mamy przypadek TP (True Positive)
    2. Na zdjęciu jest nie-kot, model wykrywa nie-kota, mamy przypadek TN (True Nagative)
    3. Na zdjęciu jest kot, model wykrywa nie-kota, mamy przypadek FN (False Negative)
    4. Na zdjęciu jest nie-kot, model wykrywa nie-kota, mamy przypadek  FP (False Positive)

    Precision (precyzja) to iloraz -> TP/(TP+FP)

    Recall (czułość)  to iloraz TP/(TP+FN)

    Po przygotowaniu wytrenowanego modelu możemy go wyeksportować. Mamy kilka możliwości, możemy zapisać go do rozwoju na urządzeniach mobilnych (iOS lub Android). Najciekawszą opcją jest, moim zdaniem możliwość, która kryje się pod nazwa DF (Dockerfile) .

    Model raz nauczony można też w prosty sposób testować na nowych zdjęciach. Te nowe zdjęcia mogą być kolejnym wsadem, który rozbudowuje naszą bazę wiedzy dla danych treningowych.  Pamiętajmy, że proces uczenia ma często cykliczny charakter.

    Pobieramy spakowany kod aplikacji w Pythonie, która wykorzystuje jako silnik uczenia maszynowego TensorFlow, serwerem www jest Flask.

    Częścią takiej aplikacji nie jest żadne ze zdjęć, które były używane w procesie uczenia modelu. Zapisywany jest jedynie plik, który zawiera konfigurację całego modelu zapisanego w formacie danego silnika. W tym przypadku jest to TensorFlow, a plik nosi nazwę model.pb.

    Zawartość pliku Dockerfile

    Najważniejsze pliki znajdują się w katalogu app

    app.py – główny kod aplikacji

    labels.txt – lista możliwych oznaczeń dla zdjęcia

    cat
    dog
    horse

    model.pb –  zapisane parametry wytrenowanego modelu w TensorFlow
    predict.py – kod w Pythonie obsługujący model uczenia maszynowego

    requirements.txt – lista modułów, które są potrzebne do działania aplikacji

    tensorflow==1.5.0
    pillow==5.0.0
    numpy==1.14.1
    flask==0.12.3

    Całość aplikacji umieściłem  na moim koncie na Githubie.

    Ciekawostką jest to, że po dodaniu projektu do repozytorium pojawia się informacja o potencjalnym problemie z bezpieczeństwem takiej aplikacji:

    djkormo,

    We found a potential security vulnerability in a repository for which you have been granted security alert access.

    @djkormo djkormo/ContainersSamples
    Known moderate severity security vulnerability detected in flask < 0.12.3 defined in requirements.txt.
    requirements.txt update suggested: flask ~> 0.12.3.
    Always verify the validity and compatibility of suggestions with your codebase.

     

    Trudno, jedna usługa Microsoftu generuje kod, a druga usługa Microsoftu uznaje go za niebezpieczny. Prawdziwa moc synergii.

    Po poprawieniu kodu zgodnie z sugestią, komunikat znika.

    Przykładowy kod umieściłem w repozytorium githuba.

    https://github.com/djkormo/ContainersSamples/tree/master/Docker/customvision-ai-cat-dog-horse-sample

    Spróbujmy zbudować z gotowego projektu REST API, które po załadowaniu na wejściu dowolnego zdjęcia, będzie w stanie odpowiedzieć na pytanie, czy znajduje się na nim jedno z trzech gatunków zwierząt.

    Wykorzystam do tego darmową piaskownicę

    https://labs.play-with-docker.com/

     

    Serwis wymaga założenia konta  w publicznym repozytorium DockerHuba.

    Po podaniu naszych poświadczeń pojawia się przycisk start

    Piaskownica wyłączy się sama po czterech godzinach. Pamiętajmy, aby nie trzymać tam poufnych i wrażliwych danych.

    Naciskamy przycisk +Add New Instance i uruchamiany nasz wirtualny kontener.

    Na początek klonujemy repozytorium z githuba

    Operacja wklejania to skrót klawiszowy Shift+Insert
    Operacja kopiowania to skrót klawiszowy Control+Insert

    Wchodzimy do odpowiedniego podkatalogu. To repozytorium zawiera też inne aplikacje.

    Zawartość wnętrza tego katalogu

    Rozpoczynamy proces budowy kontenera.

    Po krótkiej chwili następuje zbudowanie obrazu aplikacji.

    Konfiguracja tego procesu jest zapisana w pliku Dockerfile.

    Krótki opis dla osób, które nigdy nie korzystały z technologii konteneryzacji.

    Najpierw pobierany jest z repozytorium DockerHub obraz bazowy python:3.5.

    FROM python:3.5

    Dodawana jest zawartość katalogu app z hosta do katalogu app kontenera

    ADD app /app

    Instalowana jest aktualizacja oprogramowania do kontroli pakietów w Pythonie.

    RUN pip install –upgrade pip

    Instalowane są pakiety do Pythona zawarte w pliku  requirements.txt.

    RUN pip install -r /app/requirements.txt

    Port 80 zostaje udostępniony z kontenera do hosta.

    EXPOSE 80

    Ustalany jest katalog roboczy aplikacji w kontenerze.

    WORKDIR /app

    Uruchamiane jest polecenie, dzięki któremu  powstaje serwer www na udostępnionym wcześniej porcie 80.

    CMD python app.py

    Po zbudowaniu obrazu możemy uruchomić aplikację

    Podczas uruchamiania aplikacji wskazujemy jej nazwę customvision-ai:v1, mapowaniu portu kontenera (80) na port hosta (33000), flaga -d oznacza odłączenie się od kontenera. Będzie on uruchomiony niejako w tle.

    Nad oknem terminala pojawia się port, który został wystawiony po uruchomieniu aplikacji w kontenerze. W naszym przypadku jest to port 33000.

    Po uruchomieniu aplikacji możemy sprawdzić, czy usługa działa. Pamiętamy, że aplikacja ma pobrać zdjęcie i określić, czy jest na nim pies, kot czy koń.

    W katalogu images umieściłem sześć zdjęć. Żadne z nich nie było wykorzystywane podczas trenowania modelu.

    Do testowania modelu wykorzystałem polecenie curl. Aplikacja wystawia punkt końcowy (endpoint) pod adresem http://127.0.0.1:33000/image. Wykorzystywany jest  POST.

     

    Bystre oko zauważy, że  jeden z koni został sklasyfikowany z prawdopodobieństwem 100% jako pies.

    Literatura:

    https://pl.wikipedia.org/wiki/Tablica_pomy%C5%82ek

    https://github.com/djkormo/ContainersSamples/tree/master/Docker/customvision-ai-cat-dog-horse-sample

    Mała aktualizacja,  wygląda na to że serwis będzie wkrótce zamknięty. Kolejna część o tematyce ML w przygotowaniu

     

     

    Pierwsze zabawy z Kubernetes – część 1 Docker

    No Comments

    Konteneryzacja aplikacji wykorzystująca Dockera i ich orkiestracja  za pomocą Kubernetes  przebojem zdobywają coraz większą grupę zwolenników. Postanowiłem zmierzyć się z tymi produktami.

    Założyłem, ze wykorzystam jakieś darmowe środowisko, które pozwoli mi na pierwsze zabawy, bez zbędnej instalacji oprogramowania na stacji roboczej.  Powtarzalne operacje zostaną zapisane w plikach na Githubie.

    Niniejszy wpis wykorzystuje https://labs.play-with-k8s.com/ .

    Uruchomienie środowiska wymaga zalogowania się na konto GitHub lub na konto DockerHuba. Wybrałem tę drugą opcję.

    Po podaniu naszych poświadczeń i po naciśnięciu zielonego przycisku Start mamy do dyspozycji uruchomione gotowe środowisko do testów, które zostaje powołane na czas czterech godzin.

    Na początku musimy dodać pierwszą instancję. Po krótkiej chwili mamy już gotowe środowisko z dostępem do shella.

    Pierwsze polecenie uname -a

    Mamy dostęp do schowka
    Shift + insert = kopiuj
    Ctrl + insert = wklej

    Co więcej możemy doinstalować sobie potrzebne pakiety, np. edytor nano, midnight commander i inne cuda…

    Spróbujmy uruchomić prostą aplikację w kontenerze z gotowego publicznego repozytorium Docker Hub.

    Na początku uruchomimy pusta aplikacje www opartą o popularny serwer apache2.

    Polecenie to uruchamia obraz o nazwie httpd w wersji 2.4 z wystawiony portem tcp 80 od strony kontenera, port hosta zostanie zmapowany automatycznie. Za chwile zobaczymy na jaką wartość. Obrazu tego nie było do tej pory lokalnie, stąd komunikat “unable to find image”.  Przed budową zostanie on ściągnięty z repozytorium Docker Huba.

    Otrzymany wynik:

    Sprawdźmy listę naszych obrazów

    Otrzymany wynik:

    Sprawdzamy, które obrazy są uruchomione.

    Otrzymany wynik:

    Port 80 tcp kontenera zostaje zmapowany na port 32768 hosta.

    Pojawia się niebieskie łącze o nazwie wystawionego portu. Po kliknięciu mamy stronę z napisem

    It works!

     

    Wykorzystując gotowe obrazy, które  można traktować jako bazę, mamy możliwość tworzenia na ich podstawie bardziej skomplikowanych funkcjonalnie aplikacji. W tym celu możemy wykorzystać plik konfiguracyjny, tak zwany Dockerfile.

    Przykładowy Dockerfile:

    Uzupełniamy zawartość pustego pliku Dockerfile i budujemy nasz kontener.

    Uruchamiamy nasz kontener

    Jak widać kontener nasłuchuje na porcie 32770 hosta

    Można tę informację pobrać w bardziej elegancji sposób:

    Na górze powinien pojawić się niebieski link z takim numerem portu.
    Po uruchomieniu
    http://ip172-18-0-22-bf4df2mn5ugg00cc6t5g-32770.direct.labs.play-with-k8s.com/

    Mamy widoczną naszą aplikację.

    Warto zapamiętać budowę linku:

    http://ip<hyphen-ip>-<session_jd>-<port>.direct.labs.play-with-k8s.com

    A naszym przypadku był to

    http://ip172-18-0-22-bf4df2mn5ugg00cc6t5g-32770.direct.labs.play-with-k8s.com/

    Warto pamiętać o kilku zasadach, które pomagają budować obrazy kontenerowe w sposób efektywny

    1. Wybieramy obraz, z najbardziej optymalną  funkcjonalnością, czyli np. taki który zawiera tylko potrzebne oprogramowanie i nic więcej.
    2. Instalujemy tylko potrzebne oprogramowanie.
    3. Niepotrzebne pliki tymczasowe, które powstają podczas instalacji oprogramowania powinny zostać usunięte.
    4. Każde polecenie RUN tworzy nowa warstwę w obrazie, eliminujmy ich liczbę. Stad często widoczne jest sklejanie poleceń przez &&.
    5. Każdy projekt powinien mieć własny plik .dockerignore, w którym zawarte są reguły wykluczające pliki i katalogi w procesie budowania.

    Wykonajmy prosty eksperyment.

    Przygotowałem dwie wersje pliku DockerFile,

    jeden to obraz ubuntu:16.04,

    https://github.com/djkormo/ContainersSamples/blob/master/Docker/chess-ai/ubuntu/Dockerfile

    drugi to alpine:3.7.

    https://github.com/djkormo/ContainersSamples/tree/master/Docker/chess-ai/alpine/Dockerfile

    Otrzymany wynik:

    Wchodzimy do podkatalogów

    W podkatalogu mamy trzy wersje plików Dockeffile

    W każdym z podkatalogów budujemy lokalna wersje obrazu, tu dla przykładu dla obrazu pochodzącego z dystrybucji alpine.

    Dla obrazu Ubuntu

    Po zbudowaniu tych dwóch obrazów , możemy porównać ich rozmiar

    Otrzymujemy następujące wartości:

    To co widać od razu, z obrazu bazowego alpine:3.7 o wielkości 4.2MB powstał obraz local/chess-ai-alpine o wielkości 28.3MB. Natomiast z bazowego obrazu ubuntu:16.04 o wielkości 116MB powstał obraz localhost/chess-ai-ubuntu o wielkości 275MB. Funkcjonalność obu aplikacji, czyli prosta gra w szachy napisania w Javascript, jest taka sama, a różnica w wielkości jest dziesięciokrotna.

    Literatura:

    https://medium.com/@marcosnils/introducing-pwk-play-with-k8s-159fcfeb787b

    https://github.com/play-with-docker/play-with-docker/issues/259

    http://phusion.github.io/baseimage-docker/

    http://collabnix.com/kubernetes-hands-on-lab-1-setting-up-5-node-k8s-cluster/

    Categories: konteneryzacja, migawka

    Egzamin AZ-202 Materiały pomocnicze

    No Comments

    Pojawiły się nowe ścieżki certyfikacyjne Microsoftu w obszarze chmury Azure.

    Na początek spróbowałem znaleźć w internecie materiały pokrywające zakres.

    Jest to egzamin AZ-202 ,który kończy certyfikację developerską w przypadku zdania wcześniej egzaminu starej ścieżki czyli 70-532.

     

    Microsoft Azure Developer Certification Transition AZ-202

    Develop for cloud storage (10-15%)

    • Develop solutions that use file storage
    o May include but not limited to: Implement quotas for File Shares in storage account; move items in file shares between containers asynchronously; set file storage container properties in metadata

    https://docs.microsoft.com/en-us/azure/storage/files/storage-how-to-create-file-share
    https://docs.microsoft.com/en-us/azure/storage/blobs/storage-properties-metadata

    • Develop solutions that use a relational database
    o May include but not limited to: Create, read, update, and delete database tables by using code; implement dynamic data masking

    https://docs.microsoft.com/en-us/azure/sql-database/sql-database-dynamic-data-masking-get-started-portal

    Create Platform as a Service (PaaS) Solutions (20-25%)

    o May include but not limited to: Define the batch output and conditions by using Batch Service API; write code to run a batch job; run a batch job by using Azure CLI, Azure Portal, and other tools
    https://docs.microsoft.com/en-us/azure/batch/batch-task-output
    https://docs.microsoft.com/en-us/azure/batch/quick-create-portal
    https://docs.microsoft.com/en-us/azure/batch/quick-run-dotnet

    • Design and develop applications that run in containers
    o May include but not limited to: Configure diagnostic settings on resources; create a container image by using a Docker file; create an Azure Container Service (ACS/AKS) cluster by using the Azure CLI and Azure Portal; publish an image to the Azure Container Registry; implement an application that runs on an Azure Container Instance; implement container instances by using Azure Container Service (ACS/AKS), Azure Service Fabric, and other tools; manage container settings by using code

    https://docs.microsoft.com/en-us/azure/container-service/kubernetes/container-service-kubernetes-walkthrough

    Secure cloud solutions (5-10%)

    Develop for an Azure cloud model (20-25%)

    • Develop for asynchronous processing
    o May include but not limited to: Implement parallelism, multithreading, processing, durable functions, Azure logic apps, interfaces with storage, interfaces to data access, and appropriate asynchronous compute models
    https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-async-operations

    • Develop for autoscaling
    o May include but not limited to: Implement autoscaling rules and patterns (schedule, operational/system metrics, code that addresses singleton application instances, and code that addresses transient state
    • Implement distributed transactions
    o May include but not limited to: Identify tools to implement distributed transactions (e.g., ADO.NET, elastic transactions, multi-database transactions); manage transaction scope; manage transactions across multiple databases and servers
    https://docs.microsoft.com/en-us/azure/sql-database/sql-database-elastic-transactions-overview

    Implement cloud integration solutions (10-15%)

    • Configure a message-based integration architecture
    o May include but not limited to: Configure an app or service to send emails, Event Grid, and the Azure Relay Service; create and configure a Notification Hub, an Event Hub, and a Service Bus; configure queries across multiple products; configure an app or service with Microsoft Graph
    • Develop an application message model
    o May include but not limited to: Create a message schema and a message exchange; create an event model; create topics and subscriptions

    Develop AI, Machine Learning, and IoT solutions (20-25%)

    • Integrate Azure Cognitive Services in an application

    https://docs.microsoft.com/en-us/learn/modules/classify-images-with-custom-vision-service/index
    o May include but not limited to: Develop solutions by using intelligent algorithms that identify items from images and videos; develop solutions by using intelligent algorithms related to speech, natural language processing, Bing Search, and recommendations and decision making
    o https://docs.microsoft.com/en-us/azure/cognitive-services/

    • Create and integrate bots
    o May include but not limited to: Create a bot by using the Bot Framework; create a natural language conversation flow; manage bots by using the Azure Portal; register a bot by using the Bot Framework

    https://docs.microsoft.com/en-us/azure/bot-service/bot-service-quickstart?view=azure-bot-service-4.0

    https://tutorials.botsfloor.com/creating-a-bot-using-c-and-microsoft-bot-framework-a344420f9d6f

    Nasz pierwszy ChatBot

    • Integrate machine learning solutions in an app
    o May include but not limited to: Deploy a model; prepare data and data sources; work with data scientists to refine models
    • Create and implement IoT solutions
    o May include but not limited to: Configure Azure Time Series Insights; configure Stream Analytics service for inputs and outputs; establish bidirectional communication with IoT devices by using IoT Hub; register devices with IoT Hub Device Provisioning Service

    https://docs.microsoft.com/en-us/azure/time-series-insights/tutorial-create-populate-tsi-environment

    https://docs.microsoft.com/en-us/azure/stream-analytics/stream-analytics-add-inputs

    https://docs.microsoft.com/en-us/azure/stream-analytics/stream-analytics-define-outputs

     

    Dedykowana strona z labami Microsoft. Warto tu zajrzeć, można całkowicie za darmo po podłączeniu z naszym Live ID mieć dostęp do subskrypcji typu SandBox. Możemy korzystać z Portalu i Azure Cloud Shell. Możemy mieć uruchomioną jedną taką subskrypcję.

    https://docs.microsoft.com/pl-pl/learn/browse/?levels=intermediate&roles=developer

     

     

     

     

    Categories: Azure, Certyfikacja

    Od zera do mistrza Big Data i uczenia maszynowego w Pythonie. Część 4

    No Comments

     

    Po krótkim przeglądzie typów skalarnych i sekwencyjnych przyszedł czas, by pochylić się nad:

    • Instrukcjami warunkowymi
    • Pętlami
    • Wykorzystywaniem gotowych pakietów/modułów

    Dobre opanowanie instrukcji warunkowych jest podstawą do budowy bardziej skomplikowanych struktur sterujących przebiegiem programu.

    Należy zapamiętać jak Python traktuje  typ logiczny rzutowany na typ całkowity, gdzie 1 to prawa, a 0 to fałsz.

    Jak jest wartość logiczna pustej listy, krotki lub słownika ? (sprawdź!)

    Znajomość typu logicznego, operatorów logicznych i instrukcji warunkowej jest również niezbędna przy budowie funkcji i nieco później przy budowie obiektów

     

    Python dostarcza jedynie dwa rodzaje pętli , for oraz while., ale moim zdaniem jest to wystarczający wybór. Możliwa jest iteracja po elementach listy, elementach słownika , elementach napisu czy zakresach. Dodatkowe sterowanie przebiegiem petli w postaci instrukcji break, continue, pass , else:

    • break – przerwij pętlę
    • continue – przerwij obecną iterację
    • pass – nie rób nic
    • else – wykonuj jeśli pętla zakończyła się inaczej niż break

    Pozwala na budowę bardziej rozbudowanej logiki niż zwykła iteracja po elementach różnego typu.

     

    Jedną z silnych cech Pythona jest liczba dostępnych  i darmowych pakietów, które umożliwiają nam wykorzystanie skomplikowanych algorytmów w prosty sposób.

    Nie ma sensu wynajdywanie koła od nowa, ale warto poznać podstawowe funkcjonalności i sposób ich wykorzystania

    Przykładowe pakiety, gdzie praktyką jest stosowanie aliasów

    •  NumPy jest podstawowym zestawem narzędzi dla języka Python umożliwiającym zaawansowane obliczenia matematyczne, w szczególności są to operacje na macierzach..

    • Pandas umożliwia nam tworzenie ramek z danymi (dataframe), które ułatwiają nam pracę przy wstępnej i nie tylko obróbce danych pochodzących z wielu źródeł. Obsłużone są m.in. pliki płaskie, arkusze Excel, a nawet strony html.

    • Matplotlib pomaga przy tworzeniu wizualizacji, dostępnych jest wiele typów wykresów.

    • Folium wzbogaci naszą wizualizacją o interaktywne mapy

    • scilearn-kit jest zbiorem wielu algorytmów stosowanych w uczeniu  maszynowym i w praktyce zawiera wszystko co jest potrzebne do budowę modeli i ich trening.

    • Seaborn, który umożliwia bezpośrednie wykorzystanie ramek z danymi i pozwala na wygenerowanie wykresów bardziej zaawansowanych niż matplotlib.

    • TensorFlow to bogata biblioteka firmy Google, które umożliwia m.in zastosowanie algorytmów uczenia głębokiego (deep learning). Wspiera karty graficzne.

    Często na początku wielu programów w Pythonie, które dotykają uczenia maszynowego, mamy  taki zapis

    Kod notatnika Jupiter umieszczony na Githubie

    Podglad:

    https://nbviewer.jupyter.org/github/djkormo/PythonForML/blob/master/intro/Kurs_3_typy_warunki_iteracje.ipynb

    Uruchomienie:

    https://mybinder.org/v2/gh/djkormo/PythonForML/master?filepath=intro/Kurs_3_typy_warunki_iteracje.ipynb

    Po uruchomieniu kontenera należy wyczyścić informacje wyjściowe za pomocą menu Kernel -> Restart & Clear Output.

    Reenredowane wtyczką WP:

    Operacje logiczne

    In [1]:
    # zacznijmy od porownań 
    
    # czy zero jest mniejsze niż jeden
    
    print('0 < 1 : ',0 < 1)  #True
    
    # czy zero jest większe niż jeden
    
    print('0 > 1 : ',0 > 1)  #False
    
    # czy zero jest mniejsze lub równe jeden
    
    print('0 <= 1 : ',0 <= 1) #True
    
    # czy zero jest większe lub równe jeden
    
    print('0 >= 1 : ',0 >= 1) #False
    
    # czy jeden jest równe zero
    
    print('1 == 0 : ',1 == 0) #False
    
    # czy jeden jest rowne jeden
    
    print('1 == 1 : ',1 == 1) #True
    
    # czy jeden jest różne od zera
    
    print('1 != 0 : ',1 != 0) #True
    
    # czy jeden jest rózne od jeden
    
    print('',1!= 1) #False
    
    0 < 1 :  True
    0 > 1 :  False
    0 <= 1 :  True
    0 >= 1 :  False
    1 == 0 :  False
    1 == 1 :  True
    1 != 0 :  True
     False
    

    Typ logiczny True/False

    In [2]:
    # typ logiczny traktowany jako całkowity  True =1, False =0
    
    print('True + True = ',True + True, type(True + True))
    
    print('True - False = ',True - False,type(True + True))
    
    print('True * False = ',True * False,type(True + True))
    
    print('True / False =',True / False,type(True + True)) # ZeroDivisionError: division by zero
    
    True + True =  2 <class 'int'>
    True - False =  1 <class 'int'>
    True * False =  0 <class 'int'>
    
    ---------------------------------------------------------------------------
    ZeroDivisionError                         Traceback (most recent call last)
    <ipython-input-2-6b7cbeb8d79f> in <module>()
          7 print('True * False = ',True * False,type(True + True))
          8 
    ----> 9 print('True / False =',True / False,type(True + True)) # ZeroDivisionError: division by zero
    
    ZeroDivisionError: division by zero
    In [3]:
    # typ logiczny traktowany jako całkowity  True =1, False =0
    
    print('True and True = ',True and True, type(True and True))
    
    print('True or False = ',True or False,type(True or True))
    
    print('not False = ',not False,type(not False))
    
    print('not True =',not True,type(not True))
    
    True and True =  True <class 'bool'>
    True or False =  True <class 'bool'>
    not False =  True <class 'bool'>
    not True = False <class 'bool'>
    

    Instrukcja warunkowa

    In [4]:
    # instrukcja warunkowa if
    
    # wykona się jeśli wartość logiczna warunku jest prawdziwa
    if True:
      print('Prawda jest najważniejsza\n')
    
    # nie wykona się jeśli wartość logiczna warunku jest fałszywa
    
       
    if False:
      print('Ta instrukcja się nie wykona.')
        
        
    # wykonanie polecenia1 jeśli warunek jest prawdziwy a polecenie2 jeśli falszywy
    
    '''
    if ( warunek ):
        polecenie1
    else:
        polecenie2
    '''
    
    a=100
    
    if a<50:
      print('a jest mniejsze niż 50')
    else:
      print('a jest większe lub równe 50')
        
        
    
        
    
    Prawda jest najważniejsza
    
    a jest większe lub równe 50
    
    In [5]:
    a=53
    
    # instrukcja warunkowa z elif i else
    if a > 50:
        # to się wykona jeśli  warunek jest prawdziwy
        print("a jest większe niż 50")
    elif a == 50:
        # w przeciwnym przypadku, jeśli warunek jest prawdziwy
        print("a jest równe 50")
    else:
        # w pozostałych przypadkach
        print("a jest mniejsze niż 50")
        
        
    a=50
    # instrukcja warunkowa z elif i else
    if a > 50:
        # to się wykona jeśli  warunek jest prawdziwy
        print("a jest większe niż 50")
    elif a == 50:
        # w przeciwnym przypadku, jeśli warunek jest prawdziwy
        print("a jest równe 50")
    else:
        # w pozostałych przypadkach
        print("a jest mniejsze niż 50")
        
    a=47
    # instrukcja warunkowa z elif i else
    if a > 50:
        # to się wykona jeśli  warunek jest prawdziwy
        print("a jest większe niż 50")
    elif a == 50:
        # w przeciwnym przypadku, jeśli warunek jest prawdziwy
        print("a jest równe 50")
    else:
        # w pozostałych przypadkach
        print("a jest mniejsze niż 50")  
    
    a jest większe niż 50
    a jest równe 50
    a jest mniejsze niż 50
    
    In [6]:
    # wykorzystanie  funkcji input
    
    print("Podaj liczbę:", end=' ')
    
    raw_x = input() # pobieramy napis z wejścia standardowego (klawiatury)
    x = eval(raw_x) #  próba interpretacji napisu tak jak wyrażenia języka Python
    
    print('Wprowadzona liczba w stanie surowym: ',raw_x,type(raw_x),' Po ewaluacji :',x, type(x))
    
    if x<10:
        print('Wprowadzona liczba jest mniejsza niż 10')
    elif x == 10:
        # w przeciwnym przypadku, jeśli warunek jest prawdziwy
        print("Wprowadzona liczba jest równa 10")
    else:
        # w pozostałych przypadkach
        print("Wprowadzona liczba jest większa niż 10")  
    
    Podaj liczbę: 11
    Wprowadzona liczba w stanie surowym:  11 <class 'str'>  Po ewaluacji : 11 <class 'int'>
    Wprowadzona liczba jest większa niż 10
    

    Petle

    Petla for

    In [7]:
    # iteracja po liczbach całkowitych
    for licznik in (1,2,3,4):
        print('liczni k= ',licznik)
    
        
    # iteracja po elementach napisu
    
    napis1='Ala ma kota'    
    for litera in (range(len(napis1))):
        print ('Litera = ', napis1[litera])
                    
    # iteracja po liście
    
    owoce = ['gruszka', 'jabłko',  'śliwka']
    
    for owoc in range(len(owoce)):
        print ('Owoc =',owoce[owoc] )
            
    # petla for z dodatkowa klauzula else: na koncu
    
    for licznik in range(1,11):
        print('licznik =',licznik)
    else:
        print('Koniec i bomba!')       
        
        
        
    for licznik in range(10) :
            print('licznik = ',licznik,' ',end='\n')
    else:
            print('Koniec i bomba!')       
    
    liczni k=  1
    liczni k=  2
    liczni k=  3
    liczni k=  4
    Litera =  A
    Litera =  l
    Litera =  a
    Litera =   
    Litera =  m
    Litera =  a
    Litera =   
    Litera =  k
    Litera =  o
    Litera =  t
    Litera =  a
    Owoc = gruszka
    Owoc = jabłko
    Owoc = śliwka
    licznik = 1
    licznik = 2
    licznik = 3
    licznik = 4
    licznik = 5
    licznik = 6
    licznik = 7
    licznik = 8
    licznik = 9
    licznik = 10
    Koniec i bomba!
    licznik =  0  
    licznik =  1  
    licznik =  2  
    licznik =  3  
    licznik =  4  
    licznik =  5  
    licznik =  6  
    licznik =  7  
    licznik =  8  
    licznik =  9  
    Koniec i bomba!
    
    In [8]:
    # figura 1
    for i in range(10):
        print(str(i) * i)
    
    1
    22
    333
    4444
    55555
    666666
    7777777
    88888888
    999999999
    
    In [9]:
    # https://www.w3resource.com/python-exercises/python-conditional-exercise-17.php
    
    # małe ćwiczenie nd dwie petle for wraz z instrukcjami warunkowymi
    
    result_str="";    
    for row in range(0,7):    
        for column in range(0,7):     
            if (((column == 1 or column == 5) and row != 0) or ((row == 0 or row == 3) and (column > 1 and column < 5))):    
                result_str=result_str+"*"    
            else:      
                result_str=result_str+" "    
        result_str=result_str+"\n"    
    print(result_str);
    
      ***  
     *   * 
     *   * 
     ***** 
     *   * 
     *   * 
     *   * 
    
    

    Petla while

    In [10]:
    # wykonuj blok instrukcji dopóki warunek jest spełniony
    
    #while warunek:
    #   instrukcje
    
    i=0
    while i<5: # dopoki warunek jest prawdziwy
        print('Iteracja : ',i)
        i=i+1
    
    Iteracja :  0
    Iteracja :  1
    Iteracja :  2
    Iteracja :  3
    Iteracja :  4
    
    In [11]:
    # z dodaniem else:
    
    i=0
    while i<5: # dopoki warunek jest prawdziwy
        print('Iteracja : ',i)
        i=i+1
    else:  # wykona się na koncu petli 
        print('Koniec pętli.') 
    
    Iteracja :  0
    Iteracja :  1
    Iteracja :  2
    Iteracja :  3
    Iteracja :  4
    Koniec pętli.
    
    In [12]:
    # działa nawet dla pustej petli
    
    i=0
    while i>5: # dopoki warunek jest prawdziwy, w tym przypadku nigdy
        print('Iteracja : ',i)
        i=i+1
    else:  # wykona się na koncu petli 
        print('Koniec pustej pętli.')
    
    Koniec pustej pętli.
    

    Dodatkowe sterowanie w petli

    break - przerwij pętlę

    continue - przerwij obecną iterację

    pass - nie rób nic

    else - wykonuj jeśli pętla zakończyła się inaczej niż break

    break

    In [13]:
    for i in range(1,6): # od 1 do 5
        if i>3: # nie wykona się Iteracja dla i : 4,5
           break
            
        print('Iteracja dla i :',i)
        
    
    Iteracja dla i : 1
    Iteracja dla i : 2
    Iteracja dla i : 3
    

    continue

    In [14]:
    for i in range(1,6): # od 1 do 5
        if i%2==0:
          continue # pomijamy parzyste i
        print('Iteracja dla i :',i)   
    
    Iteracja dla i : 1
    Iteracja dla i : 3
    Iteracja dla i : 5
    

    pass

    In [15]:
    for i in range(1,6): # od 1 do 5
        if i%2==0:
          pass # nic nie rób
        print('Iteracja dla i :',i)   
    
    Iteracja dla i : 1
    Iteracja dla i : 2
    Iteracja dla i : 3
    Iteracja dla i : 4
    Iteracja dla i : 5
    
    In [16]:
    for i in range(1,11): # od 1 do 10
        if i%2==0:
          pass # nic nie rób
        else: # wykona się dla nieparzystych i
          print('Iteracja dla i :',i)   
    
    Iteracja dla i : 1
    Iteracja dla i : 3
    Iteracja dla i : 5
    Iteracja dla i : 7
    Iteracja dla i : 9
    

    else

    In [17]:
    #  wykonanie instrukcji na końcu pętli
    
    for i in range(1,6): # od 1 do 5
        if i%2==0:
          pass # nic nie rób
        print('Iteracja dla i :',i)  
    else:
        print('Koniec pętli.')
    
    Iteracja dla i : 1
    Iteracja dla i : 2
    Iteracja dla i : 3
    Iteracja dla i : 4
    Iteracja dla i : 5
    Koniec pętli.
    
    In [18]:
    # Przyklad petli for z else, który nie zostanie wykonany . 
    
    for i in range(1,11): # od 1 do 10
        if i%2==0:
          pass # nic nie rób
        print('Iteracja dla i :',i)  
        if i%5==0: # konczymy na i=5
            break
    else: #  ta czesc nie wykona się 
        print('Koniec pętli.')
    
    Iteracja dla i : 1
    Iteracja dla i : 2
    Iteracja dla i : 3
    Iteracja dla i : 4
    Iteracja dla i : 5
    

    Pakiety

    In [19]:
    # importowanie pakietu
    
    import this
    
    The Zen of Python, by Tim Peters
    
    Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases aren't special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    Now is better than never.
    Although never is often better than *right* now.
    If the implementation is hard to explain, it's a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea -- let's do more of those!
    
    In [20]:
    #  Dokumentacja danego pakietu/modułu
    
    help(this)
    
    Help on module this:
    
    NAME
        this
    
    MODULE REFERENCE
        https://docs.python.org/3.6/library/this
        
        The following documentation is automatically generated from the Python
        source files.  It may be incomplete, incorrect or include features that
        are considered implementation detail and may vary between Python
        implementations.  When in doubt, consult the module reference at the
        location listed above.
    
    DATA
        c = 97
        d = {'A': 'N', 'B': 'O', 'C': 'P', 'D': 'Q', 'E': 'R', 'F': 'S', 'G': ...
        i = 25
        s = "Gur Mra bs Clguba, ol Gvz Crgref\n\nOrnhgvshy vf o...bar ubaxvat ...
    
    FILE
        /home/nbuser/anaconda3_501/lib/python3.6/this.py
    
    
    
    In [21]:
    # lista obiektów, które zawiera dany pakiet 
    dir(this)
    
    Out[21]:
    ['__builtins__',
     '__cached__',
     '__doc__',
     '__file__',
     '__loader__',
     '__name__',
     '__package__',
     '__spec__',
     'c',
     'd',
     'i',
     's']
    In [22]:
    # wyswietlenie zawartości jednego z nich
    
    # odwołanie w formacie nazwapa_pkietu.nazwa_obiektu
    
    print('this.c = ',this.c,' type :', type(this.c))
    
    this.c =  97  type : <class 'int'>
    

    Aliasy

    In [23]:
    # Podczas importu pakietu można uzyc aaliasu
    import this as zp
    # dostep do zmiennej c  formacie nazwa_aliasu.nazwa_obiektu
    print('zp.c = ',zp.c,' type :', type(zp.c))
    # dostep z poprzedniego importu bez aliasu
    print('this.c = ',this.c,' type :', type(this.c))
    
    zp.c =  97  type : <class 'int'>
    this.c =  97  type : <class 'int'>
    
    In [24]:
    import sys
    # usuwamy załadowany pakiet math
    del sys.modules['math']
    # importujemy go ponownie
    import math as m
    # dostep do wartości PI i E
    print('m.pi = ',m.pi,' type :', type(m.pi)) #m.pi =  3.141592653589793  type : <class 'float'>
    print('m.e = ',m.e,' type :', type(m.e)) # m.e =  2.718281828459045  type : <class 'float'>
    # dostep bez podania aliasu 
    
    print('this.c = ',math.pi,' type :', type(math.pi)) # NameError: name 'math' is not defined
    
    m.pi =  3.141592653589793  type : <class 'float'>
    m.e =  2.718281828459045  type : <class 'float'>
    
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-24-c4f65d516bdb> in <module>()
          9 # dostep bez podania aliasu
         10 
    ---> 11 print('this.c = ',math.pi,' type :', type(math.pi)) # NameError: name 'math' is not defined
    
    NameError: name 'math' is not defined

    Często stosowane pakiety

    In [25]:
    # czesto wykorzystujemy aliasy przy imporcie znanych pakietow
    
    import pandas as pd
    
    # wersja pakietu pd
    
    print (pd.__version__) # 0.20.3
    # gdzie został zainstalowany pakiet
    
    print(pd) # <module 'pandas' from '/home/nbuser/anaconda3_501/lib/python3.6/site-packages/pandas/__init__.py'>
    
    import numpy as np
    
    # wersja pakietu np
    print (np.__version__) # 1.15.1
    
    # gdzie został zainstalowany
    print(np)
    
    # import podmodułu pyplot z pakietu patplotlib jako alias plt
    
    import matplotlib.pyplot as plt
    %matplotlib inline
    
    # Proste demo 
    
    # generowanie 100 pseudolosowych liczb 
    
    liczby=np.random.rand(100,1)
    
    # budowa histogramu
    
    plt.hist(liczby)
    
    # wyswietlenie 
    
    plt.show()
    
    0.20.3
    <module 'pandas' from '/home/nbuser/anaconda3_501/lib/python3.6/site-packages/pandas/__init__.py'>
    1.15.1
    <module 'numpy' from '/home/nbuser/anaconda3_501/lib/python3.6/site-packages/numpy/__init__.py'>
    

    Importowanie obiektów do globalnej przestrzeni nazw

    In [26]:
    # importowanie z pakietu this wyłącznie zmiennej c
    
    from this import c
    
    print('c = ',c,' type :', type(c))
    
    # importowanie z pakietu this wszystkich obiektow
    # nie jest to polecane, gdzyż skutecznie zaśmieci 
    # nam globalna przestrzeń nazw
    
    c=15.0
    print('c = ',c,' type :', type(c))
    
    from this import *
    
    # zmienna c została nadpisana wartością 97 z pakietu
    print('c = ',c,' type :', type(c))
    
    c =  97  type : <class 'int'>
    c =  15.0  type : <class 'float'>
    c =  97  type : <class 'int'>
    
    In [29]:
    # co jeśli brakuje nam zainstalowanego pakietu
    # importujemy pakiet folium do wizualizacji map
    
    import folium   # ModuleNotFoundError: No module named 'folium'
    
    # pakiet nie został zainstalowany 
    
    ---------------------------------------------------------------------------
    ModuleNotFoundError                       Traceback (most recent call last)
    <ipython-input-29-e188466ce0bb> in <module>()
          2 # importujemy pakiet folium do wizualizacji map
          3 
    ----> 4 import folium
    
    ModuleNotFoundError: No module named 'folium'
    In [30]:
    # instalacja pakietu folium
    
    # wykorzystujemy instalato pip dostepny z poziomu Pythona
    
    !pip install folium 
    
    Collecting folium
      Using cached https://files.pythonhosted.org/packages/88/89/8186c3441eb2a224d2896d9a8db6ded20ddd225f109e6144494a9893a0c1/folium-0.6.0-py3-none-any.whl
    Requirement already satisfied: requests in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from folium) (2.19.1)
    Requirement already satisfied: six in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from folium) (1.11.0)
    Requirement already satisfied: numpy in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from folium) (1.15.1)
    Requirement already satisfied: branca>=0.3.0 in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from folium) (0.3.0)
    Requirement already satisfied: jinja2 in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from folium) (2.9.6)
    Requirement already satisfied: certifi>=2017.4.17 in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from requests->folium) (2017.7.27.1)
    Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from requests->folium) (3.0.4)
    Requirement already satisfied: idna<2.8,>=2.5 in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from requests->folium) (2.6)
    Requirement already satisfied: urllib3<1.24,>=1.21.1 in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from requests->folium) (1.23)
    Requirement already satisfied: MarkupSafe>=0.23 in /home/nbuser/anaconda3_501/lib/python3.6/site-packages (from jinja2->folium) (1.0)
    Installing collected packages: folium
    Successfully installed folium-0.6.0
    
    In [32]:
    '''pojdzmy krok dalej i zbudujmy prosty mechanizam wykrywający 
    ze dany pakiet nie jest zainstalowany '''
    
    import sys
    # sprawdzenie czy dany pakiet został zainstalowany
    if  not 'folium' in sys.modules:
     # instalujemy pakiet
      !pip install folium
    
    # importujemy pakietu
    import folium
    # sprawdzamy jego wersje 
    print ('Folium version :',folium.__version__)
    
    Folium version : 0.6.0
    

     

    Categories: migawka, Python

    Od zera do mistrza Big Data i uczenia maszynowego w Pythonie. Część 3

    No Comments

    Po zapoznaniu się z podstawowymi typami zmiennych skalarnych warto zdobyć wiedzę o  typach sekwencyjnych

    Należą do nich głównie

    • Listy (lists)
    • Krotki (tuples)
    • Słowniki (dictionaries)
    • Zbiory  (sets)

    Dzielimy je na zmienialne (mutable) i  niezmienialne (immutable)

    Listy i zbiory, słowniki są przedstawicielami tej pierwszej grupy, a krotki i , napisy i zbiory niezmienne (frozenset) są przedstawicielami tej drugiej..
    Typów niezmienialnych nie można bezpośrednio modyfikować
    Postanowiłem poświęcić na początek nieco uwagi na rozszerzenie wiedzy o napisach, sposobie indeksowania i generowania podciągów.
    Warto zapamiętać: Indeksy zaczynamy od zera, więc pierwszy element zmiennej napisowej s to s[0], ostatni to s[len[s]-1]. Mamy też do dyspozycji indeksy ujemne  s[-1] to ostatni element napisu, a s[-len(s)] pierwszy.

    Ważne jest uzmysłowienie sobie informacji o tym, że Python jest nie tylko dynamicznie typowany, ale również silnie typowany, dlatego musimy uważać na wszelkie konwersje typów. Poniżej prosty kod, na trzy instrukcje print, tylko jedna wykona się poprawnie.

    https://www.python.org/dev/peps/pep-0020/
    The Zen of Python: “Explicit is better than implicit.”

    Postaram się utrwalić rzutowanie, nie tylko między zmiennymi skalarnymi, ale również sekwencyjnymi.

    Notatnik umieszczony na GitHub

    Podgląd:

    https://nbviewer.jupyter.org/github/djkormo/PythonForML/blob/master/intro/Kurs_2_typy_sekwencyjne_iterowane.ipynb

    Uruchomienie:

    https://mybinder.org/v2/gh/djkormo/PythonForML/master?filepath=intro/Kurs_2_typy_sekwencyjne_iterowane.ipynb

    Po uruchomieniu kontenera należy wyczyścić informacje wyjściowe za pomocą menu Kernel -> Restart & Clear Output.

    Reenderowane wtyczką WP:

    Indeksowanie

    In [1]:
    # deklarujemy zmienną s1 typu napis 
    
    s1="Witamy na kursie Pythona."
    print('Napis s : ',s1)
    
    #pierwszy element napisu oznaczamy cyfra 0 []
    
    print ("\nIndeksowanie dodatnie:\n")
    
    print('Pierwszy element napisu s1 : ',s1[0])
    
    # drugi element [1]
    
    print('Drugi element napisu s1 : ',s1[1])
    
    # trzeci element [2]
    
    print('Trzeci element napisu s1 : ',s1[2])
    
    
    # ostatni element napisu [dlugosc -1]
    
    print('Ostatni element napisu s1 : ',s1[len(s1)-1])
    
    print ("\nIndeksowanie ujemne:\n")
    
    # mozna tez wykorzystac indeksy ujemne
    
    
    # ostatni element [-1]
    
    print('Ostatni element napisu s1 : ',s1[-1])
    
    # przedostatni element [-2]
    
    print('Przedostatni element napisu s1 : ',s1[-2])
    
    # pierwszy element [-dlugosc]
    
    print('Pierwszy element napisu s1 : ',s1[-len(s1)])
    
    Napis s :  Witamy na kursie Pythona.
    
    Indeksowanie dodatnie:
    
    Pierwszy element napisu s1 :  W
    Drugi element napisu s1 :  i
    Trzeci element napisu s1 :  t
    Ostatni element napisu s1 :  .
    
    Indeksowanie ujemne:
    
    Ostatni element napisu s1 :  .
    Przedostatni element napisu s1 :  a
    Pierwszy element napisu s1 :  W
    

    Tworzenie podciagów

    In [2]:
    # tworzenie podciagow (slice)
    
    s1="Witamy na kursie Pythona."
    print('Oryginalny napis ',s1, ' o długości ',len(s1))
    
    # tworzymy podciag zaczynajacy sie od indeksu [1]  do ponizej indeksu [2]
    
    print ('Drugi element o indeksie [1] : ',s1[1:2]) # wyswietlamy tylko element drugi - indeks [1]
    
    # ogolna postac [a:b:c] 
    # a oznacza indeks elementu startowego, 
    # b oznacza gorny indeks elementu, ktory nas nie interesuje
    # c oznaccza roznice miedzy kolejnymi indeksami
    
    # domyslnie a =0, b =len(napis), c  = 1
    
    # wyswietlenie wzystkich elementow napisu
    
    print('Wszystkie elementy napisu s1 : ',s1[::])
    
    
    # wyswietlanie co drugiego elementu napisu
    
    print('Co drugi element napisu s1 : ',s1[::2])
    
    # krok zmiany moze byc tez ujemny
    
    print('Napis s1 w odwrotnej kolejności : ',s1[::-1])
    
    # co drugi element w odwrotnej kolejnosci
    
    print('Co drugi element napisu s1 w odwrotnej kolejnosci : ',s1[::-2])
    
    Oryginalny napis  Witamy na kursie Pythona.  o długości  25
    Drugi element o indeksie [1] :  i
    Wszystkie elementy napisu s1 :  Witamy na kursie Pythona.
    Co drugi element napisu s1 :  Wtm akri yhn.
    Napis s1 w odwrotnej kolejności :  .anohtyP eisruk an ymatiW
    Co drugi element napisu s1 w odwrotnej kolejnosci :  .nhy irka mtW
    

    Listy [lists]

    LIsty sa obiektami sekwencyjnymi zmienialnymi (mutable)

    In [1]:
    # listy tworzymy za pomoca nawiasów kwadratowych []
    
    lista1=[1,2,'Ala',4]
    print('Lista lista1 : ',lista1,type(lista1))
    
    # elementy listy nie musze byc tego samego typu
    
    # utworzmy pusta liste, warto pamietac ze konwersja takiej listy na typ logiczny zwraca falsz
    
    lista2=[]
    
    print('Lista lista2 : ',lista2,type(lista2),bool(lista2))
    
    # indeksowanie elementow analogiczne jak dla napisow
    
    print(lista1, lista1[1])  #  "[1, 2, 'Ala', 4]"
    print(lista1[-1])     # Wyswietla ostatni element listy
    lista1[3] = 'ma'      # Zmiana elementu o indeksie [3] 
    print('Lista lista1 : ',lista1)         #  wyswietla "[1, 2, 'Ala', 'ma']"
    
    # dedykowane dla list metody
    
    lista1.append('kota') # Dodajemy element listy na jej koncu
    print('Lista lista1 : ',lista1)         # "[1, 2, 'Ala', 'ma', 'kota']"
    
    
    lista11 = lista1.pop()    # Odczytanie ostatniego elementu listy z jednoczesnym usunieciem
    print('Lista lista11 : ',lista11,'Lista lista1 : ', lista1)      # kota [1, 2, 'Ala', 'ma']
    
    # lista w odwrotnej kolejnosci
    
    lista1rev=lista1[::-1]
    print('Lista lista1rev : ',lista1rev)      # kota [1, 2, 'Ala', 'ma']
    
    # dodanie nowego elementu listy w pozycji o indeksie 2, w szczegolnosci moze byc to kolejna lista
    
    lista12 = lista1.insert(2,['Basia','ma','psa'])
    print('Lista lista12 : ',lista12,' o liczbie elementow : ', lista12)
    
    
    # liczba elementow listy
    print('Lista lista1 : ',lista1, 'o liczbe elementow : ',len(lista1))
    
    # dodawanie list
    
    lista3 = lista1 +lista1
    print('Lista lista3 : ',lista3, 'o liczbie elementow : ',len(lista3))
    
    # mnozenie listy przez wartosc z prawej strony
    
    lista4=lista3[:4:1]*2;
    print('Lista lista4 : ',lista4, ' o liczbie elementow : ',len(lista4))
    
    # mnozenie listy przez wartosc z lewej strony
    
    lista5=2*lista3[:3:1];
    print('Lista lista5 : ',lista5,' o liczbie elementow : ',len(lista5))
    
    Lista lista1 :  [1, 2, 'Ala', 4] <class 'list'>
    Lista lista2 :  [] <class 'list'> False
    [1, 2, 'Ala', 4] 2
    4
    Lista lista1 :  [1, 2, 'Ala', 'ma']
    Lista lista1 :  [1, 2, 'Ala', 'ma', 'kota']
    Lista lista11 :  kota Lista lista1 :  [1, 2, 'Ala', 'ma']
    Lista lista1rev :  ['ma', 'Ala', 2, 1]
    Lista lista12 :  None  o liczbie elementow :  None
    Lista lista1 :  [1, 2, ['Basia', 'ma', 'psa'], 'Ala', 'ma'] o liczbe elementow :  5
    Lista lista3 :  [1, 2, ['Basia', 'ma', 'psa'], 'Ala', 'ma', 1, 2, ['Basia', 'ma', 'psa'], 'Ala', 'ma'] o liczbie elementow :  10
    Lista lista4 :  [1, 2, ['Basia', 'ma', 'psa'], 'Ala', 1, 2, ['Basia', 'ma', 'psa'], 'Ala']  o liczbie elementow :  8
    Lista lista5 :  [1, 2, ['Basia', 'ma', 'psa'], 1, 2, ['Basia', 'ma', 'psa']]  o liczbie elementow :  6
    

    Konwersja typow dla list

    In [3]:
    # konwersja na typ listy -> list(obiekt)
    
    # zamiana napisu na liste, kazdy z elementow napisu jest zamieniony na element listy
    
    s1='Ala ma kota, a Basia ma psa.';
    l1=list(s1)
    print('Lista l1 : ',l1,' o liczbie elementow: ',len(l1))
    
    # konwersja z listy na napis, 
    
    s2=''.join(l1)
    print('Napis s2 : ',s2, ' o dlugosci : ',len(s2))
    
    # type range, bedziemy z niego intensywnie korzystac przy petlach, domyslny krok 1.
    
    r1=range(50) # generujemy liczby od zera do najwiekszej mniejszej niz 50
    print('Sekwencja r1 : ',r1, type(r1),' liczba elementow : ',len(r1)) # <class 'range'>
    
    r2=range(-20,20) # generujemy liczby od -20 do najwiekszej mniejszej niz 20
    print('Sekwencja r2 : ',r2, type(r2),' liczba elementow : ',len(r2)) # <class 'range'>
    
    r3=range(-20,20,2) # generujemy liczby od -20 do najwiekszej mniejszej niz 20 co krok rowny 2
    print('Sekwencja r3 : ',r3, type(r3),' liczba elementow : ',len(r3)) # <class 'range'>
    
    
    # zamiana na liste
    
    lr1=list(r1)
    print('Lista lr1 : ',lr1, type(lr1)) # <class 'list'>
    lr2=list(r2)
    print('Lista lr2 : ',lr2, type(lr2)) # <class 'list'>
    lr3=list(r3)
    print('Lista lr3 : ',lr3, type(lr3)) # <class 'list'>
    
    Lista l1 :  ['A', 'l', 'a', ' ', 'm', 'a', ' ', 'k', 'o', 't', 'a', ',', ' ', 'a', ' ', 'B', 'a', 's', 'i', 'a', ' ', 'm', 'a', ' ', 'p', 's', 'a', '.']  o liczbie elementow:  28
    Napis s2 :  Ala ma kota, a Basia ma psa.  o dlugosci :  28
    Sekwencja r1 :  range(0, 50) <class 'range'>  liczba elementow :  50
    Sekwencja r2 :  range(-20, 20) <class 'range'>  liczba elementow :  40
    Sekwencja r3 :  range(-20, 20, 2) <class 'range'>  liczba elementow :  20
    Lista lr1 :  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] <class 'list'>
    Lista lr2 :  [-20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] <class 'list'>
    Lista lr3 :  [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18] <class 'list'>
    

    Krotki (tuples)

    Krotki sa elementami sekwencyjnymi niezmienialnymi (immutable)

    In [4]:
    # krotki tworzymy za pomoca nawiasów zwyklych ()
    
    k1= 1,3,5,'Pies'
    print(k1,type(k1))
    
    # W szczegolnosci mozemy tworzyc krotki bez wykorzystania ()
    
    k2 = 1,2,3,4,'Ala','ma','kota'
    print(k2,type(k2))
    
    # pusta krotka, konwertowalna na typ logiczny jako falsz
    
    k3=()
    
    print(k3,type(k3),bool(k3))
    
    # budowa krotki z jednym elementem
    
    k4a=(1)
    print(k4a,type(k4a)) # 1 <class 'int'>
    
    # w takim przypadku, nalezy postawic znak , po wartosci pierwszego/ostatniego elementu
    
    k4b=(1,)
    print(k4b,type(k4b)) # (1,) <class 'tuple'>
    
    (1, 3, 5, 'Pies') <class 'tuple'>
    (1, 2, 3, 4, 'Ala', 'ma', 'kota') <class 'tuple'>
    () <class 'tuple'> False
    1 <class 'int'>
    (1,) <class 'tuple'>
    
    In [5]:
    # dostep do elementow krotki  analogicznie jak do elementow listy
    
    k5=('Ala','ma','kota',3.14,12,2.0)
    print('Zawartosc krotki k5 : ',k5)
    print('Pierwszy element krotki k5: ',k5[0])
    
    print('Ostatni element: ',k5[-1])
    
    # dostep do elementow krotki 
    
    krotka1 = ('Poznan', 'Warszawa', 1995, 2018)
    krotka2 = (1, 2, 3, 4, 5, 6, 7 ,8)
    
    print ("krotka1[0]: ", krotka1[0])
    print ("krotka2[1:5]: ", krotka2[1:5])
    
    Zawartosc krotki k5 :  ('Ala', 'ma', 'kota', 3.14, 12, 2.0)
    Pierwszy element krotki k5:  Ala
    Ostatni element:  2.0
    krotka1[0]:  Poznan
    krotka2[1:5]:  (2, 3, 4, 5)
    
    In [6]:
    # modyfikacja elementu krotki
    
    krotka1 = ('Poznan', 'Warszawa', 1995, 2018)
    
    krotka1[2] =1999 # TypeError: 'tuple' object does not support item assignment
    
    # krotka jest niezmienialna, co oznacza ze raz stworzony obiekt jest tylko do odczytu
    
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-6-4dac655d56c5> in <module>()
          3 krotka1 = ('Poznan', 'Warszawa', 1995, 2018)
          4 
    ----> 5 krotka1[2] =1999 # TypeError: 'tuple' object does not support item assignment
          6 
          7 # krotka jest niezmienialna, co oznacza ze raz stworzony obiekt jest tylko do odczytu
    
    TypeError: 'tuple' object does not support item assignment
    In [7]:
    krotka1 = ('Poznan', 'Warszawa', 1995, 2018)
    krotka2 = (1, 2, 3, 4, 5, 6, 7 ,8)
    
    krotka3=krotka1+krotka2
    print('Zawartosc krotka1 : ',krotka1,' o dlugosci :',len(krotka1))
    print('Zawartosc krotka2 : ',krotka2,' o dlugosci :',len(krotka2))
    print('Zawartosc krotka3 : ',krotka3,' o dlugosci :',len(krotka3))
    
    Zawartosc krotka1 :  ('Poznan', 'Warszawa', 1995, 2018)  o dlugosci : 4
    Zawartosc krotka2 :  (1, 2, 3, 4, 5, 6, 7, 8)  o dlugosci : 8
    Zawartosc krotka3 :  ('Poznan', 'Warszawa', 1995, 2018, 1, 2, 3, 4, 5, 6, 7, 8)  o dlugosci : 12
    

    Dodatkowe operacje na krotkach

    In [8]:
    # Sortowanie
    
    # kwotka nieposortowana
    
    osoby = ('Alicja','Magda','Izabella','Agnieszka','Jadwiga')
    print('Krotka osoby :', osoby)
    
    # sortowanie krotki osoby
    
    osoby = tuple(sorted(osoby))
    
    print('Krotka osoby po sortowaniu :', osoby)
    
    Krotka osoby : ('Alicja', 'Magda', 'Izabella', 'Agnieszka', 'Jadwiga')
    Krotka osoby po sortowaniu : ('Agnieszka', 'Alicja', 'Izabella', 'Jadwiga', 'Magda')
    

    Konwersja typow dla krotek

    In [9]:
    listax = [1,5,3,6]
    
    # konwersja na krotke za pomoaca funkcji tuple()
    
    krotkax = tuple(listax)
    print('Krotkax : ',krotkax,type(krotkax),'liczba elementow : ',len(krotkax))
    
    # sortowanie 
    krotkax = tuple(sorted(listax))
    print('Krotkax po sortowaniu: ',krotkax,type(krotkax),'liczba elementow : ',len(krotkax))
    
    Krotkax :  (1, 5, 3, 6) <class 'tuple'> liczba elementow :  4
    Krotkax po sortowaniu:  (1, 3, 5, 6) <class 'tuple'> liczba elementow :  4
    

    Slowniki {dictionaries}

    In [10]:
    # słowniki przechowuja  zestawy par klucz-wartość
    
    #tworzymy pusty słownik, rzutowany na typ logiczny daje wartość fałszu
    
    slownik1={}
    
    print(slownik1,type(slownik1),bool(slownik1)) # {} <class 'dict'> False
    
    # dodajemy pierwsza parę do pustego słownika
    
    slownik1['wzrost']=187
    
    # dodajemy druga pare
    
    slownik1['kolor']='blond'
    
    print(slownik1,len(slownik1)) # {'wzrost': 187, 'kolor': 'blond'} 2
    
    # klucz jest unikalny w ramach slownika
    
    # zmiana wartosci dla klucza, takie podstawienie niszczy poprzednia wartość
    slownik1['wzrost']=190
    
    print(slownik1,len(slownik1)) # {'wzrost': 190, 'kolor': 'blond'} 2
    
    # usuniecie pary klucz-wartosc
    
    del slownik1['wzrost']
    
    print(slownik1,len(slownik1)) # {'kolor': 'blond'} 1
    
    
    # dodanie po raz kolejny pary {'wzrost':1}
    slownik1['wzrost']=190
    
    # zauważmy zmianę kolejności kluczy
    print(slownik1,len(slownik1)) # {'kolor': 'blond', 'wzrost': 190} 2
    
    # wyczyszczenie zawartości słownika
    
    slownik1.clear()
    
    print(slownik1,len(slownik1)) # {} 0
    
    {} <class 'dict'> False
    {'wzrost': 187, 'kolor': 'blond'} 2
    {'wzrost': 190, 'kolor': 'blond'} 2
    {'kolor': 'blond'} 1
    {'kolor': 'blond', 'wzrost': 190} 2
    {} 0
    
    In [11]:
    #usunięcie obiektu 
    
    del slownik1
    
    print(slownik1,len(slownik1)) # NameError: name 'slownik1' is not defined
    
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-11-3a1d850715e0> in <module>()
          3 del slownik1
          4 
    ----> 5 print(slownik1,len(slownik1)) # NameError: name 'slownik1' is not defined
    
    NameError: name 'slownik1' is not defined
    In [12]:
    # tworzymy slownik z trzema parami klucz-wartosc
    
    # wykorzystujemy tu notacje JSON
    
    slownik2 =	{
      "wzrost": 190,
      "kolor": "brunet",
      "hobby": "szachy"
    }
    
    print(slownik2,len(slownik2))  # {'wzrost': 190, 'kolor': 'brunet', 'hobby': 'szachy'} 3
    
    # mozna też uzyć funkcji dict()
    
    slownik3 = dict(wzrost=190, kolor="brunet", hobby="szachy")
    
    print(slownik3,len(slownik3)) # {'wzrost': 190, 'kolor': 'brunet', 'hobby': 'szachy'} 3
    
    # klucze
    
    # zwracamy liste kluczy
    
    print(slownik3.keys()) # dict_keys(['wzrost', 'kolor', 'hobby'])
          
    # sprawdzamy , czy dany klucz istnieje
    
    # wykorzystujemy operator zawierania in
    
    print('Czy klucz wzrost istnieje w slowniku slownik3 : ','wzrost' in slownik3)
    print('Czy klucz miara istnieje w slowniku slownik3 : ','miara' in slownik3)
    
    # lub negacje operatora in
    
    print('Czy klucz wzrost nie istnieje w slowniku slownik3 : ','wzrost'not in slownik3)
    print('Czy klucz miara nie istnieje w slowniku slownik3 : ','miara' not in slownik3)
    
    # przedsmak wykorzytując pętlę for
    
    for klucz in slownik3.keys():
      print('Slownik slownik3 : ',klucz, '=', slownik3[klucz])
    
    # wartosci
    
    # zwracamy liste wartosci 
    
    print(slownik3.values()) # dict_values([190, 'brunet', 'szachy'])
    
    # klucze/wartosci
    
    # zwracamy listę kluczy-wartosci
    
    print(slownik3.items()) # dict_items([('wzrost', 190), ('kolor', 'brunet'), ('hobby', 'szachy')])
    
    
    
    # dodanie lub aktualizacja pary klucz-wartosc
    
    slownik3.update({'przyjaciel': False})
    
    
    print(slownik3.items()) # dict_items([('wzrost', 190), ('kolor', 'brunet'), ('hobby', 'szachy'), ('przyjaciel', False)])
    
    slownik3.update({'przyjaciel': True}) 
    
    print(slownik3.items()) # dict_items([('wzrost', 190), ('kolor', 'brunet'), ('hobby', 'szachy'), ('przyjaciel', True)])
    
    {'wzrost': 190, 'kolor': 'brunet', 'hobby': 'szachy'} 3
    {'wzrost': 190, 'kolor': 'brunet', 'hobby': 'szachy'} 3
    dict_keys(['wzrost', 'kolor', 'hobby'])
    Czy klucz wzrost istnieje w slowniku slownik3 :  True
    Czy klucz miara istnieje w slowniku slownik3 :  False
    Czy klucz wzrost nie istnieje w slowniku slownik3 :  False
    Czy klucz miara nie istnieje w slowniku slownik3 :  True
    Slownik slownik3 :  wzrost = 190
    Slownik slownik3 :  kolor = brunet
    Slownik slownik3 :  hobby = szachy
    dict_values([190, 'brunet', 'szachy'])
    dict_items([('wzrost', 190), ('kolor', 'brunet'), ('hobby', 'szachy')])
    dict_items([('wzrost', 190), ('kolor', 'brunet'), ('hobby', 'szachy'), ('przyjaciel', False)])
    dict_items([('wzrost', 190), ('kolor', 'brunet'), ('hobby', 'szachy'), ('przyjaciel', True)])
    

    Konwersja typów dla słowników

    In [13]:
    lista1 = [1,2,3,4] 
    lista2 = ['a','b','c','d'] 
    
    # jak z dwoch list stworzyć słownik
    
    
    # Funkcja zip() tworzy listę krotek z podanych elementów, potem nalezy tę listę skonwertować na słownik
    
    lista12=list(zip(lista1,lista2)) 
    slownik12=dict(zip(lista1,lista2)) 
    
    print("lista12 :",lista12)
    print("slownik12 :",slownik12)
    
    lista12 : [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
    slownik12 : {1: 'a', 2: 'b', 3: 'c', 4: 'd'}
    

    Zbiory {sets}

    In [14]:
    #Deklaracja pustego zbioru, konwertowalnego na typ logiczny jako fałsz
    
    zbior1 = set()
    
    print('Zawartość zbior1 : ',zbior1,'',type(zbior1),bool(zbior1))
    
    # definicja zbioru trzech elementów, konwertowalnego na typ logiczny jako prawda
    zbior2=set(['Agnieszka','Magda','Izabella'])
        
        
    print('Zawartość zbior2 : ',zbior2,'',type(zbior2),bool(zbior2))
    
    # elementy zbioru są unikalnie, nie mogą się powtarzać
    zbior3=set(['Agnieszka','Magda','Izabella','Magda'])
    
        
    print('Zawartość zbior3 : ',zbior3,'',type(zbior3))
    
    # jesli taki element istnieje to nie zostanie dodany do zbioru
    zbior3.add('Agnieszka')
    
    print('Zawartość zbior3 po dodaniu istniejacego elementu: ',zbior3,'',type(zbior3))
    
    
    
    zbiora=set([2,4,8,16])
    zbiorb=set([2,4,6,8])
    print ('\nMamy dwa zbiory: zbiora i zbiorb .')
    print('zbiora : ',zbiora, ' zbiorb : ',zbiorb)
    
    
    # podstawowe operacje na zbiorach
    
    # suma zbiorów: elementy ktore sa w  pierwszym lub drugim zbiorze
    print('\nSuma zbiorów: \n')
    
    print('zbiora | zbiorb : ',zbiora | zbiorb) 
    
    # alternatywnie
    print('zbiora.union(zbiorb) : ',zbiora.union(zbiorb)) 
    
    print('\nRóżnica zbiorów: \n')
    # roznica zbiorow: tylko te elementy ktore sa w  pierwszym zbiorze z nie ma ich w drugim
    print('zbiora - zbiorb : ',zbiora - zbiorb)  
    
    #alternatywnie
    
    print('zbiora.difference(zbiorb) : ',zbiora.difference(zbiorb))  
    
    print('\nIloczyn zbiorów: \n')
    
    # iloczyn zbiorow: elementy ktore sa w pierwszym i drugim zbiorze (czesc wspolna) 
    
    print('zbiora & zbiorb : ',zbiora & zbiorb)                             
    
    #alternatywnie
    
    print('zbiora.intersection(zbiorb)  : ',zbiora.intersection(zbiorb) )   
    
    
    print('\nRóżnica symetryczna zbiorów: \n')
    # roznica symetryczna : elementy ktore sa w obu zbiorach , ale bez ich czesci wspolnej
    
    print('zbiora ^ zbiorb : ',zbiora ^zbiorb)                
    
    # alternatywnie
    
    print('zbiora.symmetric_difference(zbiorb) : ',zbiora.symmetric_difference(zbiorb) ) 
    
    # dodanie elementu do zbioru
    print('\nDodanie elementu zbioru :')
    zbiora.add(7)
    
    print('zbiora : ',zbiora)
    
    # usuniecie elementu ze zbioru
    print('\nUsuniecie elementu zbioru:')
    zbiora.discard(7)
    print('zbiora : ',zbiora)
    
    
    # zawieranie się zbiorów
    
    print('\nZawieranie sie zbiorow: ')
    
    zbior1a = set([1,4,8])
    zbior1b = set([1,2,4,6,8])
    
    print('\nzbior1a : ',zbior1a, ' zbior1b : ',zbior1b)
    
    
    # podzbiory
    
    print('\nPodzbiory: ')
    
    print('czy zbiór zbior1a jest podzbiorem zbioru zbior1b: ',zbior1a.issubset(zbior1b))
    print('czy zbiór zbior1b jest podzbiorem zbioru zbior1a: ',zbior1b.issubset(zbior1a))
    print('czy zbiór zbior1b jest podzbiorem zbioru zbior1b: ',zbior1b.issubset(zbior1b))
    
    
    
    
    # nadzbiory
    
    print('\nNadzbiory: ')
    
    print('czy zbiór zbior1a jest nadzbiorem zbioru zbior1b: ',zbior1a.issuperset(zbior1b))
    print('czy zbiór zbior1b jest nadzbiorem zbioru zbior1a: ',zbior1b.issuperset(zbior1a))
    print('czy zbiór zbior1b jest nadzbiorem zbioru zbior1b: ',zbior1b.issuperset(zbior1b))
    
    
    
    # alternatywnie
    print('\nPodzbiory/nadzbiory alternatywna notacja: ')
    print('czy zbiór zbior1a jest podzbiorem zbioru zbior1b: ',zbior1a<=zbior1b)
    print('czy zbiór zbior1a jest nadzbiorem zbioru zbior1b: ',zbior1a>=zbior1b)
    print('czy zbiór zbior1a jest nadzbiorem zbioru zbior1a: ',zbior1a==zbior1b)
    
    Zawartość zbior1 :  set()  <class 'set'> False
    Zawartość zbior2 :  {'Magda', 'Agnieszka', 'Izabella'}  <class 'set'> True
    Zawartość zbior3 :  {'Magda', 'Agnieszka', 'Izabella'}  <class 'set'>
    Zawartość zbior3 po dodaniu istniejacego elementu:  {'Magda', 'Agnieszka', 'Izabella'}  <class 'set'>
    
    Mamy dwa zbiory: zbiora i zbiorb .
    zbiora :  {8, 16, 2, 4}  zbiorb :  {8, 2, 4, 6}
    
    Suma zbiorów: 
    
    zbiora | zbiorb :  {2, 4, 6, 8, 16}
    zbiora.union(zbiorb) :  {2, 4, 6, 8, 16}
    
    Różnica zbiorów: 
    
    zbiora - zbiorb :  {16}
    zbiora.difference(zbiorb) :  {16}
    
    Iloczyn zbiorów: 
    
    zbiora & zbiorb :  {8, 2, 4}
    zbiora.intersection(zbiorb)  :  {8, 2, 4}
    
    Różnica symetryczna zbiorów: 
    
    zbiora ^ zbiorb :  {16, 6}
    zbiora.symmetric_difference(zbiorb) :  {16, 6}
    
    Dodanie elementu zbioru :
    zbiora :  {2, 4, 7, 8, 16}
    
    Usuniecie elementu zbioru:
    zbiora :  {2, 4, 8, 16}
    
    Zawieranie sie zbiorow: 
    
    zbior1a :  {8, 1, 4}  zbior1b :  {1, 2, 4, 6, 8}
    
    Podzbiory: 
    czy zbiór zbior1a jest podzbiorem zbioru zbior1b:  True
    czy zbiór zbior1b jest podzbiorem zbioru zbior1a:  False
    czy zbiór zbior1b jest podzbiorem zbioru zbior1b:  True
    
    Nadzbiory: 
    czy zbiór zbior1a jest nadzbiorem zbioru zbior1b:  False
    czy zbiór zbior1b jest nadzbiorem zbioru zbior1a:  True
    czy zbiór zbior1b jest nadzbiorem zbioru zbior1b:  True
    
    Podzbiory/nadzbiory alternatywna notacja: 
    czy zbiór zbior1a jest podzbiorem zbioru zbior1b:  True
    czy zbiór zbior1a jest nadzbiorem zbioru zbior1b:  False
    czy zbiór zbior1a jest nadzbiorem zbioru zbior1a:  False
    
    In [15]:
    # Istnieją też zbiory niezmienialne frozenset
    
    zbiorniezmienialny1a =frozenset([1,2,3,4,5,6,7,8])
    print('Zbiór niezmienialny zbiorniezmienialny1a : ',zbiorniezmienialny1a, type(zbiorniezmienialny1a))
    
    # wykonanie tej instrukcji konczy się błedem
    
    zbiorniezmienialny1a.add(9) #AttributeError: 'frozenset' object has no attribute 'add'
    
    # wykonanie tej instrukcji konczy się błedem
    zbiorniezmienialny1a.discard(2) #AttributeError: 'frozenset' object has no attribute 'discard'
    
    Zbiór niezmienialny zbiorniezmienialny1a :  frozenset({1, 2, 3, 4, 5, 6, 7, 8}) <class 'frozenset'>
    
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-15-baaf14606d8a> in <module>()
          6 # wykonanie tej instrukcji konczy się błedem
          7 
    ----> 8 zbiorniezmienialny1a.add(9) #AttributeError: 'frozenset' object has no attribute 'add'
          9 
         10 # wykonanie tej instrukcji konczy się błedem
    
    AttributeError: 'frozenset' object has no attribute 'add'

    Konwersja typów dla zbiorów

    In [16]:
    # konwersja z listy do zbioru zmienialnego i niezmienialnego 
    
    listanapedow1=["C:\\","D:\\","E:\\","C:\\"]
    zbiornapedow1=set(listanapedow1)
    zbiornapedow2=frozenset(listanapedow1)
    print('Zbiór zbiornapedow1 : ',zbiornapedow1, type(zbiornapedow1))
    print('Zbiór zbiornapedow2 : ',zbiornapedow2, type(zbiornapedow2))
    
    # konwersja każdej litery na element zbioru
    
    zbiorn1=set('Dorotka')
    
    
    # konwersja całego napisu na element zbioru
    
    zbiorn2=set(['Dorotka'])
    
    print('Zbiór :',zbiorn1,type(zbiorn1),' o długości : ',len(zbiorn1))
    print('Zbiór :',zbiorn2,type(zbiorn2),' o długości : ',len(zbiorn2))
    
    Zbiór zbiornapedow1 :  {'E:\\', 'C:\\', 'D:\\'} <class 'set'>
    Zbiór zbiornapedow2 :  frozenset({'E:\\', 'C:\\', 'D:\\'}) <class 'frozenset'>
    Zbiór : {'o', 'a', 'D', 'k', 'r', 't'} <class 'set'>  o długości :  6
    Zbiór : {'Dorotka'} <class 'set'>  o długości :  1
    
    In [ ]:
     
    
    Categories: migawka, Python

    Od zera do mistrza Big Data i uczenia maszynowego w Pythonie. Część 2

    2 komentarze

    Anaconda i notatniki Jupitera

    Do zabawy z Pythonem wykorzystałem Anaconda i dostępne notatniki Jupitera.

    Downloads

    Pobrałem wersję 64 bitową z obsługa Pythona 3.

    Po pomyślnej instalacji uruchamiamy Anaconda Navigator

    Wybieramy jupyter notebook, przycisk Launch i naszym oczom otwiera się strona

    http://localhost:8888/tree

    Tworzymy notatnik wybierając język Python 3.

    Przygotowaliśmy nasz pierwszy notatnik o nazwie Nowy, nazwę można łatwo zmienic z poziomu menu File lub klikając na nazwę.

     

    Podstawowe operacje dostępne w notatniku można wylistować za pomocą klawisza H.  Należy pamiętać, by kursor nie był umieszczony w komórce.

    Notatnik można rozumieć jako interkatywny skrypt, który składa się z dwóch rodzajów komórek: opisowych (w składni Markdown)  i tych, w których wpisujemy kod języka.

    Opis składni Markdown można znaleźć w wielu miejscach. Ja korzystałem z

    https://github.com/adam-p/markdown-here/wiki/Markdown-Here-Cheatsheet

    Próbujmy sprawdzić wersję  naszych narzędzi

    U mnie wyglada to tak:

    Siłą języka, nie tylko w zakresie uczenia maszynowego (ML), jest dostępna ogromna list  gotowych pakietów, które znacznie upraszczają budowę skomplikowanych algorytmów.

    Pakiety gromadzone są w repozytorium zwanym PyPI (Python Package Index). Instalacja modułów  może być wykonana również z poziomu notatnika.
    Kod zaczynamy od !pip, co oznacza wykorzystanie instrukcji powłoki pip. Przykładem takiego pakietu jest folium pozwalający na obsługę map.

    Krótka demonstracja możliwości

    Kod umieszczony na GitHub

    Podgląd:

    https://nbviewer.jupyter.org/github/djkormo/PythonForML/blob/master/intro/MapaPolski.ipynb

    Uruchomienie:

    https://mybinder.org/v2/gh/djkormo/PythonForML/master?filepath=intro/MapaPolski.ipynb

    Po uruchomieniu kontenera należy wyczyścić informacje wyjściowe za pomocą menu Kernel -> Restart & Clear Output.

    Reenderowane wtyczką WP:

    In [8]:
    # importujemy pakiet folium
    import folium
    
    # konfiguracja obiektu mapy
    mapa = folium.Map(location=[52.325, 18.94], zoom_start=6)
    
    # wyswietlamy mape
    mapa
    
    Out[8]:
    In [ ]:
     
    

    Na tym kończę pierwszą demonstrację. Nie można być astronautą z marszu.

    Wracamy do podstaw

    • Na początku warto zaznajomić się z czterema podstawowymi typami skalarnymi:
      całkowitym,
      rzeczywistym,
      logicznym,
      łańcuchowym
      Należy zwrócić uwagę na to, że mamy do czynienia z dynamicznym typowaniem, co w praktyce oznacza zmianę typu zmiennej w czasie i wymaga kontroli typu przez programistę. To na czym chcę się dodatkowo skoncentrować to jawna konwersja typów, system pomocy, wbudowane funkcje.

    Przykładowy  notatnik  umieszczony na githubie:

    https://github.com/djkormo/PythonForML/blob/master/intro/Kurs_1_typy_zmienne.ipynb

    Podgląd:

    https://nbviewer.jupyter.org/github/djkormo/PythonForML/blob/master/intro/Kurs_1_typy_zmienne.ipynb

    Uruchomienie:

    https://mybinder.org/v2/gh/djkormo/PythonForML/master?filepath=intro/Kurs_1_typy_zmienne.ipynb

    Po uruchomieniu kontenera należy wyczyścić informacje wyjściowe za pomocą menu Kernel -> Restart & Clear Output.

    Reenderowane wtyczką WP:

    In [1]:
    print("Powitanie!")
    
    Powitanie!
    

    Podstawowe typy danych

    całkowite

    rzeczywiste

    logiczne

    napisy

    In [2]:
    # Python jako kalkulator
    
    1+2
    
    Out[2]:
    3
    In [3]:
    # Priorytety operatorów  dodawania i mnożenia
    
    1+2*3
    
    Out[3]:
    7
    In [4]:
    # wymuszanie priorytetow operacji
    
    (1+2)*3
    
    Out[4]:
    9
    In [5]:
    # dzielenie
    
    1/2
    
    Out[5]:
    0.5
    In [6]:
    # dzielenie, ktorego wynikiem jest wartość rzeczywista
    
    4.0/2.0
    
    Out[6]:
    2.0
    In [7]:
    # dzielenie calkowite
    
    5//2
    
    Out[7]:
    2
    In [8]:
    # nie mylić dzielenia całkowitego // z resztą z dzielenia całkowitego %
    5%2
    
    Out[8]:
    1
    In [9]:
    # typ całkowity
    
    type(2)
    
    Out[9]:
    int
    In [10]:
    # typ rzeczywisty
    
    type(2.0)
    
    Out[10]:
    float
    In [11]:
    # konwersja typu całkowitego na rzeczywisty
    
    float(1)
    
    Out[11]:
    1.0
    In [12]:
    # konwersja typu rzeczywistego na całkowity
    
    int(1.0)
    
    Out[12]:
    1
    In [13]:
    # zapiszmy wartość w zmiennej a
    
    a=1
    
    # wyświetlamy jej wartość
    
    print(a)
    
    # wyświetlamy jej typ
    
    print(type(a))
    
    1
    <class 'int'>
    
    In [14]:
    # python jest typowany dynamiczne, typ zmiennej a moze się zmieniać w czasie
    
    a=2.1
    
    # wyswietlmy jej wartość
    
    print(a)
    
    # wyswietlmy jej typ
    
    print(type(a))
    
    2.1
    <class 'float'>
    
    In [15]:
    #usuwanie zmiennych
    
    a=2.5
    print(a)
    
    #usuwamy zmienną a
    
    del a
    
    #uzycie usuniętej zmiennej konczy się błędem
    
    print(a)
    
    2.5
    
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-15-a90c5f43f700> in <module>()
         10 #uzycie usuniętej zmiennej konczy się błędem
         11 
    ---> 12 print(a)
    
    NameError: name 'a' is not defined
    In [16]:
    #Python rozróżnia duże i małe litery
    
    b=1.0
    print(B) #name 'B' is not defined
    
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-16-6d77e211bb3c> in <module>()
          2 
          3 b=1.0
    ----> 4 print(B) #name 'B' is not defined
    
    NameError: name 'B' is not defined
    In [17]:
    # dwie różne zmienne  o dwóch różnych typach
    
    b=1.0
    B=102
    print(b,type(b),B,type(B))
    
    1.0 <class 'float'> 102 <class 'int'>
    
    In [18]:
    # utworzenie zmiennych typu napis, możemy stosować jak ograniczniki znaki " jak rownież '
    
    s1="NApis1"
    s2='Napis2'
    
    # powielamy pięć razy zawartość zmiennej s1 i umieszczamy całość w zmiennje s3
    
    s3=5*s1
    print(s3)
    
    # sklejanie napisów za pomocą operatora +
    
    s4=s1+" "+s2
    print(s4)
    
    # postawowe funkcje operujące na napisach
    
    print(len(s4)) # dlugość napisu
    print(s4.upper()) # zamiana na duze litery
    print(s4.lower()) # zamiana na male litery
    
    print(s4.capitalize())  # kapitalizacja napisu
    print(s4.replace('N', 'NN'))  #zamiana N na NN
    print(s4.rjust(20)) #dopasowanie do prawej napisu , pozostałe znaki wypełnione spacją 
    print(s4.ljust(20)) #dopasowanie do lewej napisu, pozostałe znaki wypełnione spacją-
    print(s4.center(20)) #dopasowanie do lewej napisu, pozostałe znaki wypełnione spacją-
    print('  napis ze spacjami po obu stronach     '.strip())
    
    # formatowanie napisu wyjściowego
    
    s5 ='{0} {1} {2}'.format('Witamy', 'w roku',2018)
    print(s5)  
    
    NApis1NApis1NApis1NApis1NApis1
    NApis1 Napis2
    13
    NAPIS1 NAPIS2
    napis1 napis2
    Napis1 napis2
    NNApis1 NNapis2
           NApis1 Napis2
    NApis1 Napis2       
       NApis1 Napis2    
    napis ze spacjami po obu stronach
    Witamy w roku 2018
    
    In [19]:
    #typy logiczne przyjmują tylko dwie wartości prawda/fałsz
    
    l1=True
    l2=False
    
    #wyswietlamy wartośc obu zmiennych
    
    print(l1,l2)
    print(type(l1))
    
    #operator  iloczynu logicznego AND
    
    print(l1 and l2)
    
    #operator sumy logicznej OR
    
    print(l1 or l2)
    
    # operator negacji NOT
    
    print (not l2)
    
    # alternatywa rozłączna XOR
    
    print (l1 != l2)
    
    True False
    <class 'bool'>
    False
    True
    True
    True
    

    System pomocy

    In [20]:
    #  polecenie help pozwala na dostęp do systemowej pomocy  Pythona
    help(print)
    help(len)
    
    Help on built-in function print in module builtins:
    
    print(...)
        print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
        
        Prints the values to a stream, or to sys.stdout by default.
        Optional keyword arguments:
        file:  a file-like object (stream); defaults to the current sys.stdout.
        sep:   string inserted between values, default a space.
        end:   string appended after the last value, default a newline.
        flush: whether to forcibly flush the stream.
    
    Help on built-in function len in module builtins:
    
    len(obj, /)
        Return the number of items in a container.
    
    
    In [22]:
    # istnieje też możliwość otrzymania pomocy wykorzystując składnię Jupitera. To nie jest część języka Python (!)
    
    # dodajemy znak ? przed nazwą funkcji
    
    ?print
    
    # to samo jeśli dodamy znak ? po nazwie funkcji
    
    print?
    

    Konwersja typów

    In [23]:
    #konwersja typu logicznego na całkowity 
    
    a1=int(True)
    a2=int(False)
    print('poczatek: ',a1,a2)
    
    #konwersja typu całkowitego na logiczny 0 -> False, pozostałe liczby -> True
    
    b1=bool(-1)
    b2=bool(0)
    b3=bool(1)
    b4=bool(2)
    print('konwersja z int: ',b1,b2,b3,b4)
    
    
    #konwersja typu  rzeczywistego na logiczny 0.0 -> False, pozostałe liczby -> True
    
    b11=bool(-1.0)
    b21=bool(0.0)
    b31=bool(1.5)
    b41=bool(5.6)
    print('konwersja z float:', b11,b21,b31,b41)
    
    
    # konwersja napisu na typ logiczny, pusty napis -> False, pozostałe -> True
    
    b12=bool('')
    b22=bool('Ala')
    b32=bool('ma')
    b42=bool('kota')
    print('KOnwersja ze string: ',b12,b22,b32,b42)
    
    poczatek:  1 0
    konwersja z int:  True False True True
    konwersja z float: True False True True
    KOnwersja ze string:  False True True True
    
    In [24]:
    #konwesja typu łańcuchowego i liczowego
    
    s1='13'
    s2='12'
    a1=int(s1+s2)
    print(a1)
    print(type(a1))
    
    # konwersja połączona z operarorem potęgowania **
    
    a2=int(s1)**2
    print(a2)
    print(type(a2))
    
    # konwersja typu łańcuchowego przez typ całowity do typu rzeczywistego
    
    f1 = float(int(a1)-int(a2))
    print(f1, type(f1))
    
    # konwersja typu rzeczywistego na łańcuchowy
    
    s3=str(f1)
    print(s3,type(s3))
    
    1312
    <class 'int'>
    169
    <class 'int'>
    1143.0 <class 'float'>
    1143.0 <class 'str'>
    

    Kilka sztuczek

    In [25]:
    # zamiana wartości dwoch zmiennych
    
    z1 =5
    z2 =7
    
    print('Stan wejściowy: ',z1,z2, type(z1),type(z2))
    
    # klasycznie za pomocą dodatkowej zmiennej
    
    temp= z1
    z1  = z2
    z2  = temp
    
    print('Stan wyjściowy  z dodatkową zmienną: ',z1,z2, type(z1),type(z2))
    
    # sprytnie, bez pomocy dodatkowej zmiennej
    # tu zastosowano krotkę (tuple) 
    # będzie o tym w dalszej cześć kursu
    
    print('Stan wejściowy: ',z1,z2, type(z1),type(z2))
    
    # krotka w tle
    z1, z2 = z2, z1
    
    print('Stan wyjściowy z krotką: ',z1,z2, type(z1),type(z2))
    
    Stan wejściowy:  5 7 <class 'int'> <class 'int'>
    Stan wyjściowy  z dodatkową zmienną:  7 5 <class 'int'> <class 'int'>
    Stan wejściowy:  7 5 <class 'int'> <class 'int'>
    Stan wyjściowy z krotką:  5 7 <class 'int'> <class 'int'>
    
    In [26]:
    # Komentarze w Języku Python to znak #, po którym wszystkie znaki do końca linii sa ignorowane przez interpreter
    
    a, b,c,d,s = 1, 2,3,4.5,'Jest parno' # deklarujemy wartość kilku zmiennych w jednej linii 
    # Na szczęście można też tworzyć komentarze  o zakresie wielu linii 
    '''
    To jest komentarz, który można zapisać w wielu liniach.
    Często jest stosowany na początku definicji funkcji.
    '''
    print(a,b,c,d,s, type(a),type(b),type(c),type(d),type(s))
    
    1 2 3 4.5 Jest parno <class 'int'> <class 'int'> <class 'int'> <class 'float'> <class 'str'>
    
    In [27]:
    # potegowanie ma wyższy priorytet niż mnożenie, dodawanie, ale również zmianę znaku (operator unarny) (!)
    
    print(-2**8)   # wynik -256
    
    # w takiej sytuacji zawsze można wymusić priorytet wykorzystująca nawiasy ()
    
    print((-2)**8) # wynik 256
    
    -256
    256
    
    In [28]:
    # Dzielenie modulo % i // ma zastosowanie nie tylko dla liczb całkowitych dodatnich, ale również dla liczb całkowitych ujemnych
    # a nawet liczb rzeczywistych
    
    # Dzielenie całkowite dla liczb całkowitych ujemnych
    
    print(-13//-5)
    
    # Dzielenie całkowite dla liczb całkowitych ujemnych
    
    print(-13%-5)
    
    
    # Dzielenie całkowite dla liczb rzeczywistych
    
    print(2.4//1.3)
    
    # Dzielenie modulo  dla liczb rzeczywistych
    
    print(2.4%1.3)
    
    2
    -3
    1.0
    1.0999999999999999
    
    In [29]:
    # Python udostępnia również odpowiednik liczb zespolonych
    
    
    c1=2+5j
    c2=2-4j
    
    print(c1,c2,type(c1),type(c2))
    
    
    # dodawanie
    
    c3=c1+c2
    
    # odejmowanie
    
    c4 =c1-c2
    
    # mnozenie 
    
    c5=c1*c2
    
    # dzielenie
    
    c6=c1/c2
    
    print(c3,c4,c5,c6,type(c3),type(c4),type(c5),type(c6))
    
    # są też dostępne inne operacje
    
    # moduł 
    
    print(abs(3+4j))  #   
    
    # potegowanie
    
    print(pow(c1, 2))
    
    # tworzenie zmiennej typu zespolonego
    c7=complex(2,5) # 2+5j
    print(c7.real,type(c7.real)) # część rzeczywista  2.0
    print(c7.imag,type(c7.imag)) # część urojona 5.0
    print(c7.conjugate(),type(c7.conjugate())) 
    
    # do bardziej skompilowanych wyrażeń mozna wykorzystać modul cmath
    
    import cmath
    print(cmath.sin(2 + 5j), type(cmath.sin(2 + 5j)))
    
    (2+5j) (2-4j) <class 'complex'> <class 'complex'>
    (4+1j) 9j (24+2j) (-0.8+0.9j) <class 'complex'> <class 'complex'> <class 'complex'> <class 'complex'>
    5.0
    (-21+20j)
    2.0 <class 'float'>
    5.0 <class 'float'>
    (2-5j) <class 'complex'>
    (67.47891523845588-30.879431343588244j) <class 'complex'>
    
    In [47]:
    import sys
    
    # maksymalnia wartość liczby całkowitej 64 bitowej
    
    print(sys.maxsize)
    
    amax=amax=2**63 -1
    
    print(amax,type(amax))
    
    # przekraczamy wartość maksymalną, czy pojawi się błąd ?
    amax=2**128
    
    print(amax,type(amax)) # nadal typu int
    
    9223372036854775807
    9223372036854775807 <class 'int'>
    340282366920938463463374607431768211456 <class 'int'>
    
    In [58]:
    # przykład z poprzedniej komorki, który obrazuje dodawania kolejnych bajtów dla zmiennej całkowitej
    # rozszerzanie on demand
    
    #  mały przedsmak  wykorzystania pętli for
    
    x=256
    for i in range(1,6):
      x=x*x
      print ("size:", x.__sizeof__(), "value:", x)
    
    size: 28 value: 65536
    size: 32 value: 4294967296
    size: 36 value: 18446744073709551616
    size: 44 value: 340282366920938463463374607431768211456
    size: 60 value: 115792089237316195423570985008687907853269984665640564039457584007913129639936
    
    In [51]:
    # liczby całkowite mogą stosować inne systemy niż dziesiętny
    
    # system dwójkowy -> liczbe rozpoczybamy od 0b
    
    abin=0b1111 # 1*2**3 + 1*2**2 + 1*2**1 +1*2**0 = 8 + 4 + 2 + 1 =15
    
    # system usemkowy -> liczbe rozpoczybamy od 0o
    
    aoct = 0o123 # 1*8**2 + 2*8**1 + 3 * 8**0 = 64 + 16 +3 = 83
    
    # system szestnastkowy -> liczbe rozpoczybamy od 0x
    
    ahex =0xff # 15*16**1 + 15*16**0 =  240 + 15 = 255
    
    print(abin,aoct,ahex)
    
    15 83 255
    
    In [ ]:
     
    

    Literatura:
    Opis podłączenia notatnika z Githuba do WordPressa

    https://github.com/ghandic/nbconvert

    Cheat sheet

    https://perso.limsi.fr/pointal/_media/python:cours:mementopython3-english.pdf

    Tutorial z Kaggle

    https://www.kaggle.com/learn/python

     

    Categories: migawka, Python

    Od zera do mistrza Big Data i uczenia maszynowego w Pythonie. Część 1

    No Comments

    W dniu, w którym postanowiłem rozpocząć krótki kurs podstaw Pythona, prawdziwy lub domniemany gad jest nadal poszukiwany w okolicach wyspy.

    Robiąc w 2017 roku  kurs MPP Data Science firmy Microsoft miałem do wyboru dwie opcje. Poznać podstawy języka R lub poznać podstawy języka Python.

    Kurs udało się ukończyć z wynikiem pozytywnym

    Wybrałem to pierwsze. Program RStudio, z którym pracowałem przez klika miesięcy jest naprawdę potężnym narzędziem. W rękach sprawnego naukowca danych potrafi wyśpiewać swoją opowieść.

    Po pewnym czasie postanowiłem uzupełnić moją wiedzę o drugi popularny w obszarze Data Science język jakim jest Python.

    Nie chcę wchodzić w dyskusję, który z języków R czy Python jest lepszy. Oba warto znać, ale głównie warto poznać matematykę, które jest niejako pod spodem tych setek i tysięcy gotowych bibliotek. Jeśli myślisz, że uciekniesz przed królową nauk, to się grubo mylisz.

    Na początku ustanawiam sobie kilka zasad:

    1. Wykorzystam dostępne i darmowe kursy online dotyczące języka Python. Mowa o podstawie składni. Z założenia będzie to Python 3.

    2. Wykorzystam darmowe oprogramowanie  (silnik język i narzędzia dodatkowe)

    3. Opanuję przynajmniej podstawy uczenia maszynowego w języku Python

    4. Poznam takie biblioteki jak TensorFlow, SciPy, Keras

    5. Opanuję podstawy Apache Sparka w Pythonie, czyli  poznam pysparka.

    6. Spróbuję nie używać dedykowanych narzędzi firmy Microsoft. Kurs MPP był oparty głównie o Microsoft Azure Machine Learning. Pora ruszyć na inne wody.

    Będę się  uczyć razem z wami i pokażę narzędzia jakie powinien poznać młody adept sztuki  i nie tylko młody.

    Znalazłem uruchomiony przez IBM  w okolicach 2015 darmowy serwis

    Python for Data Science

     

    Anakonda

     

    W następnym odcinku  rozpoczniemy od podstaw składni Pythona, będę się uczyć razem z Wami.

    To dopiero początek przygody, należy ją potraktować jak wyzwanie i zabawę przy poznawaniu nowych technologii, egzaminy, certyfikaty  to tylko sprawa wtórna.

    Czy uda się zrealizować wszystkie punkty? Pewnie nie, ale jeśli część z tego, co  opanujemy sprawi nam nieco radości, to było warto.

    Categories: migawka, Python

    Tworzenie prostej statycznej strony www w Azure

    No Comments

    Byłem ostatnio poproszony o przygotowanie małej prezentacji o historii informatyki.
    Wybrałem subiektywnie kilka tematów: m.in. program Apollo, początki inżynierii oprogramowania i walkę człowieka z maszynami grającymi w szachy i Go. Czy od czasu zwycięstwa nad Gari Kasparovem (lata 90-te XX wieku) przez Deep Blue nic się nie zmieniło?

    Wykorzystałem poniższą stronę:

    https://medium.freecodecamp.org/simple-chess-ai-step-by-step-1d55a9266977

    Podane w artykule repozytorium kodu w JavaScript przekopiowałem na własne konto

    https://github.com/djkormo/simple-chess-ai

    Postanowiłem na przykładzie chmury Azure pokazać krótką demonstrację.

    Ile linii kodu jest potrzebne na postawienie własnej strony www, która zagra z nami w szachy i która ma szanse nas pokonać.

    Wszystko to można zrobić z poziomu Portalu, postanowiłem zmierzyć się z problemem za pomocą Azure Cli 2.0.

    1.Wersja PaaS

    Ostatnią nowością jest możliwość postawienia statycznej strony www z poziomu konta magazynowego.

    2. Statyczna strona www w wersji preview na koncie storage.

    Od niedawna Azure pozazdrościł jednej z funkcjonalność AWS, czyli możliwość postawienia statycznej strony www na usłudze S3. Aktualnie znajduje się ona w wersji zapoznawczej.
    Trochę późno, ale nie ma co narzekać, jak widać konkurencja ma tu swoje dobre strony.

    Oficjalna dokumentacja producenta

    https://azure.microsoft.com/en-us/blog/azure-storage-static-web-hosting-public-preview/

    https://github.com/Azure/azure-cli-extensions/tree/master/src/storage-preview

     

    Nie ukrywam , że bardziej podoba mi się wersja PaaS, ale z niecierpliwością czekam na dalszy rozwój budowy statycznych stron www na bazie kont magazynowych. To czego mi najbardziej brakuje to proste podłączenie z repozytorium kodu, w którym umieścimy zawartość strony. Dodatkowo zauważyłem słabszą wydajność nowego rozwiązania, a wersja PaaS jest uruchomiona na darmowym planie.

    Strony do porównania

    1.PaaS

    https://mywebappchessai.azurewebsites.net/

    2. Statyczne www

    https://accountforstaticwebsite.z13.web.core.windows.net/

     

    Categories: Azure, migawka, PaaS