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 ja 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.

    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
    
    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

    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]:

    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

     

    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
    

    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

    Moja metodyka zdawania egzaminów certyfikacyjnych Azure

    No Comments

    W dniu dzisiejszym (22.06.2018) udało się zdać z pozytywnym wynikiem jeden z egzaminów Microsoftu dotyczących chmury publicznej Azure

    Chciałbym podzielić się z wami moim doświadczeniem dotyczącym efektywnego przyswojenia wiedzy potrzebnej do takiego wyzwania.

    To z czego korzystam:

    1. Oficjalna strona egzaminu

    https://www.microsoft.com/en-us/learning/exam-70-473.aspx

    Tu należy zwracać uwagę na zmiany, które od czasu do czasu są wprowadzane przez producenta, ma to też wpływ na wybór kursu online.

     

    2. Kurs wideo

    W tym przypadku był to:

    https://www.udemy.com/70473-azure/learn/v4/overview

    Lectures: 69
    Video: 4.5 hours
    Skill level: Intermediate Level

    Prawie 5 godzin, ale taki kurs daje przegląd usług, które są w zakresie egzaminacyjnym, nie zastąpi w żaden sposób ćwiczeń, które utrwalą wiedzę. Te ćwiczenia moim zdaniem są najważniejszym elementem przygotowywania do opanowania zakresu, który nie jest taki mały, jak mi się na początku wydawało, w szczególności dla osób, które dopiero zaczynają poznawać technologie dookoła silnika SQL. Jeżeli są tu braki należy je nadrobić, ale nie w zakresie skompilowanych zapytań t-sql. Tu znajdziemy głównie konfiguracje administratorskie, nadawanie uprawnień, zagadnienia bezpieczeństwa, kopie zapasowe, import i eksport danych i metadanych, itp.

     

    Ćwiczenia wykonuję z poziomu Portalu, PowerShella i Azure CLI 2.0 (az).

    3. Przegląd dokumentacji Microsoftu

    Dokumentacja Microsoftu jest bardzo obszerna. Zapewne nie jestem pierwszą osobą, która taki egzamin zdaje, więc istnieje możliwość, że ktoś wcześniej dokonał już wyboru dokumentacji, kursów i wpisów na blogu.

    Przykładem jest strona www.mssqltips.com

    https://www.mssqltips.com/sqlservertip/4913/exam-material-for-the-microsoft-70473-designing-and-implementing-cloud-data-platform-solutions/

    W przypadku 70-473 znalazłem również stronę:

    Exam 70-473 – Designing and Implementing Cloud Data Platform Solutions

     

    Na te materiały należy oczywiście spojrzeć krytycznie pod kątem aktualności względem zmian wprowadzanych cyklicznie przez Microsoft.

    3. MVA Microsoftu

    https://mva.microsoft.com/en-us/training-courses/certification-exam-overview-70473-designing-and-implementing-cloud-data-platform-solutions-17402

    Nie polecam, znajdują się tam często przestarzale treści, ale to też w zależności od egzaminu.

     

    4. Portale społecznościowe

    W chwilach desperacji zawsze można zadać pytanie na grupie na Facebooku Microsoft Azure User Group Poland

    Polscy MVP z obszaru Azure chętnie odpowiedzą.

    5. Nauka cykliczna

    Cykliczne powtórki treści, które wymagają zapamiętania. Parametry poszczególnych maszyn wirtualnych  (liczba rdzeni, wielkość pamięci), wielkości baz danych w poszczególnych planach, jest tego trochę.

    Korzystam z ANKI

    6. Uwagi końcowe

    Można też wykupić przykładowe zestawy pytań, ale to radzę robić z dużą ostrożnością. Uczenie się na pamięć jest drogą na skróty, a tak przyswojona wiedza wyparuje szybciej niż myślimy. A przecież głównym celem zdania egzaminu powinno być potwierdzenie, że to czego nauczyliśmy się w praktyce pozwala na zamknięcie pewnego zakresu kompetencyjnego, a nie kolejny znaczek lub wydrukowany dokument.

     

    Są też dostępne dumpy  z pytaniami na rożnych stronach, ale tu radzę, jeśli już chcemy z nich koniecznie korzystać, weryfikować każdą poprawną odpowiedź. Bez ćwiczeń, o czym wspomniałem już wcześniej nie obędzie się, wiem, bo je próbowałem oglądać. Strata czasu..

    Nie należy stresować się brakami w wiedzy “on-premise”, jeśli tak się zdarzy, to pytam mądrzejszych. Ważne, by czas poświęcony nauce był dla nas intelektualnym wyzwaniem, nie należy też przesadzać z intensywnością. Pamiętajmy o celu.

    Chmura publiczna jest doskonałym zestawem usług, gdzie w ramach wirtualnej serwerowni możemy sami zbudować rozwiązanie end2end.

     

    Mały dodatek.

    Egzaminy z Azure proponuję zacząć od 70-533

    Zgodnie z informacją

    There are exam updates effective as of March 29, 2018. To learn more about these changes and how they affect the skills measured, please download and review the Exam 533 change document.

    Uważajcie na zmiany.

    Ja zacząłem od https://www.mssqltips.com/sqlservertip/4853/exam-material-for-the-microsoft-70533–implementing-microsoft-azure-infrastructure-solutions/

    Kurs na Udemy.

    https://www.udemy.com/70534-azure/learn/v4/content

    By the numbers
    • Lectures: 238
    • Video: 16 hours
    • Skill level: Intermediate Level

    Dodatkowo na githubie mam forkowane repozytoria:

    https://github.com/djkormo/Exam-70-533-Azure

    https://github.com/djkormo/microsoft-exam-prep-70533

    Trzeba dużo czytać, ale radzę omijać dokumentację z czasów Windows Azure, potem polecam przeklikać zakres w Portalu Azure.

    Trochę pracy ze skryptami w PowerShellu.

     

    Categories: Azure, chmura

    Azure Hacking – logowanie CLI za pomocą service principala

    No Comments

    Od kiedy zainteresowałem się chmurą Microsoft Azure początkowe kroki skierowałem do Portalu.

    Postawiłem kilka maszyn wirtualnych, strony www, proste funkcje. Następnie spróbowałem  przygotować to samo bez jednego kliknięcia myszą. Do wyboru miałem Powershell i moduł az CLI 2.0 napisany w Pythonie. Wybrałem az.

    Pierwsza linia kodu skryptu powołującego chmurową infrastrukturę wyglądała tak.

    Pojawia się wtedy komunikat

    To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code CCJULN8F8 to authenticate.

    Za pomocą podanej strony i kodu autoryzacyjnego muszę wskazać użytkownika , a potem wpisać hasło.

    Co zrobić, jeśli chciałbym uniknąć podawania za każdym razem hasła administratora subskrypcji i stworzyć techniczny byt, który pozwoli na wielokrotne uruchamianie np. skryptu wdrożeniowego, oczywiście bez interakcji z wyskakującymi oknami.

    Poniżej przedstawiam prosty sposób na skorzystanie z service principala

     

    Składnia

    Jak widać potrzebne nam będą trzy identyfikatory.

    Zacznijmy od TENAND_ID.

    Wybieramy menu  Azure Active Directory i zakładkę Properties

    azure_sp_1

    To, co widzimy w miejscu Directory ID to nasz TENAND_ID. Kopiujemy i zapisujemy sobie na boku.

    Pozostałe dwa identyfikatory wymagają stworzenia aplikacji.

    Zmieniamy zakładkę Properties na App registrations.

    Tworzymy nową aplikację typu Web app/API. Swoją nazwałem deployer. Adres url nie ma znaczenia w naszym zastosowaniu, wpisujemy dowolną wartość.

    azure_sp_2

     

    Po utworzeniu aplikacji mamy dostęp do identyfikatora APP_ID

    azure_sp_3

    Kopiujemy Application ID i zachowujemy  w tym samym miejscu co TENANT_ID.

    Czas na ostatni identyfikator, czyli KEY. Wchodzimy na zakładkę Keys.

    Tworzymy nowy klucz o nazwie np. KeyOne i terminie wygaśnięcia za jeden rok, pole Value zostanie wypełnione po zapisaniu klucza

    azure_sp_4

    W tym momencie powinniśmy skopiować wartość klucza. Jest to operacja jednorazowa. Portal o tym uczciwie przypomina. Klucz oczywiście można skasować i wygenerować kolejny.

    azure_sp_5

    Mamy już trzy identyfikatory. Co dalej ?

    Spróbujmy połączyć się do subskrypcji z poziomu linii komend.

    Po zalogowaniu się pojawi się zwrotny komunikat w postaci JSON

     

    Podanie błędnych danych kończy się małą katastrofą z kodem 401.

    Spróbujmy stworzyć nową grupę zasobów

    Pojawił się komunikat.

    Brakuje uprawnień dla naszej aplikacji i słusznie.

    Nadajmy uprawnienia dla aplikacji na poziomie subskrypcji.

    Dodajemy z poziomu zakładki Access control [IAM] uprawnienia Contributor dla całej subskrypcji.

    azure_sp_6

    Uruchamiamy ten sam kod i teraz mamy już komunikat zwrotny

    Wchodzimy na zakładkę Activity Log naszej nowej grupy zasobów i widać, kto i kiedy utworzył zasób.

    azure_sp_7

     

    Usuwamy grupę zasobów

    To samo można zrobić z poziomu CLI bez korzystania z Portalu, ale o tym innym razem…..

     

    Literatura:

    https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal

    https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?toc=%2Fazure%2Fazure-resource-manager%2Ftoc.json&view=azure-cli-latest

     

     

    Categories: Azure, chmura, migawka, Python

    Zabawa z IoT na platformie Azure

    1 Comment

    1. Zakup urządzenia
    Wg producenta jest to
    Moduł WiFi oparty na układzie ESP8266. Na pokładzie znajduje się 9 portów GPIO z obsługą I2C i SPI, wejście analogowe oraz złącze baterii lipol 3,7 V. Posiada oprogramowanie NodeMCU, które wspiera język skryptowy Lua lub środowisko Arduino IDE. Dodatkowym atutem jest wbudowany konwerter napięć na liniach interfejsu UART.
    Czyli skrócie dostajemy gotowe urządzenie, które potrafi się komunikować po WIFI i ma możliwość podłączania dodatkowych czujników m.in. temperatury i wilgotności.

    esp8266_1

    2. Konfiguracja IoTHub na platformie Azure

    Wybieramy menu “wszystkie zasoby”

    azure_iot_1

    Z kategorii Internet of Things wybieramy IoT Hub i wypełniamy podstawowe parametry, unikalną nazwę, grupę zasobów i lokalizację. Na początek proponuję zacząć od planu darmowego F1, ale jeśli planujemy coś bardziej poważnego, to w chwili obecnej nie ma możliwości podniesienia planu usługi. Można tylko postawić kolejna usługę. Wstaje ona po kilku minutach.

     

    azure_iot_2

     

    Po wygenerowaniu kluczy z polisy iothubowner możemy przejść do rejestracji naszych urządzeń

    Device ID: Nazwa urządzenia. Unikalna w ramach IoT huba, wielkie i male litery maja znaczenie

    Authentication Type: Pozostawiamy Symmetric Key.

    Auto Generate Keys: Pozostawiamy zaznaczone (zostaną automatycznie wygenerowanie klucze).

    Connect device to IoT Hub: Pozostawiamy Enable.

    azure_iot_3

     

    Każde z urządzeń będzie mieć wygenerowane dwa klucze.

    azure_iot_4

    Konfiguracja połączeń w tym przypadku wygląda tak

     

    I tę konfigurację będziemy wykorzystywać podczas pracy z urządzeniem. W ten sposób Hub wie, z jakiego urządzenia nadchodzą dane z czujników.

    Jeżeli nasz hub nazwałem djkormohub to warto sprawdzić połączenie sieciowe na porcie 8883

    3. Instalacja oprogramowania Arduino
    Adres instalatora
    https://www.arduino.cc/en/Main/Software
    W momencie pisania artykułu jest to wersja 1.8.5.

    arduino_1

    arduino_2

    Pojawi się grupa  pytań wymagających potwierdzenia instalacji sterowników “Arduino”arduino_5 arduino_6

    Instalacja została zakończona.

    4. Konfiguracja Visual Studio Code

    Potrzebny będzie dedykowany plugin do Arduino. Plugin ten nie zadziała bez instalacji  oprogramowania z punktu 3).

    Adres pluginu
    https://marketplace.visualstudio.com/items?itemName=vsciot-vscode.vscode-arduino

    vsc_1

     

    Po instalacji pluginu proponuje restart VSC. U mnie bez tego nie były możliwe dalsze kroki.

    Zaczynamy od konfiguracji dla ESP8266.

    Podlączyłem urządzenie po USB, pojawił się komunikat

    vsc_3

    -> Arduino: Boar Manager.

    vsc_2Naciskamy aditional Urls. Wstawiamy w pliku User Settings .json adres

    vsc_4

    Wybieramy w polu “filter your search” esp8266.

    Wybrałem ostatnią wersje stabilną, czyli 2.4.0 i przycisk install. Po krótkiej chwili skończyło się to tak:

    Ups…
    Bez chwili namysłu wybrałem starszą wersję 2.3.0. Udało się

    A poźniej zrobiłem upgrade. W ten sposób mam działającą wersje 2.4.0.

    Uruchamiamy Arduino:Board Config

    vsc_5

    To czego nam brakuje to bibioteki do obsługi naszego IoTHuba w Azure i nie tylko

    Uruchamiamy Arduino: Librany Manager i instalujemy bibioteki

    AzureIoTHub
    AzureIoTUtility
    AzureIoTProtocol_MQTT
    ArduinoJso
    DHT sensor library
    Adafruit Unified Sensor

    vsc_6

    Oprogramowanie do pracy z płytką zostało zinstalowane. Czas na prosty przykład. Pobieram z githuba, gotowy projekt przygotowany przez Microsoft.

    Ponieważ, nie mam jeszcze czujnika DTH22 (temparatura i wilgotność) wykorzystam możliwość symulacji jego zachowania.
    W pliku config.h należy zmienić linię kodu odpowiedzialną za nią

    Otwieramy w VSC plik app.ino.

    Spróbujmy zapisać oprogramowanie na urządzeniu
    Uruchamiamy Arduino:Upload i po wybraniuy portu komunikacyjnego pojawi się po chwili następujący komunikat.

    Kolejne ups ?

    Po krótkim wykorzystaniu wujka Google trafiłem na rozwiązanie. Należy zainstalować brakujące oprogramowanie w podkatalogu hardware Arduino.

     

    Log z instalacji

    Restartujemy Arduino.

    Instalujemy obraz z poziomu Arduino (VSC nadal poprawnie nie działa).

    arduino_7

    Zwróćcie uwagę na migająca niebieską diodę podczas zapisywania oprogramowania.

    Oprogramowanie wgrane, teraz należy podłączyć urządzenie do naszej sieci WIFI.

    Po podaniu nazwy sieci WIFI (SSID) , hasła (PASS) i konfiguracji połączenia naszego urządzenia do IotHuba w postaci

    Urządzenie uruchamia się:

    Widać, że urządzenie podłączyło się do sieci bezprzewodowej i próbuje wystać komunikat w postaci

    Urządzenie ESP_*  jest widoczne od strony rutera WIFI, otrzymało przez DHCP swój adres IP.

    asus_1

    Włączyłem opcje debugowania i mam taki wyciąg z logów

     

    Problematyczne okazało się żle skonfigurowany DNS i urządzenie nie potrafiło ustalić adresu IP huba. IP 10.0.0.1 to lokalny adres rutera mojego dostawcy internetu.

    Po naprawie konfiguracji w logach monitora zaczęły pojawiac sie komunikaty

    Zweryfikowałem metryki diagnostyczne usługi w Azure. Pojawiły się pierwsze komunikaty.

    azure_iot_5

    W darmowym planie F1 mamy do wykorzystania 8000 komunikatów na dobę, jeśli dobrze oszacowałem oznacza to jeden komunikat co 11 sekund. Do prostych pomiarów jest to wystarczające.

     

    Categories: Arduino, Azure, IoT

    Uniwersalna procedura aktywacyjna Service Brokera

    No Comments

    Usługa Service Brokera, która pojawiła się wraz z wersja 2005 zadziwia mnie do tej pory.
    Od wielu lat producent niewiele w niej zmienia, co może świadczyć o dobrze przemyślanej architekturze.
    Z drugiej strony monitoring tej usługi dostarczony przez producenta pozostawia wiele do życzenia patrząc na to nawet z ergonomicznego puntku widzenia. Walka z wyłączającymi się kolejkami i komunikatami typu poison spędziła nie jeden sen z powiek. Jak sobie z tym najlepiej poradzić ?
    Zakładam, że czytelnik zna podstawową budowę Service Brokera i ma doświadczenie w jego stosowaniu w warunkach produkcyjnych. To o czym należy pamiętać, to świadomość, że wbudowano w serwer bazodanowy mechanizm, który potrafi obsłużyć za pomocą języka t-sql komunikację asynchroniczną bez pomocy zewnętrznych narzędzi. To niewątpliwie wielki plus funkcjonalny.
    Chciałbym skoncentrować się nad propozycją budowy szkicu uniwersalnej procedury aktywacyjnej, która obsługuje kolejkę targetową.
    Dokumentacja Microsoftu sprowadza się do budowy dedykowanej per kolejka procedury aktywacyjnej, gdzie spore fragmenty kodu są powtarzane i jest to nieco niezgodne z podejściem DRY.
    Przyjęte założenia:
    1. Przekazywane są jedynie komunikaty w formie XML
    2. Każdy typ komunikatu XML na podstawie jego root elementu będzie obsługiwany przez dedykowaną procedurę składowaną
    3. Każda z takich procedur ma standardową postać

    4. Wszystkie obiekty bazodanowe są obrębie jednej bazy.
    5. Wykorzystany zostanie dynamiczny sql.
    6. Procedura przyjmie minimalną liczbę argumentów i stanie się wewnętrzną procedurą aktywacyjną każdej z kolejek targetowych.

    Proponowany nagłówek:

    Powiązanie uniwersalnej procedury aktywacyjnej z przykładową kolejką

    Niech nasza kolejka nazywa się SampleTargetQueue.

    Przygotowujemy procedurę nakladkową definiowaną per kolejka

    Powiązanie kolejki docelowej z tak przygotowaną procedurą aktywacyjną.

    Szkic funkcjonalny uniwersalnej procedury aktywacyjnej

    1. Pobranie z kolejki pierwszego komunikatu XML

    2. Na podstawie root elementu XML ustalenie nazwy procedury składowanej odpowiedzialnej za logikę biznesową

    Proponowany kod transformacji :

    W tym przypadku wyznaczamy wartość nazwy procedury składowanej jako
    spInterfaceAccountV5getNumberGetAccountNumber

    3. Obsłużenie sytuacji wyjątkowych, komunikatów typu poison, XML-i niezgodnych ze schema parametru wejściowego procedury składowanej, wyłączonej kolejki, naruszenia więzów integralność.
    4. Wszystkie powyższe punkty powinny być realizowane w ramach jednej transakcji

    5. Zalogowane komunikaty błędów trafiają do jednej wspólnej tabeli.
    Propozycja takiej wspólnej tabeli

    Przykładowy fragment kodu uzupełniającego tabelę w przypadku wystąpienia błędu:

    Znaczenie pola status:

    wartość znaczenie czy do ponownego przetworzenia
    0 nowy wpis TAK
    1 wpis przetworzony z sukcesem NIE
    2 wpis przetworzony z błędem TAK
    3 nie wymaga przetworzenia NIE

     

    Proste zapytanie monitorujące błędne wpisy w tabeli

    Należy dodatkowo wprowadzić politykę retencji, gdzie po ustalonej liczbie dni, dane powinny być usuwane trwale, w szczegolności tam, gdzie status wskazuje na brak potrzeby ponownego przetworzenia.

     

     

    Literatura

    Configuring Service Broker for Asynchronous Processing

     

    Categories: implementacja, t-sql

    Hacking Azure – PoIaaS model

    3 komentarze

    Pierwszy wpis na blogu dotyczący chmury publicznej Microsoftu Azure.

    Każdy młody adept  Azure  spotyka się na początku z różnymi modelami obsługi zasobów w chmurze. Zgodnie z poniższym rysunkiem.

    https://social.technet.microsoft.com/wiki/cfs-filesystemfile.ashx/__key/communityserver-wikis-components-files/00-00-00-00-05/5482.sec_2D00_cloudstack.png

    To, co na zielono kontroluje Microsoft, a to co na niebiesko właściciel subskrypcji, czyli w dużym uproszczeniu, ja. Jak u każdego chlopca, który krzyczy po raz pierwszy “Ja sam, ja sam!”.

    Rozpocząłem klasycznie od  lewej strony, czyli postawiłem kilka maszyn wirtualnych, Najpierw z poziomu portalu, a potem za pomocą Azure CLI 2.0, od czasu do czasu Azure Cloud Shell był pomocny. Skoncentrowałem swoje działania wokół dystrybucji Ubuntu , na której w finalnym instalowałem Midnight Commandera. Prześmiewcom tego pakietu powiem tylko tyle ze linuxa używam wcześniej niż pojawiła się dystrybucja RedHata 4.0. To taka sentymentalna podróż do czasów produktów Petera Nortona. Następnie skoncentrowałem się na modelu PaaS, gdzie  poznawałem bazy danych i usługi pod strony www.

    Dziś chciałbym opowiedzieć o jednej z nich: App Service on Linux

    Instalację wykonałem zgodnie z

    https://github.com/djkormo/azurewordpress

    Z tym, że jako bazę mysql wykorzystałem usługę Azure datatabase for Mysql

    .mywordpressaspaas_1

     

    Konfiguracja po stronie WordPressa wymagała ustawienia czterech zmiennych środowiskowych, zgodnie z zapisem w pliku
    wp_config.php

    Po stronie aplikacji wyglądało to tak:
    mywordpressaspaas_2

    Nie jest to bardzo bezpieczne, ale na Proof of Concept na początek wystarczy.

    Po zainstalowaniu kodu WordPressa pobranego z repozytorium na Githubie pokazała się ładna strona. Dowolna zmiana w kodzie repo powoduje uruchomienie wdrożenia zmian.

    Po konfiguracji oprogramowania  możemy się pochwalić stroną startową.

    mywordpressaspaas_3

    Udało się. Pierwsza strona www z obsługa PHP i Mysql została uruchomiona. Chciałem sprawdzić,  jakie są dalsze możliwości konfiguracyjne, a przy okazji dowiedzieć się co właściwie jest pod spodem, np. z którą dystrybucją linuxa mamy do czynienia.  Uwaga!. To jest ta część kontrolowana przez dostawcę usług, czyli przez Microsoft.

    Wykorzystałem w tym celu wbudowane w usługę narzędzie KUDU . Gorąco polecam.

    Uruchomienie to zakładka Advanced Tools -> go.

    A potem z poziomu KUDU uruchomiłem SSH.

    mywordpressaspaas_4

    Jaka tam jest jest dystrybucja  ?

    Polecenie

    Linux 1c7503c5ac2b 4.4.0-112-generic #135-Ubuntu SMP Fri Jan 19 11:48:36 UTC 2018 x86_64 GNU/Linux

    Spróbowałem zainstalować na początku pakiet mc. Po wpisaniu polecenia

    system stwierdził, że nie znalazł pakietu, ale wystarczyło po chwili zastanowienia

    Sprawdziłem czy to działamywordpressaspaas_6

    Instalacja zakończyła się sukcesem.

    Weryfikacja ostateczna, to uruchomienie  pakietu.

    I naszym oczom ukazuje się znajomy interfejs programu.

    mywordpressaspaas_5

    Czy można zrobić upgrade pakietów systemu operacyjnego ?

    Zakończyło się bez błędu, ale z zerowym przebiegiem.

    I tu się zacząłem zastanawiać, co w jakim modelu stworzyłem moją stronę wordpressową ?  IaaS (mam dostęp do systemu operacyjnego), czy PaaS, a może model hybrydowy który tu roboczo nazywam PoIaaS. (Platform on IaaS) .

    Kolejne pytania, które się pojawiły:

    • W jaki sposób zachowa się system podczas autoskalowania? Czy kolejne “maszyny” wstaną z zainstalowanym mc czy bez?
    • Co jest wzorcem dla takie usługi ?
    • I kto zadba o zmiany w systemie operacyjnym ? Microsoft czy ja ?

    Sprawdzam, jakie procesy w są uruchomione:

    Zrobiłem już kilka eksperymentów i wiem …. Zrób i ty…. Odpowiedz na te trzy pytania.

    Pozdrawiam.

    Komentujcie…..

    Krzysztof Pudłowski

     

    Categories: Azure, chmura, IaaS, PaaS

    Generowanie losowych odpowiedników dla danych wrażliwych dla RODO . Część 3

    No Comments

    W poprzedniej części  przygotowaliśmy szkic  procedury składowanej implementującej prosty mechanizm wykrywania danych osobowych.

    To czego zabrakło, to wykorzystanie funkcji tabelarycznych  do wykrywania tych danych, które posiadają sumę kontrolną i same wyrażenia regularne mogą nie wystarczyć.

    Zajmijmy się   identyfikatorami PESEL, NIP, REGON. Zainteresowanych budową  takich identyfikatorów odsyłam do powszechnie dostępnych źródeł (m.in WIkipedia).

    Poniżej przedstawiono kod trzech prostych funkcji tabelarycznych napisanych w Transact SQL.

    PESEL

    NIP

    REGON

    Przykłady wywołania

    Wynik działania

     

    RAWPESEL PESEL isValid
    00000000001 00000000000 0

    RAWREGON REGON isValid
    000000001 000000000 0

    RAWNIP NIP isValid
    0000000001 0000000000 0

    Każda z tych funkcji jest zbudowana na podstawie tego samego schematu.
    Na poczatku pobieramy na wejściu danę do weryfikacji, następnie pobieramy cześć danych bez sumy kontrolnej i wyliczany na jej podstawie brakującą sumę kontrolną. Jeśli tak spreparowany identyfikator jest tożsami z wejściowym i dodatkowo składa się z samych cyfr, możemy uznać, ze mamy do czynienia z poprawnymi danymi. W ten sposón wyznaczana jest kolumna isValid.

    Jak można je zastosować ?

    Przydatne strony:

    http://walidator.testerzy.pl/

    http://zylla.wipos.p.lodz.pl/ut/nip-rego.html

    Categories: implementacja, RODO, t-sql