Programming-Python

Tasks studies - laboratory

View project on GitHub

Język skryptowy lab6

Wyrażenia regularne

Wyrażenia regularne są potężnym narzędziem do różnego rodzaju manipulacji ciągami znaków. Są obecne jako biblioteki w większości nowoczesnych języków programowania, a nie tylko w Pythonie. Są przydatne do dwóch głównych zadań:

  • sprawdzenie, czy ciągi są zgodne z wzorcem (na przykład, że ciąg ma format adresu e-mail),
  • wykonywanie podstawień w ciągu znaków (np. zmiana wszystkich pisowni amerykańskich na angielskie).

Do wyrażeń regularnych w Pythonie można uzyskać dostęp za pomocą modułu re, który jest częścią standardowej biblioteki. Po zdefiniowaniu wyrażenia regularnego można użyć funkcji re.match w celu ustalenia, czy pasuje ono do początku ciągu znaków. Jeśli tak, dopasowanie zwraca obiekt reprezentujący dopasowanie, jeśli nie, zwraca None. Inne funkcje do dopasowania wzorców to re.search i re.findall. Funkcja re.search odnajduje dopasowanie wzorca w dowolnym miejscu ciągu. Funkcja re.findall zwraca listę wszystkich podciągów pasujących do wzorca.

import re

pattern = r"spam"

if re.search(pattern, "ssspamspamspamsp"):
    print(re.search(pattern, "ssspamspamspamsp").span().__getitem__(1))
else:
    print("No mach")

Funkcja search zwraca obiekt za pomocą kilku metod, które podają szczegóły na jego temat. Te metody obejmują grupę, która zwraca dopasowany ciąg, początek i koniec, które zwracają pozycje początkową i końcową pierwszego dopasowania, i zakres, który zwraca pozycje początkową i końcową pierwszego dopasowania jako krotkę.

import re

pattern = r"pam"

match = re.search(pattern, "eggspamsausage")
if match:
   print(match.group())
   print(match.start())
   print(match.end())
   print(match.span())

Wyszukaj i zamień

Jedną z najważniejszych metod, które używają wyrażeń regularnych jest sub.

re.sub(pattern, repl, string, max=0)

Ta metoda zastępuje wszystkie wystąpienia pattern w łańcuchu za pomocą repl, zastępując wszystkie wystąpienia, chyba że podana jest wartość max. Ta metoda zwraca zmodyfikowany ciąg.

import re

str = "My name is David. Hi David."
pattern = r"David"
newstr = re.sub(pattern, "Amy", str)
print(newstr)

Metaznaki

Pierwszym metaznakiem, jest symbol . (kropka). Dopasowuje dowolny znak, z wyjątkiem znaku nowej linii.

import re

pattern = r"gr.y"

if re.match(pattern, "grey"):
   print("Match 1")

if re.match(pattern, "gray"):
   print("Match 2")

if re.match(pattern, "blue"):
   print("Match 3")

Następne dwa metaznaki to ^ i $. Dopasowują odpowiednio początek i koniec ciągu znaków.

import re

pattern = r"^gr.y$"

if re.match(pattern, "grey"):
   print("Match 1")

if re.match(pattern, "gray"):
   print("Match 2")

if re.match(pattern, "stingray"):
   print("Match 3")

Klasy znaków

Umożliwiają dopasowanie tylko jednego określonego zestawu znaków. Klasa znaków jest tworzona przez umieszczenie znaków, które pasują w nawiasach kwadratowych.

import re

pattern = r"[aeiou]"

if re.search(pattern, "grey"):
   print("Match 1")

if re.search(pattern, "qwertyuiop"):
   print("Match 2")

if re.search(pattern, "rhythm myths"):
   print("Match 3")

Wzorzec [aeiou] w funkcji wyszukiwania pasuje do wszystkich ciągów, które zawierają dowolny zdefiniowany znak.

