Python - Zajęcia 5

Python - Zajęcia 5
Photo by Lautaro Andreani / Unsplash

1) Gra papier, kamień, nożyce

import random

# Opcje gry
opcje = ("papier", "kamień", "nożyce")

# Powitanie i zasady
print("Witaj w grze 'Papier, Kamień, Nożyce'!")
print("Zasady są proste:")
print("0 - Papier pokonuje kamień")
print("1 - Kamień pokonuje nożyce")
print("2 - Nożyce pokonują papier")

print("Wybierz jedną z opcji:")
print("0: Papier")
print("1: Kamień")
print("2: Nożyce")


wybor_gracza = int(input("Twój wybór (0, 1, 2): "))

# Sprawdzenie Czy jest w zakresie 0, 1, 2
if wybor_gracza not in [0, 1, 2]:
    print("Błędny wybór! Wybierz liczbę 0, 1 lub 2.")
else:
    
    # Wybór komputera za pomocą random.choice
    wybor_komputera = random.choice(opcje)

    # Wyświetlenie wyborów gracza i komputera
    print(f"Twój wybór: {opcje[wybor_gracza]}")
    print(f"Wybór komputera: {wybor_komputera}")

    # Sprawdzenie wyniku
    if opcje[wybor_gracza] == wybor_komputera:
        print("Remis!")
    elif (opcje[wybor_gracza] == "papier" and wybor_komputera == "kamień") or \
         (opcje[wybor_gracza] == "kamień" and wybor_komputera == "nożyce") or \
         (opcje[wybor_gracza] == "nożyce" and wybor_komputera == "papier"):
        print("Gratulacje! Wygrałeś!")
    else:
        print("Przegrałeś! Spróbuj ponownie.")

Wybór komputera za pomocą random.choice.

2) Odpowiedź prowadzącego

import random

# Opcje gry
możliwości = ("papier", "nożyce", "kamień")

# Komunikat z instrukcją
print("""
Wprowadź swój wybór w postaci liczbowej:
0 - papier
1 - nożyce
2 - kamień
""")

# Umożliwiam graczowi wykorzystanie liczby
# będącej indeksem w liście możliwości
# - łatwiej wpisać cyfrę, niż słowo

wybor_gracza_indeks = int(input())

# W pierwszym kroku sprawdzam czy to co wpisał gracz ma sens
# jak nie - można od razu zakończyć
if wybor_gracza_indeks not in (0, 1, 2):
    print("Wpisałeś nieprawidłową liczbę.")
else:
    # Wykorzystuje indeks żeby pobrać wybór gracza z listy
    # pamiętając żeby zamienić string na int
    wybor_gracza = możliwości[wybor_gracza_indeks]
    print(f"Twój wybór: {wybor_gracza}")

    # losuje to co wybierze komputer
    wybor_komputera = random.choice(możliwości)
    print(f"Komputer wybrał: {wybor_komputera}")

    # porównanie wyborów gracza i komputera
    if wybor_gracza == wybor_komputera:
        print("Remis!")
    elif wybor_gracza == "nożyce" and wybor_komputera == "papier":
        print("Wygrana!")
    elif wybor_gracza == "papier" and wybor_komputera == "kamień":
        print("Wygrana!")
    elif wybor_gracza == "kamień" and wybor_komputera == "nożyce":
        print("Wygrana!")
    else:
        print("Przegrana :(")

3) Instalacja i dodanie biblioteki - korzystajmy z gotowców

Warto sprawdzić czy nasz problem nie został już rozwiązany przez kogoś innego. Jest szansa, że ktoś będzie chciał podzielić się rozwiązaniem. Jedną z najmocniejszych stron Pythona jest duża biblioteka gotowych modułów. Część z nich jest dostarczana razem z standardową instalacją Pythona.

Chcąc użyć wybranego gotowca w danym pliku z naszym programem musimy go zaimportować. Należy to zrobić gdzieś na początku pliku (zazwyczaj umieszcza się importy na samej górze) poprzez wstawienie:

import nazwa_biblioteki
import turtle

