LEKCJA 10 – ZBIORY I REKORDY

 

Zbiory

Przejdźmy do trybu interaktywnego Pythona.

W Pythonie możemy tworzyć tak zbiory zmienne:

 

>>> A=set([1,2,3])

>>> A

set([1, 2, 3])

 

 jak i niezmienne:

 

>>> B=frozenset([2,3,4])

>>> B

frozenset([2, 3, 4])

 

Aby stworzyć zbiór pusty napiszemy:

 

>>> C=set()

>>> C

set([])

 

Zbiory zmienne mogą być powiększane i zmniejszane:

 

>>> A.discard(2)

>>> A

set([1, 3])

>>> A.add(5)

>>> A

set([1, 3, 5])

 

Zbiory niezmienne nie mogą być ani zmniejszane:

 

>>> B.discard(2)

 

Traceback (most recent call last):

  File "<pyshell#11>", line 1, in -toplevel-

    B.discard(2)

AttributeError: 'frozenset' object has no attribute 'discard'

 

ani powiększane:

 

>>> B.add(7)

 

Traceback (most recent call last):

  File "<pyshell#12>", line 1, in -toplevel-

    B.add(7)

AttributeError: 'frozenset' object has no attribute 'add'

>>>

Zbiory niezmienne mogą być kluczami w słownikach:

 

>>> d={B:7}

>>> d

{frozenset([2, 3, 4]): 7}

 

i elementami innych zbiorów:

 

>>> C.add(B)

>>> C

set([frozenset([2, 3, 4])])

 

Zbiory zmienne nie mogą być ani kluczami w słownikach:

 

>>> d={A:7}

 

Traceback (most recent call last):

  File "<pyshell#18>", line 1, in -toplevel-

    d={A:7}

TypeError: set objects are unhashable

 

ani elementami innych zbiorów:

 

>>> C.add(A)

 

Traceback (most recent call last):

  File "<pyshell#17>", line 1, in -toplevel-

    C.add(A)

TypeError: set objects are unhashable

 

Operacje na zbiorach

Aby ustalić liczbę elementów zbioru piszemy:

 

>>> len(A)

3

>>> len(B)

3

>>> len(C)

1

 

Aby sprawdzić, czy dany obiekt jest elementem zbioru, piszemy:

 

>>> 2 in A

False

>>> 2 in B

True

>>> 5 in A

True

>>> 5 in B

False

 

Aby sprawdzić, czy dany obiekt nie jest elementem zbioru, piszemy:

 

>>> 3 not in A

False

>>> 3 not in B

False

>>> 7 not in A

True

>>> 7 not in B

True

 

Aby sprawdzić czy dany zbiór jest podzbiorem innego piszemy:

 

>>> set([1,3])<=A

True

>>> set([3,4])<=B

True

>>> set([5])<=A

True

>>> set([1,3,5])<=A

True

 

Lub:

 

>>> A.issubset(B)

False

 

Aby sprawdzić czy dany zbiór jest nadzbiorem innego piszemy:

 

>>> A>=set([1,3])

True

>>> B>=set([3,4])

True

 

Lub:

 

>>> A.issuperset(B)

False

 

Aby połączyć dwa zbiory piszemy:

 

>>> D=A | B

>>> D

set([1, 2, 3, 4, 5])

 

Aby określić część wspólną dwóch zbiorów piszemy:

 

>>> E=A & B

>>> E

set([3])

 

Aby określić różnicę dwóch zbiorów piszemy:

 

>>> A-B

set([1, 5])

>>> B-A

frozenset([2, 4])

 

(Typ zbioru wynikowego jest typem pierwszego ze zbiorów.)

 

Aby określić różnicę symetryczną dwóch zbiorów piszemy:

 

>>> F=A^B

>>> F

set([1, 2, 4, 5])

 

Przykład programu wykorzystującego zbiory

Wykorzystując zbiory rozwiążemy teraz ćwiczenie II z lekcji 7:

„Napisz program „lotto.py”, który wyświetli 6 losowych i nie powtarzających się liczb z zakresu od 1 do 49.”

 

Aby przejść do edycji nowego programu należy z menu File wybrać polecenie New Window. Otworzy się nowe okno, przeznaczone do edycji programu. Wybierzmy z menu File polecenie Save As. Wybieramy folder Moje dokumenty, następnie wpisujemy nazwę lotto.py.

 

# program losuje 6 liczb od 1 do 49

from random import choice

Wylosowane = set()

while len(Wylosowane) < 6:

    Wylosowane.add(choice(range(1,50)))

for x in Wylosowane:

    print x,

 

Wypróbujmy (F5):

 

>>> ================================ RESTART =============================

>>>

1 36 8 22 24 29              

 

Rekordy

Aby używać rekordów, musimy wpierw zdefiniować ich klasę.

W Pythonie lista pól w rekordzie może ulec zmianie w trakcie działania programu.