Klasy postaci mogą również dopasowywać zakresy znaków. Kilka przykładów: Klasa [a-z] dopasowuje każdą literę alfabetu pisaną małymi literami. Klasa [G-P] dopasowuje dowolną wielką literę od G do P. Klasa [0-9] pasuje do dowolnej cyfry. W jednej klasie można uwzględnić wiele zakresów. Na przykład [A-Za-z] pasuje do litery dowolnego rozmiaru.

import re

pattern = r"[A-Z][A-Z][0-9]"

if re.search(pattern, "LS8"):
   print("Match 1")

if re.search(pattern, "E3"):
   print("Match 2")

if re.search(pattern, "1ab"):
   print("Match 3")

Umieść ^ na początku klasy postaci, aby ją odwrócić. Powoduje to, że pasuje on do dowolnego znaku innego niż te uwzględnione. Inne metaznaki, takie jak $ i., Nie mają znaczenia w obrębie klas znaków. Metaznak ^ nie ma znaczenia, chyba że jest pierwszym znakiem w klasie.

import re

pattern = r"[^A-Z]"

if re.search(pattern, "this is all quiet"):
   print("Match 1")

if re.search(pattern, "AbCdEfG123"):
   print("Match 2")

if re.search(pattern, "THISISALLSHOUTING"):
   print("Match 3")

Inne metaznaki to *,+,?,{ i }. Określają one liczby powtórzeń. Metaznak * oznacza zero lub więcej powtórzeń poprzedniego wzorca. Próbuje dopasować tyle powtórzeń, ile to możliwe. Poprzedni wzorzec może być pojedynczym znakiem, klasą lub grupą znaków w nawiasie.

import re

pattern = r"egg(spam)*"

if re.match(pattern, "egg"):
   print("Match 1")

if re.match(pattern, "eggspamspamegg"):
   print("Match 2")

if re.match(pattern, "spam"):
   print("Match 3")

Metaznak + jest bardzo podobny do *, z wyjątkiem tego, że oznacza jedno lub więcej powtórzeń.

import re

pattern = r"g+"

if re.match(pattern, "g"):
   print("Match 1")

if re.match(pattern, "gggggggggggggg"):
   print("Match 2")

if re.match(pattern, "abc"):
   print("Match 3")

Metaznak ? oznacza zero lub jedno powtórzenie.

import re

pattern = r"ice(-)?cream"

if re.match(pattern, "ice-cream"):
   print("Match 1")

if re.match(pattern, "icecream"):
   print("Match 2")

if re.match(pattern, "sausages"):
   print("Match 3")

if re.match(pattern, "ice--ice"):
   print("Match 4")

Nawiasy klamrowe

Za pomocą nawiasów klamrowych można reprezentować liczbę powtórzeń między dwiema liczbami. Wyrażenia regularne {x, y} oznaczają między x i y powtórzeń czegoś. Stąd {0,1} to to samo co ?. Jeśli brakuje pierwszej liczby, przyjmuje się, że wynosi zero. Jeśli brakuje drugiej liczby, przyjmuje się, że jest nieskończoność.

import re

pattern = r"9{1,3}$"

if re.match(pattern, "9"):
   print("Match 1")

if re.match(pattern, "999"):
   print("Match 2")

if re.match(pattern, "9999"):
   print("Match 3")

Django

Zanim zaczniesz

Upewnij się, że zostały spełnione następujące wymagania wstępne:

  • Pracujesz z PyCharm w wersji 2016.1 lub nowszej.
  • Masz co najmniej jednego interpretera języka Python poprawnie zainstalowanego na komputerze (Python 3.4.1. lub nowszy).
  • Masz zainstalowany pakiet Django (Django 1.10.0 lub nowszy). Aby dowiedzieć się, jak instalować pakiety za pomocą interfejsu użytkownika PyCharm, przeczytaj sekcję https://www.jetbrains.com/help/pycharm/installing-uninstalling-and-upgrading-packages.html

Tworzenie nowego projektu

Właściwie wszystkie nowe projekty są tworzone w ten sam sposób: klikając przycisk Create new project w obszarze Szybki start ekranu powitalnego: image