Jeśli danej biblioteki nie ma na naszym komputerze (a widzimy, że jest np. na PyPI) to najprościej jest ją zainstalować poprzez wykonanie w terminalu:

pip install nazwa_modulu

Inne możemy pobrać z zewnętrznych źródeł np. https://pypi.org/

Można budować kod jak z klocków. Gotowce mogą oszczędzić masę pracy i czasu. Importowanie bibliotek rozwiązujących trywialne problemy to zła praktyka.

4) Podgląd funkcji w bibliotece

Żeby podejrzeć szczegóły biblioteki można nacisnąć lewy ctrl i kliknąć lewy przycisk myszy.

5) Pętla for

Pętla for jest narzędziem pozwalających wykonać coś tyle razy ile jest elementów. Dzięki niej możemy wykonać blok kodu dla każdego elementu w kolekcji.

for element in kolekcja:
owoce = ["jabłko", "banan", "wiśnia"]
for owoc in owoce:
    print(owoc)
    
Wynik:
jabłko
banan
wiśnia

Ważne jest wcięcie. Oznaczają one blok kodu, który zostanie wykonany w pętli (coś co chcemy powtórzyć wiele razy).

6) Ćwiczenia

a) wyświetl kolejne elementy listy, następnie komunikat o zakończeniu

moja_lista = [1, 2, 3, 4, 5]

for element in moja_lista:
print(element)
print("Zakończono wyświetlanie elementów listy")

b) wyświetl klucze słownika

moj_slownik = {"a": 1, "b": 2, "c": 3}

for element in moj_slownik:
print(element)

Wynik:
a b c
moj_slownik = {"a": 1, "b": 2, "c": 3}

for element in moj_slownik:
print(element)
print(moj_slownik[element])

Wynik:
a 1 b 2 c 3

Jeżeli przemieszczamy się po słowniku to przemieszczamy się tylko po kluczach. Zamiast element możemy wpisać podłogę _.

moj_slownik = {"a": 1, "b": 2, "c": 3}

for _ in moj_slownik:
print("Hej!")

7) Metoda .items

moj_slownik = {"a": 1, "b": 2, "c": 3}
print(moj_slownik.items())

Wynik:
dict_items([('a', 1), ('b', 2), ('c', 3)])
for klucz, wartosc in moj_slownik.items():
    print(f"Klucz to: {klucz}")
    print(f"Wartosc to: {wartosc}")

Wynik:
Klucz to: a
Wartosc to: 1
Klucz to: b
Wartosc to: 2
Klucz to: c
Wartosc to: 3    

8) Dodatkowe pytanie

moja_lista = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]

for el1, el2 in moja_lista:
    print(el1)
    print(el2)

Wynik: błąd    
moja_lista = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]

for el1, el2, el3 in moja_lista:
    print(el1)
    print(el2)

Wynik: 
1
2
4
5
7
8   

W tym przypadku kod zakłada, że każdy element w moja_lista zawiera dokładnie dwa wartości. Jeśli moja_lista ma elementy składające się z trzech wartości (np. (1, 2, 3)), to Python wywoła błąd, ponieważ próbujesz przypisać trzy wartości do tylko dwóch zmiennych (el1 i el2).

Kiedy Python wykonuje rozpakowywanie (el1, el2 in moja_lista), wymaga, aby liczba zmiennych po lewej stronie odpowiadała liczbie elementów w każdej krotce lub liście po prawej stronie.

Jeśli moja_lista wygląda tak: moja_lista = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
To próbując rozpakować każdą krotkę (1, 2, 3) na dwie zmienne (el1 i el2), Python zgłosi błąd, ponieważ brakuje miejsca na trzecią wartość (3).

8) Przykłady

moja_lista = [2,3,4]
a = 1
print(f"Zmienna a ma teraz wartość {a}")

for liczba in moja_lista:
    a *= liczba  # Mnożenie zmiennej a przez element liczba z listy moja_lista
    print(f"Zmienna a ma teraz wartość {a}")

print(f"Zmienna a ma teraz wartość {a}")


