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:
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
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.
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.
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.
Wybierz sugerowany link i zobacz następującą stronę:
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
:
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:
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:
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.
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.
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ę:
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:
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 i , 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:
- Zdefiniuj to odniesienie w następujący sposób:
- Utworzyć katalog w katalogu głównym o nazwie static/polls.
- Następnie utwórz arkusz stylów w tym katalogu.
- 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.
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.
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