Następnie wybierz żądany typ projektu (tutaj jest Django). Określ nazwę i lokalizację projektu.

Najlepszą praktyką Pythona jest utworzenie virtualenv dla każdego projektu. Aby to zrobić, rozwiń węzeł Project Interpreter: New Virtualenv Environment i wybierz narzędzie używane do tworzenia nowego środowiska wirtualnego. Wybierzmy narzędzie Virtualenv i określ lokalizację oraz podstawowy interpreter używany w nowym środowisku wirtualnym.

Następnie rozwiń węzeł More Settings i określ ustawienia związane z Django. W polu Application name podaj nazwę aplikacji image

Kliknij Create - projekt Django jest gotowy.

Eksplorowanie struktury projektu

Gotowy projekt zawiera pliki i katalogi specyficzne dla frameworku. To samo dzieje się, gdy tworzony jest projekt dowolnego obsługiwanego typu, np. Pyramid lub Google App Engine.

Zobaczmy, jak struktura nowego projektu jest widoczna w oknie narzędzia projektu.

Widok plików projektu

Ten widok jest domyślnie wyświetlany. Pokazuje strukturę projektu Django: ankiety i katalogi mysite; zobacz także pliki manage.py i settings.py.

image

Struktura projektu

Co widzimy w widoku projektu?

  • Katalog DjangoApp jest kontenerem dla twojego projektu. W widoku projektu oznaczono go pogrubioną czcionką.
  • manage.py: To narzędzie wiersza polecenia, które pozwala na interakcję z projektem Django. Szczegółowe informacje w dokumentacji Django.
  • Zagnieżdżony katalog DjangoApp jest aktualnym pakietem Pythona dla twojego projektu.
  • DjangoApp/__init__.py: Ten pusty plik mówi Pythonowi, że ten katalog powinien być uznany za pakiet Pythona.
  • DjangoApp/settings.py: Ten plik zawiera konfigurację twojego projektu Django.
  • DjangoApp/urls.py: Ten plik zawiera deklaracje adresów URL dla twojego projektu Django.
  • DjangoApp/wsgi.py: Ten plik definiuje punkt wejścia dla serwerów WWW, które obsługują twój projekt.
  • Zagnieżdżony katalog MyApp zawiera wszystkie pliki wymagane do utworzenia aplikacji Django (w tej chwili te pliki są puste):
    • MyApp/__init__.py mówi Pythonowi, że ten katalog powinien być traktowany jako pakiet Pythona.
    • MyApp/models.py: W tym pliku utworzymy modele dla naszej aplikacji.
    • MyApp/views.py: W tym pliku utworzymy widoki.
  • Katalog szablonów (templates) jest narazie pusty. Powinien zawierać pliki szablonów.
  • Zagnieżdżony katalog migrations zawiera już tylko plik pakietu init.py, ale będzie używany w przyszłości w celu propagowania zmian wprowadzonych w modelach (dodawanie pola, usuwanie modelu itp.) do schematu bazy danych.
W razie potrzeby można utworzyć dowolną liczbę aplikacji Django. Aby dodać aplikację do projektu, uruchom zadanie startapp narzędzia manage.py (Tools Run manage.py, a następnie wpisz polecenie startapp w konsoli).

Konfigurowanie bazy danych

W pliku settings.py określ bazę danych, której chcesz użyć w swojej aplikacji. W tym celu znajdź zmienną DATABASES. Następnie w linii ENGINE dodaj nazwę systemu zarządzania bazą danych po kropce.

W wierszu NAME wprowadź nazwę żądanej bazy danych, nawet jeśli jeszcze nie istnieje. image

Uruchamianie serwera Django

Ponieważ wybieramy sqlite3, nie musimy definiować innych wartości (poświadczenia użytkownika, port i host). Sprawdźmy teraz, czy nasze ustawienia są poprawne. Można to zrobić najłatwiej: wystarczy uruchomić zadanie runserver w narzędziu manage.py: naciśnij Ctrl + Alt + R i wpisz nazwę zadania w konsoli manage.py po spacji można dopisać port na jakim chcemy aby urochomił się serwer aplikacji. image