Wynik:
Zmienna a ma teraz wartość 1
Zmienna a ma teraz wartość 2
Zmienna a ma teraz wartość 6
Zmienna a ma teraz wartość 24
Zmienna a ma teraz wartość 24
for i in range(3):
print(i, end=' ')

Wynik:
0 1 2

Range zaczyna od 0!

moja_lista = [2,3,4]
a = 1

for i in moja_lista:
    a *= i

print(a)

Wynik:
24

9) Moduł Turtle

Służy do proceduralnego (tzn. poprzez kod) rysowania kształtów na ekranie.

Stworzony w latach 60-tych. W podobny sposób działają np. maszyny sterowane numerycznie (CNC, np. frezarki). Bardzo ułatwia to zrozumienie działania pętli i programów nieco bardziej konstruowanych.

Turtle powinien być domyślnie zainstalowany z Pythonem. Jeśli go nie ma to dodajemy przez pip install turtle. A następnie zaimportowanie przez import turtle.

Potrzebujemy dodać na początku (gdzieś po imporcie), żebyśmy stworzyli przestrzeń do pracy naszego żółwia:

zolwik = turtle.Turtle()

A na koniec kodu, po narysowaniu tego co chcemy dodajemy opcje exitonclick , to powoduje, że okno z programem nie zamknie się po tym jak żółwik skończy rysować.

turtle.exitonclick()

Do sterowania potrzebujemy następujących metod:

  • .forward(odległość) - przesuwa żółwika do przodu
  • .left(kąt) - żółwik skręca w lewo o podany kąt
  • .right(kąt) - skręca w prawo o podany kąt
  • .circle(promień) - rysuje okrąg o podanym promieniu
  • .penup() - żółwik przemieszcza się przestając zostawiać ślad
  • .pendown() - ponownie zacznie rysować
  • .speed() - jeśli uznamy że żółwik jest za wolny / za szybki (Wartość od 1 do 10)
  • .shape() z parametrem "turtle" - żeby zamiast strzałki pojawił się żółwik
  • .pencolor() - zmienia kolor kreski
  • .pensize() - zmienia grubość kreski

Budowa kodu:

import turtle

zolwik = turtle.Turtle()
zolwik.speed(5)
zolwik.shape("turtle")

turtle.exitonclick()

10) Rysowanie kwadratu

import turtle
zolwik = turtle.Turtle()
zolwik.speed(5)
zolwik.shape("turtle")

zolwik.forward(100)
zolwik.right(90)
zolwik.forward(100)
zolwik.right(90)
zolwik.forward(100)
zolwik.right(90)
zolwik.forward(100)
zolwik.right(90)

turtle.exitonclick()

Można prościej używając pętli:

import turtle
zolwik = turtle.Turtle()
zolwik.speed(2)
zolwik.shape("turtle")

for _ in range(4):
    zolwik.forward(100)
    zolwik.right(90)

turtle.exitonclick()

Wynik:

11) Rysowanie Hex

import turtle

zolwik = turtle.Turtle()
zolwik.speed(2)
zolwik.shape("turtle")

for _ in range(6):
    zolwik.forward(100)
    zolwik.right(60)

turtle.exitonclick()

12) Rysowanie wielokąta

import turtle
zolwik = turtle.Turtle()
zolwik.speed(2)
zolwik.shape("turtle")

ilosc_katow = 10
kat_skretu = 360 / ilosc_katow

for _ in range(ilosc_katow):
    zolwik.forward(100)
    zolwik.right(kat_skretu)

turtle.exitonclick()

13) Rysowanie kwadratu i koła

import turtle  
zolwik = turtle.Turtle()  
zolwik.speed(2)  
zolwik.shape("turtle")  

zolwik.circle(50)  
zolwik.penup()  
zolwik.forward(100)  
zolwik.pendown()  

ilosc_scianek = 4  
kat_skretu = 360 / ilosc_scianek  

for _ in range(ilosc_scianek):  
    zolwik.forward(100)  
    zolwik.left(kat_skretu)  

turtle.exitonclick()