Dlatego możemy zdefiniować klasę jako pustą:

 

>>> class Adres:

      pass

 

A następnie utworzyć rekord w tej klasie:

 

>>> a=Adres( )

 

I dowolnie go rozszerzać:

 

>>> a.ulica="Matejki"

>>> a.numer="14a/2"

>>> a.kod="71-128"

>>> a.miasto="Szczecin"

 

Aby poznać zawartość poszczególnych pól rekordu piszemy:

 

>>> a.ulica

'Matejki'

>>> a.numer

'14a/2'

>>> a.kod

'71-128'

>>> a.miasto

'Szczecin'

 

Oczywiście, odpowiednie pola muszą istnieć:

 

>>> a.panstwo

 

Traceback (most recent call last):

  File "<pyshell#148>", line 1, in -toplevel-

    a.panstwo

AttributeError: Adres instance has no attribute 'panstwo'

 

Aby poznać zawartość wszystkich pól rekordu piszemy:

 

>>> a.__dict__

{'numer': '14a/2', 'miasto': 'Szczecin', 'ulica': 'Matejki', 'kod': '71-128'}

 

Możemy także określić listę pól już  w momencie definiowania klasy, podając ich domyślne wartości:

 

>>> class Osoba:

      imie="Jan"

      nazwisko="Kowalski"

 

Aby stworzyć klasę opartą o inne klasy, podajemy je jako parametry:

 

>>> class Pracownik(Osoba, Adres):

      pensja=1000.00

 

Otrzymana klasa Pracownik będzie miała wszystkie pola klas Osoba i Adres, a dodatkowo pole pensja. Sprawdźmy:

 

>>> p=Pracownik()

>>> p2=Pracownik()

>>> p2.imie="Adam"

>>> p2.ulica="Torfowa"

>>> p2.pensja=700

>>> p.imie

'Jan'

>>> p.ulica

 

Traceback (most recent call last):

  File "<pyshell#3>", line 1, in <module>

    p.ulica

AttributeError: Pracownik instance has no attribute 'ulica'

 

>>> p.pensja

1000.0

>>> p2.imie

'Adam'

>>> p2.ulica

'Torfowa'

>>> p2.pensja

700

 

Trzeba przy tym pamiętać, że __dict__ zwraca słownik tylko tych pól, których wartości różnią się od domyślnych:

 

>>> p2.__dict__

{'imie': 'Adam', 'pensja': 700, 'ulica': 'Torfowa'}

>>> p.__dict__

{ }

Przykład – lista ocen studentów

Spróbujemy teraz napisać program, który posłuży do przechowania listy ocen studentów z egzaminu.

Aby przejść do edycji nowego programu należy z menu File wybrać polecenie New Window. Otworzy się nowe okno, przeznaczone do edycji programu. Wybierzmy z menu File polecenie Save As. Wybieramy folder Moje dokumenty, następnie wpisujemy nazwę studenci.py.

 

# Lista Ocen Studentów

class Student:

    imie=""

    nazwisko=""

    ocena=0.0

   

studenci = []

nr = 0

while True:

    naz=raw_input('Podaj nazwisko studenta nr %i (ENTER=koniec): ' % (nr+1))

    if not naz: break

    studenci.append(Student())

    studenci[nr].nazwisko = naz

    studenci[nr].imie = raw_input('Podaj imię studenta nr %i > ' % (nr+1))

    studenci[nr].ocena = float(raw_input('Podaj ocenę studenta nr %i > ' % (nr+1)))

    nr += 1

 

print

print "%-4s %-14s %-10s %7s" % ("L.p.","Nazwisko","Imię","Ocena")

for s in studenci:

    print "%3i. %-14s %-10s %7.1f" % (studenci.index(s)+1,s.nazwisko, s.imie, s.ocena)

 

Wypróbujmy (F5):

 

>>> ================================ RESTART =============================

>>>

Podaj nazwisko studenta nr 1 (ENTER=koniec): Adamczak

Podaj imię studenta nr 1 > Piotr

Podaj ocenę studenta nr 1 > 3.5

Podaj nazwisko studenta nr 2 (ENTER=koniec): Gierek

Podaj imię studenta nr 2 > Franz

Podaj ocenę studenta nr 2 > 2.0

Podaj nazwisko studenta nr 3 (ENTER=koniec): Hubert

Podaj imię studenta nr 3 > Anna

Podaj ocenę studenta nr 3 > 4.5

Podaj nazwisko studenta nr 4 (ENTER=koniec):

 

L.p. Nazwisko       Imię         Ocena

  1. Adamczak       Piotr          3.5

  2. Gierek         Franz          2.0

  3. Hubert         Anna           4.5

Ćwiczenia kontrolne

I.                   Zmień program „lotto” w taki sposób, by wyświetlał wylosowane liczby od najmniejszej do największej.

II.                Zmień program „lista studentów” w taki sposób, by dodatkowo obliczał średnią ocen wszystkich studentów