Wybierz sugerowany link i zobacz następującą stronę: image

Tworzenie modeli

Następnie otwórz plik models.py i zauważ, że instrukcja importu już istnieje. Następnie wpisz następujący kod:

from django.db import models

# the following lines added:
import datetime
from django.utils import timezone


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text

    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now

    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.DO_NOTHING, )
    choice_test = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):

        return self.choice_test

Tworzenie bazy danych

Musimy stworzyć tabele dla nowego modelu. W tym celu użyjemy magicznego skrótu Ctrl + Alt + R do wywołania konsoli manage.py. Pierwsze polecenie do wykonania to makemigrations MyApp: image

W ten sposób powiedziałeś Django, że zostały utworzone dwa nowe modele, mianowicie Choise i Question, i utworzyłeś migrację widoczną w strukturze projektu w katalogu migrations.

Następnie po znaku zachęty wpisz następujące polecenie: sqlmigrate MyApp 0001 W konsoli widoczne będą wykonane zapytania do bazy danych.

Na koniec uruchom komendę migrate, aby faktycznie utworzyć te tabele w bazie danych. W przypadku gdy w danym projekcie posiadasz więcej aplikacji po spacji dopisz nazwię aplikacji aby migracja odnosiła sie tylko do niej.

Wykonywanie funkcji administracyjnych

Najpierw utwórz superużytkownika. Aby to zrobić, wpisz polecenie createsuperuser w konsoli manage.py, podaj nazwę użytkownika, swój adres e-mail i hasło:

image

Ponieważ zdecydowaliśmy się włączyć administrację witryną, PyCharm odkomentował już odpowiednie wiersze w pliku urls.py.

Przygotowywanie konfiguracji uruchamiania/debugowania

Jesteśmy teraz gotowi, aby przejść do strony administratora. Oczywiście, możliwe jest uruchomienie serwera Django, następnie przejście do przeglądarki i wpisanie całego adresu URL na pasku adresu.

Uruchomienie strony administratora

Teraz, aby uruchomić aplikację, naciśnij Shift + F10 lub kliknij uruchom na głównym pasku narzędzi, aby otworzyć standardową stronę logowania do witryny Django: image

Po zalogowaniu się wyświetlana jest strona administracyjna. Ma sekcję Authentication and Authorization (Groups and Users), ale ankiety nie są dostępne. Dlaczego tak?

Musimy powiedzieć administratorowi, że obiekty Question mają interfejs administratora; aby to zrobić, otwórzmy plik MyApp/admin.py i wpisz następujący kod:

from django.contrib import admin
from .models import Question #this line added
admin.site.register(Question)#this line added

Odśwież stronę i zobacz sekcję MyApp z pytaniami.

image

Kliknij Dodaj, aby utworzyć kilka pytań.

Edytowanie pliku admin.py

Jednak każde pytanie ma wiele opcji, ale wybory wciąż nie są dostępne. Ponownie otwórz edycję pliku i zmień ją w następujący sposób:

from django.contrib import admin
from .models import Choice, Question


class ChoiceInline(admin.TabularInline):
    model = Choice
    extra = 3


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]


admin.site.register(Question, QuestionAdmin)

Teraz spójrz na stronę zmiany pytania. image

Pisanie widoków

Otwórz plik MyApp/views.py i wpisz następujący kod Pythona:

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")

Następnie dodaj nowy plik do katalogu MyApp z nazwą urls.py i wpisz w nim następujący kod:

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
]

Następnie otwórz plik _DjangoApp/urls.py (który PyCharm już utworzył dla ciebie) i dodaj adres URL strony indeksu. Powinieneś otrzymać następujący kod:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('polls/', include('MyApp.urls')),
    path('admin/', admin.site.urls),
]

Teraz otwórz stronę 127.0.0.1:8000/polls/ i ciesz się:

image

Następnie dodajmy więcej widoków. Ponownie dodaj następujący kod do pliku MyApp/views.py:

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

Połącz te nowe widoki z modułem MyApp/urls.py, dodając następujące wywołania url():

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
    # ex: /polls/5/
    url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
    # ex: /polls/5/results/
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
    # ex: /polls/5/vote/
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

Otwórz teraz odpowiednie strony w przeglądarce.

Tworzenie szablonów Django

Jak widzisz, projektowanie tych stron jest zakodowane w widokach. Aby uczynić go bardziej czytelnym, musisz edytować odpowiedni kod w Pythonie. Oddzielmy wizualną reprezentację danych wyjściowych od Pythona - aby to zrobić, stwórzmy szablony.

Otwórz, plik MyApp/views.py i zastąpić jego zawartość następującym kodem:

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse

from .models import Question, Choice


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)


def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})


def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/results.html', {'question': question})


def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

Pierwszą rzeczą, którą zauważysz, jest nierozwiązane odniesienie do strony index.html: image

PyCharm sugeruje szybką naprawę: jeśli klikniesz żarówkę lub naciśniesz Alt + Enter, odpowiedni plik szablonu zostanie utworzony w folderze szablonów.

W tagach HTML dostępne jest także uzupełnianie kodu.

Zwróć uwagę na ikony image i image, które pojawiają się na lewym marginesie odpowiednio plików views.py i index.html. Ikony te umożliwiają natychmiastowe przejście między metodą widoku a jej szablonem.

Korzystanie z arkusza stylów

Jak widać w pliku widoku index.html, istnieje odniesienie do arkusza stylów i jest ono niezdefiniowane:

  1. Zdefiniuj to odniesienie w następujący sposób:
  2. Utworzyć katalog w katalogu głównym o nazwie static/polls.
  3. Następnie utwórz arkusz stylów w tym katalogu.
  4. Uzupełnij zawartość do utworzonego arkusza stylów, w zależności od twoich preferencji. Na przykład chcielibyśmy zobaczyć wypunktowaną listę pytań w kolorze zielonym:
    li a {
    color: green;
    }
    

    W pliku setings.py dopisz poniższy kod

    STATICFILES_DIRS = [
     os.path.join(BASE_DIR, "static"),
    ]
    

    Teraz sprawdźmy listę dostępnych ankiet(127.0.0.1:8888/polls). Nasza strona administratora już działa, a najprostszym sposobem odwiedzenia strony zawierającej listę pytań (stronę indeksu) jest określenie jej adresu URL. image

Sprawdź to…

Teraz zobaczmy, jak PyCharm pomaga uprościć testowanie aplikacji.

Istnieje już plik tests.py w katalogu MyApp. Ten plik jest pusty. Naturalnie wskazane jest umieszczenie nowych testów w tym konkretnym pliku. Na przykład chcemy się upewnić, że nasza ankieta nie jest pusta:

import datetime
from django.urls import reverse
from django.test import TestCase
from django.utils import timezone
from .models import Question


def create_question(question_text, days):
    time = timezone.now() + datetime.timedelta(days=days)
    return Question.objects.create(question_text=question_text, pub_date=time)


class QuestionViewTests(TestCase):
    def test_index_view_with_no_questions(self):
        """
        If no questions exist, an appropriate message should be displayed.
        """
        response = self.client.get(reverse('index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context['latest_question_list'], [])

Aby uruchomić ten test, kliknij prawym przyciskiem myszy tło pliku tests.py w edytorze, wybierz opcję Run. image

Podsumowanie

Pomyślnie utworzyłeś i uruchomiłeś prostą aplikację Django. Powtórzmy to, co zostało zrobione przy pomocy PyCharm:

  • Projekt i aplikacja Django zostały stworzone
  • Uruchomiono serwer Django
  • Baza danych skonfigurowana
  • Utworzono modele, widoki i szablony
  • Uruchomiono aplikację
  • Testy stworzone i wykonane

image