14) Rysowanie kółek połączonych

import turtle  
zolwik = turtle.Turtle()  
zolwik.speed(6)  
zolwik.shape("turtle")  

for _ in range(4):  
    zolwik.circle(40)  
    zolwik.penup()  
    zolwik.forward(60)  
    zolwik.pendown()  

zolwik.hideturtle()  
turtle.exitonclick()

15) Rysowanie kwiatka

import turtle  
zolwik = turtle.Turtle()  
zolwik.speed(6)  
zolwik.shape("turtle")  

for _ in range(6):  
    zolwik.circle(100)  
    zolwik.left(60)  

zolwik.hideturtle()  
turtle.exitonclick()

16) Rysowanie rozety z dowolna ilością kółek

import turtle  
zolwik = turtle.Turtle()  
zolwik.speed(6)  
zolwik.shape("turtle")  

ilosc_kolek = 6  
kat_obrotu = 360 / ilosc_kolek  

for _ in range(ilosc_kolek):  
    zolwik.circle(100)  
    zolwik.left(kat_obrotu)  

zolwik.hideturtle()  
turtle.exitonclick()

17) Rysowanie - zadanie domowe i wspólne

Rysowanie krzyża - 1

import turtle
zolwik = turtle.Turtle()
zolwik.speed(5)
zolwik.shape("turtle")

dlugosc = 50

zolwik.left(90)
zolwik.forward(dlugosc)
zolwik.right(90)
zolwik.forward(dlugosc)
zolwik.right(90)
zolwik.forward(dlugosc)

zolwik.left(90)
zolwik.forward(dlugosc)
zolwik.right(90)
zolwik.forward(dlugosc)
zolwik.right(90)
zolwik.forward(dlugosc)

zolwik.left(90)
zolwik.forward(dlugosc)
zolwik.right(90)
zolwik.forward(dlugosc)
zolwik.right(90)
zolwik.forward(dlugosc)

zolwik.left(90)
zolwik.forward(dlugosc)
zolwik.right(90)
zolwik.forward(dlugosc)
zolwik.right(90)
zolwik.forward(dlugosc)

turtle.exitonclick()
import turtle
zolwik = turtle.Turtle()
zolwik.speed(5)
zolwik.shape("turtle")

dlugosc = 50

for _ in range(4):
    zolwik.left(90)
    zolwik.forward(dlugosc)
    zolwik.right(90)
    zolwik.forward(dlugosc)
    zolwik.right(90)
    zolwik.forward(dlugosc)

turtle.exitonclick()

Rysowanie rozety z kwadratów - 2

import turtle  
zolwik = turtle.Turtle()  
zolwik.speed(5)  
zolwik.shape("turtle")  

ilosc_kwadratow = 20
dlugosc = 100

for _ in range(ilosc_kwadratow):  
    for _ in range(4):  
        zolwik.forward(dlugosc)  
        zolwik.right(90)  
    zolwik.left(360 / ilosc_kwadratow)  

zolwik.hideturtle()  
turtle.exitonclick()

Rysowanie kwadratu z kwadratami - 3

import turtle
zolwik = turtle.Turtle()
zolwik.speed(8)
zolwik.shape("turtle")

ilosc_powtorzen = 6
dlugosc_boku = 60

for _ in range(ilosc_powtorzen):
    for _ in range(4):
        zolwik.forward(dlugosc_boku)
        zolwik.right(90)
    dlugosc_boku += 15

zolwik.hideturtle()
turtle.exitonclick()

18) Rysowanie - kolumny

import turtle

zolwik = turtle.Turtle()
zolwik.speed(5)
zolwik.shape("turtle")

ilosc_slupkow = 5
szerokosc_podstawy = 60

for i in range(ilosc_slupkow):
    for _ in range(2):
        zolwik.forward(szerokosc_podstawy)
        zolwik.left(90)
        zolwik.forward(szerokosc_podstawy * (i + 1))
        zolwik.left(90)
    zolwik.penup()
    zolwik.forward(szerokosc_podstawy)
    zolwik.pendown()