diff --git a/.github/list_languages b/.github/list_languages new file mode 100755 index 00000000000..27ee2e7999e --- /dev/null +++ b/.github/list_languages @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +import argparse +import json +import os +from pathlib import Path + + +def parse_langs(langs, include_beta): + for line in langs.readlines(): + description = line[3:-7] + code = line[-5:-3] + + if include_beta or 'beta' not in description: + yield code, description + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--include-beta', help='Include beta languages', default='false', + choices=('true', 'false')) + parser.add_argument('--langs-file', help='LANGS.md to use', + type=argparse.FileType('r', encoding='UTF-8'), + default=(Path(__file__).absolute().parent.parent / 'LANGS.md').as_posix()) + args = parser.parse_args() + + languages = dict(parse_langs(args.langs_file, args.include_beta == 'true')) + + if 'GITHUB_ACTION' in os.environ: + print(f'::set-output name=languages::{json.dumps(list(languages.keys()))}') + for code, language in languages.items(): + print(f'{language} ({code})') + + +if __name__ == '__main__': + main() diff --git a/.github/workflows/translations.yml b/.github/workflows/translations.yml new file mode 100644 index 00000000000..434e1f1aa4e --- /dev/null +++ b/.github/workflows/translations.yml @@ -0,0 +1,54 @@ +name: Update translations + +on: + workflow_dispatch: + inputs: + include_beta: + type: boolean + default: false + description: Include beta languages + +env: + GIT_AUTHOR_NAME: Django Girls Automation + GIT_AUTHOR_EMAIL: automation@djangogirls.org + +jobs: + list_languages: + name: List languages + runs-on: ubuntu-latest + outputs: + languages: ${{ steps.set_list.outputs.languages }} + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set the language list + id: set_list + run: ./.github/list_languages --include-beta ${{ inputs.include_beta }} + + update_language: + name: 'Update ${{ matrix.language }} translations from Crowdin' + needs: list_languages + if: ${{ needs.list_languages.outputs.languages != '[]' }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + language: ${{ fromJson(needs.list_languages.outputs.languages) }} + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Update language + run: | + wget https://crowdin.com/backend/download/project/django-girls-tutorial/${{ matrix.language }}.zip + unzip ${{ matrix.language }}.zip + find ${{ matrix.language }} -name '*.md' -delete + rsync -av master/${{ matrix.language }}*/* ${{ matrix.language }}/ + rm -rf ${{ matrix.language }}.zip master + - name: Open a PR + uses: peter-evans/create-pull-request@v3 + with: + commit-message: "Update ${{ matrix.language }} translations from Crowdin" + branch: "update_translations/${{ matrix.language }}" + title: "Update ${{ matrix.language }} translations from Crowdin" + body: '' + delete-branch: true diff --git a/pl/GLOSSARY.md b/pl/GLOSSARY.md old mode 100755 new mode 100644 diff --git a/pl/README.md b/pl/README.md old mode 100755 new mode 100644 index b61e3af7186..4f1e9030693 --- a/pl/README.md +++ b/pl/README.md @@ -6,9 +6,9 @@ ## Witaj -Witaj w tutorialu Django Girls! Super Cię widzieć! :) W tym tutorialu odbędziemy podróż po technologiach internetowych, oferując Tobie podgląd na wszystkie części składowe, które połączone razem tworzą sieć taką, jaką ją znamy. +Witaj w tutorialu Django Girls! We are happy to see you here. :) In this tutorial, we will take you on a journey under the hood of web technologies, offering you a glimpse of all the bits and pieces that need to come together to make the web work as we know it. -Jak ze wszystkim, co jest nieznane, będzie to naprawdę niezła przygoda - ale nie przejmuj się! Skoro już się tutaj znalazłaś, to dalej już będzie tylko z górki! :) +As with all unknown things, this is going to be an adventure - but no worries, since you already worked up the courage to be here, you'll be just fine. :) ## Wprowadzenie diff --git a/pl/SUMMARY.md b/pl/SUMMARY.md old mode 100755 new mode 100644 index f65c37e6c03..7524c735144 --- a/pl/SUMMARY.md +++ b/pl/SUMMARY.md @@ -1,7 +1,15 @@ # Podsumowanie * [Wprowadzenie](README.md) -* [Instalacja](installation/README.md) +* [Instalacja](installation/README.md) + * [Wiersz poleceń](installation/README.md#command-line) + * [Python](installation/README.md#python) + * [Edytor kodu](installation/README.md#code-editor) + * [Środowisko wirtualne](installation/README.md#virtualenv) + * [Django](installation/README.md#django) + * [Git](installation/README.md#git) + * [GitHub](installation/README.md#github-account) + * [PythonAnywhere](installation/README.md#pythonanywhere-account) * [Instalacja (chromebook)](chromebook_setup/README.md) * [Jak działa internet?](how_the_internet_works/README.md) * [Wprowadzenie do wiersza polecenia](intro_to_command_line/README.md) @@ -14,7 +22,7 @@ * [Modele w Django](django_models/README.md) * [Administracja Django (admin)](django_admin/README.md) * [Wdrażanie!](deploy/README.md) -* [Adresy URL w Django](django_urls/README.md) +* [Django URLs](django_urls/README.md) * [Widoki Django - czas zacząć tworzyć!](django_views/README.md) * [Wprowadzenie do HTML-a](html/README.md) * [Django ORM (QuerySet)](django_orm/README.md) diff --git a/pl/chromebook_setup/README.md b/pl/chromebook_setup/README.md index e55849392ab..5418d7a2564 100644 --- a/pl/chromebook_setup/README.md +++ b/pl/chromebook_setup/README.md @@ -1,5 +1,5 @@ # Instalacja na Chromebooku -> **Uwaga**! Jeżeli wykonałaś już kroki instalacyjne, nie musisz tego robić ponownie - możesz przejść od razu do [Wprowadzenie do Pythona](../python_introduction/README.md). +> **Note** If you already worked through the [installation steps](../installation/README.md), no need to do this again – you can skip straight ahead to [Introduction to Python](../python_introduction/README.md). {% include "/chromebook_setup/instructions.md" %} \ No newline at end of file diff --git a/pl/chromebook_setup/instructions.md b/pl/chromebook_setup/instructions.md index 2dbaeb931fe..b3c8e328878 100644 --- a/pl/chromebook_setup/instructions.md +++ b/pl/chromebook_setup/instructions.md @@ -1,14 +1,14 @@ Możesz [pominąć tę sekcję](http://tutorial.djangogirls.org/en/installation/#install-python), jeżeli nie używasz Chromebooka. W przeciwnym wypadku, proces instalacji będzie wyglądał nieco inaczej. Możesz zignorować pozostałe elementy instrukcji dotyczące instalacji. -### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9) +### Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com) -Cloud IDE jest narzędziem, które pełni funkcję edytora kodu oraz umożliwia dostęp do komputera uruchomionego w internecie, gdzie możesz instalować, pisać oraz uruchamiać programy. Na czas trwania tutoriala Cloud IDE będzie działać jako *komputer lokalny*. Będziesz mogła uruchamiać komendy w terminalu, tak jak inne osoby korzystające z systemu OS X, Ubuntu czy Windows, z tym że Twój terminal będzie podłączony do komputera, który ustawi dla Ciebie Cloud IDE. Oto instrukcje dotyczące różnych Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9). Możesz wybrać jedno z poniższych Cloud IDE i postępować zgodnie z instrukcją. +Cloud IDE jest narzędziem, które pełni funkcję edytora kodu oraz umożliwia dostęp do komputera uruchomionego w internecie, gdzie możesz instalować, pisać oraz uruchamiać programy. Na czas trwania tutoriala Cloud IDE będzie działać jako *komputer lokalny*. Będziesz mogła uruchamiać komendy w terminalu, tak jak inne osoby korzystające z systemu OS X, Ubuntu czy Windows, z tym że Twój terminal będzie podłączony do komputera, który ustawi dla Ciebie Cloud IDE. Oto instrukcje dotyczące różnych Cloud IDE (PaizaCloud Cloud IDE, AWS Cloud9, Glitch.com). Możesz wybrać jedno z poniższych Cloud IDE i postępować zgodnie z instrukcją. #### PaizaCloud Cloud IDE 1. Przejdź do [PaizaCloud Cloud IDE](https://paiza.cloud/) 2. Załóż konto -3. Kliknij przycisk *New Server* +3. Kliknij *Nowy serwer* i wybierz aplikację Django 4. Kliknij przycisk "Terminal" (po lewej stronie okna) Teraz powinnaś zobaczyć interfejs z bocznym paskiem i przyciski po lewej stronie. Kliknij przycisk "Terminal", aby otworzyć okno terminala ze znakiem zachęty takim jak ten: @@ -22,9 +22,17 @@ Terminal PaizaCloud Cloud ID jest gotowy na Twoje instrukcje. Możesz zmienić r #### AWS Cloud9 -1. Przejdź do [AWS Cloud9](https://aws.amazon.com/cloud9/) -2. Załóż konto -3. Kliknij *Create Environment* +Obecnie Cloud 9 wymaga rejestracji w AWS i wprowadzenia informacji o karcie kredytowej. + +1. Zainstaluj Cloud 9 ze [ sklepu internetowego Chrome](https://chrome.google.com/webstore/detail/cloud9/nbdmccoknlfggadpfkmcpnamfnbkmkcp) +2. Przejdź do [c9.io](https://c9.io) i kliknij *Zacznij z AWS Cloud9* +3. Zarejestruj konto AWS (wymaga danych karty kredytowej, ale możesz używać go za darmo) +4. W Panelu AWS wpisz * Cloud9 * na pasku wyszukiwania i kliknij go +5. W panelu Cloud 9 kliknij * Utwórz środowisko * +6. Nazwij go * django-girls * +7. Podczas konfiguracji wybierz *Utwórz nową instancję dla środowiska (EC2)* dla "Typ Środowiska" i *t2.micro* dla "Typ instancji" (powinien powiedzieć "Kwalifikuje się na poziom darmowy"). Domyślne ustawienie oszczędzania kosztów jest dobre, a pozostałe wartości możesz zachować domyślne. +8. Kliknij *Next step* +9. Kliknij *Create Environment* Teraz powinnaś zobaczyć interfejs z bocznym paskiem, duże główne okno z tekstem i małe okno na dole, które wygląda następująco: @@ -35,32 +43,107 @@ Teraz powinnaś zobaczyć interfejs z bocznym paskiem, duże główne okno z tek Dolny obszar jest Twoim terminalem. Możesz użyć go do wysyłania instrukcji do zdalnego komputera Cloud 9. Możesz zmienić rozmiar tego okna, aby je trochę powiększyć. -### Środowisko wirtualne +#### Glitch.com Cloud IDE -Środowisko wirtualne (Virtual Environment - zwane także virtualenv) jest jak skrzynka, do której możemy wstawić użyteczny program komputerowy dla projektu, nad którym pracujemy. Używamy go, aby oddzielić od siebie różne części kodu potrzebne nam w różnych projektach, przez co nie mieszają się one pomiędzy nimi. +1. Przejdź do [Glitch.com](https://glitch.com/) +2. Stwóż darmowe konto (https://glitch.com/signup) lub użyj swojego konta GitHub, jeśli je posiadasz. (Zobacz instrukcje GitHub poniżej) +3. Kliknij *New Project* i wybierz *hello-webpage* +4. Click on the Tools dropdown list (at the bottom left side of the window), then on Terminal button to open terminal tab with a prompt like this: -W swoim terminalu na dole ekranu Cloud 9 wykonaj następujące polecenie: +{% filename %}Terminal{% endfilename %} -{% filename %}Cloud 9{% endfilename %} + app@name-of-your-glitch-project:~ + + +When using Glitch.com as your Cloud IDE, you don't have to create a virtual environment. Instead, create the following files manually: + +{% filename %}glitch.json{% endfilename %} + +```json +{ + "install": "pip3 install -r requirements.txt --user", + "start": "bash start.sh", + "watch": { + "throttle": 1000 + } +} +``` + +{% filename %}requirements.txt{% endfilename %} + + Django~={{ book.django_version }} + + +{% filename %}.bash_profile{% endfilename %} + +```bash +alias python=python3 +alias pip=pip3 +``` + +{% filename %}start.sh{% endfilename %} + +```bash +chmod 600 .bash_profile +pip3 install -r requirements.txt --user +python3 manage.py makemigrations +python3 manage.py migrate +python3 manage.py runserver $PORT +``` + +Once these files are created, go to the Terminal and execute the following commands to create your first Django project: - sudo apt update - sudo apt install python3.6-venv +{% filename %}Terminal{% endfilename %} + + django-admin.py startproject mysite . + refresh -Jeżeli polecenie cały czas nie chce zadziałać, poproś o pomoc swojego mentora. +In order to see detailed error messages, you can activate Django debug logs for your Glitch application. Simply add the following at the end of the `mysite/settings.py` file. + +{% filename %}mysite/settings.py{% endfilename %} + +```python +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'file': { + 'level': 'DEBUG', + 'class': 'logging.FileHandler', + 'filename': 'debug.log', + }, + }, + 'loggers': { + 'django': { + 'handlers': ['file'], + 'level': 'DEBUG', + 'propagate': True, + }, + }, +} +``` + +This will create a `debug.log` file detailing Django operations and any error messages that might come up, making it much easier to fix if your website does not work. + +The initial restarting of the Glitch project should fail. (If you click on the top dropdown button `Show` then click on `In a New Window`, you will receive a `DisallowedHost` error message.) Do not worry about it at this stage, the tutorial will fix this as soon as you update the Django settings of your project in the `mysite/settings.py` file. + +### Środowisko wirtualne + +A virtual environment (also called a virtualenv) is like a private box we can stuff useful computer code into for a project we're working on. We use them to keep the various bits of code we want for our various projects separate so things don't get mixed up between projects. -Następnie uruchom: +Run: {% filename %}Cloud 9{% endfilename %} mkdir djangogirls cd djangogirls - python3.6 -mvenv myvenv + python3 -m venv myvenv source myvenv/bin/activate pip install django~={{ book.django_version }} -(zauważ, że w ostatniej linii użyłyśmy tyldy, za którą następuje znak równości: ~=). +(note that on the last line we use a tilde followed by an equal sign: `~=`). ### GitHub @@ -68,8 +151,8 @@ Załóż konto na [GitHubie](https://github.com). ### PythonAnywhere -Tutorial Django Girls zawiera sekcję dotycząca wdrożenia, tzn. procesu przenoszenia kodu programu, który odpowiada za działanie naszej nowej aplikacji internetowej na publicznie dostępny komputer (zwany serwerem) w taki sposób, by inne osoby były w stanie zobaczyć Twoje dzieło. +The Django Girls tutorial includes a section on what is called Deployment, which is the process of taking the code that powers your new web application and moving it to a publicly accessible computer (called a server) so other people can see your work. -Ta część może wydać się lekko niezrozumiała, gdy przechodzimy tutorial na Chromebooku, skoro w trakcie tutoriala używamy komputera, który już jest w internecie (w odróżnieniu od chociażby naszego laptopa). Jednak może ona być cały czas przydatna, byśmy traktowały nasze konto w Cloud9 jako miejsce, w którym postępuje nasza praca oraz PythonAnywhere jako miejsce, gdzie możemy pokazać światu nasze dzieło, gdy tylko będzie ono bardziej dokończone. +This part is a little odd when doing the tutorial on a Chromebook since we're already using a computer that is on the Internet (as opposed to, say, a laptop). However, it's still useful, as we can think of our Cloud 9 workspace as a place for our "in progress" work and Python Anywhere as a place to show off our stuff as it becomes more complete. -Dlatego właśnie załóż nowe konto w PythonAnywhere pod adresem [www.pythonanywhere.com](https://www.pythonanywhere.com). \ No newline at end of file +Thus, sign up for a new Python Anywhere account at [www.pythonanywhere.com](https://www.pythonanywhere.com). \ No newline at end of file diff --git a/pl/code_editor/README.md b/pl/code_editor/README.md old mode 100755 new mode 100644 index c57f2363bdd..b0b37f046dc --- a/pl/code_editor/README.md +++ b/pl/code_editor/README.md @@ -6,6 +6,6 @@ Zaraz napiszesz swoją pierwszą linijkę kodu, więc najwyższy czas zainstalow > **Uwaga** Jeśli używasz już Chromebooka, pomiń ten rozdział i upewnij się, że postąpiłaś zgodnie z instrukcją [Instalacja Chromebooka](../chromebook_setup/README.md). Cloud IDE, które wybrałaś (PaizaCloud Cloud IDE or AWS Cloud9) zawiera edytor kodu, więc kiedy otworzysz plik z menu w swoim IDE, automatycznie zostanie on otworzony w edytorze. > -> **Uwaga** Jeśli zrobiłaś to już wcześniej w rozdziale 'Instalacja' - możesz przejść od razu do następnego rozdziału! +> **Note** You might have done this earlier in the [Installation chapter](../installation/README.md) – if so, you can skip right ahead to the next chapter! {% include "/code_editor/instructions.md" %} \ No newline at end of file diff --git a/pl/code_editor/instructions.md b/pl/code_editor/instructions.md old mode 100755 new mode 100644 index 34bd0b81d27..c0789f69470 --- a/pl/code_editor/instructions.md +++ b/pl/code_editor/instructions.md @@ -2,6 +2,12 @@ Istnieje wiele programów tego typu, jednak który wybrać? To nie takie proste, Nasze propozycje prezentujemy poniżej, ale w razie czego spytaj o sugestie swojego mentora - będzie on w stanie wybrać coś zgodnego z Twoimi preferencjami. +## Visual Studio Code + +Visual Studio Code jest edytorem kodu źródłowego opracowanym przez Microsoft dla Windows, Linux i macOS. Obejmuje on wsparcie debugowania, kontrolę wbudowanego Git, podświetlanie składni, inteligentne uzupełnianie kodu, fragmenty i refaktoryzację kodu. + +[Pobierz tutaj](https://code.visualstudio.com/) + ## Gedit Gedit to open source'owy i darmowy edytor dostępny dla wszystkich systemów operacyjnych. Czasami nie jest jednak zbyt prosty w zainstalowaniu. @@ -28,4 +34,4 @@ Podstawowym powodem jest to, że kod musi być **zwykłym, niesformatowanym teks Drugim powodem jest specjalizacja edytorów kodu - dzięki temu mogą one dostarczać bardzo użytecznych funkcjonalności, jak kolorowanie składni zgodnie z jej przeznaczeniem lub automatyczne zamykanie cudzysłowów zamiast Ciebie. -Za chwilę przetestujemy wybrany edytor w akcji. Nim się obejrzysz, będziesz uważać swój edytor tekstu jako jedno z ulubionych narzędzi. :) +Za chwilę przetestujemy wybrany edytor w akcji. Nim się obejrzysz, będziesz uważać swój edytor tekstu jako jedno z ulubionych narzędzi. :) \ No newline at end of file diff --git a/pl/css/README.md b/pl/css/README.md old mode 100755 new mode 100644 index 6a2468b7d15..c89a1cb937d --- a/pl/css/README.md +++ b/pl/css/README.md @@ -21,8 +21,7 @@ Aby zainstalować Bootstrap, otwórz plik `.html` w edytorze kodu i dodaj do sek {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - - + ``` Akurat to nie doda żadnych nowych plików do Twojego projektu. Te dwie linijki wskazują na pliki, które istnieją w Internecie. Sprawdź sama, otwórz swoją stronę w przeglądarce internetowej, odśwież zawartość. No i proszę! @@ -81,7 +80,7 @@ h1 a, h2 a { `h1 a` to selektor CSS. Oznacza to, że zastosujemy nasze style do każdego elementu `a` znajdującego się w elemencie `h1`; selektor `h2 a` czyni to samo dla elementów `h2`. Czyli gdy mamy coś takiego jak `

link

`, styl `h1 a`, styl zostanie użyty. W tym przypadku nadajemy mu kolor `#C25100`, czyli ciemnopomarańczowy. Możesz też tutaj wstawić swój własny kolor, ale pamiętaj, by odpowiednio kontrastował z białym tłem! -W pliku CSS ustalamy styl dla elementów znajdujących się w pliku HTML. Pierwszą metodą rozpoznawania elementu jest jego nazwa. Możesz pamiętać te tagi z rozdziału o HTML. Takie rzeczy jak `a`, `h1` i `body` to wszystko przykłady nazw elementów. Elementy rozpoznajemy również po atrybutach `class` lub `id`. Nazwę klasy lub id ustalasz sama dowolnie. Ta sama nazwa klasy może być przypisana do wielu elementów, ale id musi być unikalne dla całego kodu HTML. Dla przykładu, możesz zidentyfikować następujący tag używając nazwy tagu `a`, klasy `external_link` lub po jego id `link_to_wiki_page`: +W pliku CSS ustalamy styl dla elementów znajdujących się w pliku HTML. Pierwszą metodą rozpoznawania elementu jest jego nazwa. Możesz pamiętać te tagi z rozdziału o HTML. Takie rzeczy jak `a`, `h1` i `body` to wszystko przykłady nazw elementów. Elementy rozpoznajemy również po atrybutach `class` lub `id`. Nazwę klasy lub id ustalasz sama dowolnie. Ta sama nazwa klasy może być przypisana do wielu elementów, ale id musi być unikalne dla całego kodu HTML. Dla przykładu, możesz zidentyfikować następujący element używając nazwy elementu `a`, klasy `external_link` lub po jego id `link_to_wiki_page`: ```html @@ -113,24 +112,24 @@ Twój plik powinien teraz wyglądać tak: ```html {% load static %} + Django Girls blog - - + -
+

Django Girls Blog

-
+ {% for post in posts %} -
-

published: {{ post.published_date }}

+
+

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} @@ -181,26 +180,28 @@ Wspaniale! Jak napisałyśmy powyżej, w CSS istnieje koncepcja klas. Pozwalają one nazwać część naszego kodu HTML i aplikować style tylko do tej części, omijając wpływ tych stylów na inne części. To może być super użyteczne! Może masz dwa divy, które odpowiadają za coś innego (jak nasz header lub post). Klasa pomoże nam, gdy będziemy chciały, by wyglądały one inaczej. -Śmiało! Nazwijmy kilka części Twojego kodu HTML. Dodaj klasę nazwaną `page-header` do Twojego `div` który zawiera nagłówek: +Go ahead and name some parts of the HTML code. Replace the `header` that contains your header with the following: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html - + ``` -Teraz dodaj klasę `post` do Twojego `div` zawierającego post bloga: +And now add a class `post` to your `article` containing a blog post. {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
-

published: {{ post.published_date }}

+
+

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ ``` A teraz dodamy bloki deklaracji do selektorów. Selektory zaczynające się od `.` odnoszą się do klas. W Internecie jest wiele wspaniałych tutoriali dotyczących CSS, które pomogą Tobie zrozumieć następujący kod. Na razie skopiuj i wklej do `blog/static/css/blog.css` poniższy kod: @@ -211,20 +212,23 @@ A teraz dodamy bloki deklaracji do selektorów. Selektory zaczynające się od ` .page-header { background-color: #C25100; margin-top: 0; + margin-bottom: 40px; padding: 20px 20px 20px 40px; } -.page-header h1, .page-header h1 a, .page-header h1 a:visited, .page-header h1 a:active { +.page-header h1, +.page-header h1 a, +.page-header h1 a:visited, +.page-header h1 a:active { color: #ffffff; font-size: 36pt; text-decoration: none; } -.content { - margin-left: 40px; -} - -h1, h2, h3, h4 { +h1, +h2, +h3, +h4 { font-family: 'Lobster', cursive; } @@ -236,11 +240,14 @@ h1, h2, h3, h4 { float: right; } -.post-form textarea, .post-form input { +.post-form textarea, +.post-form input { width: 100%; } -.top-menu, .top-menu:hover, .top-menu:visited { +.top-menu, +.top-menu:hover, +.top-menu:visited { color: #ffffff; float: right; font-size: 26pt; @@ -251,9 +258,27 @@ h1, h2, h3, h4 { margin-bottom: 70px; } -.post h2 a, .post h1 a:visited { +.post h2 a, +.post h2 a:visited { color: #000000; } + +.post > .date, +.post > .actions { + float: right; +} + +.btn-secondary, +.btn-secondary:visited { + color: #C25100; + background: none; + border-color: #C25100; +} + +.btn-secondary:hover { + color: #FFFFFF; + background-color: #C25100; +} ``` Teraz otocz kod HTML wyświetlający posty deklaracjami klas. Zamień to: @@ -262,11 +287,11 @@ Teraz otocz kod HTML wyświetlający posty deklaracjami klas. Zamień to: ```html {% for post in posts %} -
-

published: {{ post.published_date }}

+
+

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` @@ -275,21 +300,21 @@ w pliku `blog/templates/blog/post_list.html` na to: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html -
+
-
+
{% for post in posts %} -
-
-

published: {{ post.published_date }}

-
+
+

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` Zapisz te pliki i odśwież swoją stronę. @@ -300,6 +325,6 @@ Woohoo! Wygląda to niesamowicie, prawda? Sprawdź w kodzie, który przed chwil Nie bój się trochę pomajstrować w CSS próbując zmienić niektóre rzeczy. Zabawa z CSS pozwoli Ci lepiej zrozumieć, co robią różne rzeczy. Niczym się nie przejmuj, jeżeli coś zepsujesz - zawsze przecież można cofnąć zmiany! -Naprawdę zalecamy wzięcie udziału w darmowym kursie online [Codeacademy HTML & CSS](https://www.codecademy.com/tracks/web). Pomoże on Tobie nauczyć się wszystkiego, czego potrzebujesz, by upiększyć twoje strony za pomocą CSS. +Naprawdę polecamy skorzystanie z bezpłatnych kursów online "Basic HTML & HTML5" i "Basic CSS" na [freeCodeCamp](https://learn.freecodecamp.org/). Pomoże to Tobie nauczyć się wszystkiego, czego potrzebujesz, by upiększyć twoje strony za pomocą CSS. Gotowa na następny rozdział?! :) \ No newline at end of file diff --git a/pl/deploy/README.md b/pl/deploy/README.md old mode 100755 new mode 100644 index c81a2fe9964..5775c830ad0 --- a/pl/deploy/README.md +++ b/pl/deploy/README.md @@ -12,7 +12,7 @@ Te trzy miejsca będą dla Ciebie bardzo ważne. Twój lokalny komputer będzie # Git -> **Uwaga** Jeżeli wykonałaś już wszystkie kroki instalacji, nie ma potrzeby ich powtarzać - możesz przeskoczyć do następnej sekcji i zacząć tworzyć repozytorium w Gicie. +> **Note** If you already did the [installation steps](../installation/README.md), there's no need to do this again – you can skip to the next section and start creating your Git repository. {% include "/deploy/install_git.md" %} @@ -32,31 +32,75 @@ Git śledzi zmiany dokonywane w zbiorze plików w czymś, co nazywamy repozytori Inicjalizacja repozytorium gita jest jednorazowym zadaniem dla każdego projektu (nie będzie więcej potrzeby, byś ponownie podawał nazwę użytkownika i email). -Git będzie śledzić zmiany we wszyskich plikach i folderach w tym katalogu, ale zwróć uwagę, że znajdują się w nim pewne pliki, których zmiany chcemy ignorować. By to zrobić, musimy utworzyć w tym katalogu plik, który nazwiemy `.gitignore`. Otwórz swój edytor kodu i utwórz nowy plik o następującej treści: +### Adjusting your branch name + +If the version of Git that you are using is older than **2.28**, you will need to change the name of your branch to "main". To determine the version of Git, please enter the following command: + +{% filename %}command-line{% endfilename %} + + $ git --version + git version 2.xx... + + +Only if the second number of the version, shown as "xx" above, is less than 28, will you need to enter the following command to rename your branch. If it is 28 or higher, please continue to "Ignoring files". As in "Initializing", this is something we need to do only once per project, as well as only when your version of Git is less than 2.28: + +{% filename %}command-line{% endfilename %} + + $ git branch -M main + + +### Ignoring files + +Git will track changes to all the files and folders in this directory, but there are some files we want it to ignore. We do this by creating a file called `.gitignore` in the base directory. Open up your editor and create a new file with the following contents: {% filename %}.gitignore{% endfilename %} + # Python *.pyc *~ __pycache__ - myvenv + + # Env + .env + myvenv/ + venv/ + + # Database db.sqlite3 - /static + + # Static folder at project root + /static/ + + # macOS + ._* .DS_Store + .fseventsd + .Spotlight-V100 + + # Windows + Thumbs.db* + ehthumbs*.db + [Dd]esktop.ini + $RECYCLE.BIN/ + + # Visual Studio + .vscode/ + .history/ + *.code-workspace -I zapisz go jako `.gitignore` w katalogu "djangogirls". +And save it as `.gitignore` in the "djangogirls" folder. -> **Uwaga** Ta kropka na początku nazwy pliku jest ważna! Jeżeli masz problem podczas tworzenia tego pliku (MacOS ma na przykład problem z tworzeniem plików zaczynających się od kropki za pomocą Findera), to spróbuj użyć polecenia "Zapisz jako" w swoim edytorze, to akurat jest niezawodne. I upewnij się, że nie dodałaś .txt, .py lub jakiegokolwiek innego rozszerzenia do nazwy pliku. Zostanie on rozpoznany przez Gita tylko wtedy, gdy jego nazwą jest po prostu .gitignore. +> **Uwaga** Ta kropka na początku nazwy pliku jest ważna! Jeżeli masz problem podczas tworzenia tego pliku (MacOS ma na przykład problem z tworzeniem plików zaczynających się od kropki za pomocą Findera), to spróbuj użyć polecenia "Zapisz jako" w swoim edytorze, to akurat jest niezawodne. I upewnij się, że nie dodałaś .txt, .py lub jakiegokolwiek innego rozszerzenia do nazwy pliku. Zostanie on rozpoznany przez Gita tylko wtedy, gdy jego nazwą jest po prostu .gitignore. Linux and MacOS treat files with a name that starts with `.` (such as `.gitignore`) as hidden and the normal `ls` command won't show these files. Instead use `ls -a` to see the `.gitignore` file. > > **Uwaga** Jednym z plików, który wyszczególniliśmy w `.gitignore` to `db.sqlite3`. Ten plik to Twoja lokalna baza danych, w której przechowywani są wszyscy Twoi użytkownicy i posty. Będziemy podążać za standardem praktyki programowania webowego, co oznacza, że będziemy używać oddzielnych baz danych dla naszej lokalnej strony testowej oraz produkcyjnej witryny na PythonAnywhere. Bazą danych dla PythonAnywhere może być SQLite, tak jak na Twojej lokalnej maszynie. Najczęściej natomiast będziesz korzystać z bazy MySQL, która potrafi poradzić sobie z dużo większą ilością odwiedzających niż SQLite. W każdym razie, zignorowanie Twojej bazy SQLite w kopii dla GitHuba oznacza, że wszystkie posty i użytkownicy, których do tej pory stworzyłaś, będą dostępne jedynie lokalnie i będziemy musiały dodać ich ponownie na środowisku produkcyjnym. Powinnaś myśleć o swojej lokalnej bazie danych jako o dobrym placu zabaw, na którym możesz testować różne rzeczy nie bojąc się, że skasujesz prawdziwe artykuły ze swojego bloga. -Dobrym nawykiem jest wpisywanie polecenia `git status` zanim wpiszesz `git add` albo gdy nie jesteś pewna co się zmieniło. Pozwala ono zabezpieczyć się przed niespodziankami takimi, jak chociażby dodanie lub skomitowanie błędnego pliku. Polecenie `git status` zwraca informację o wszystkich nieśledzonych/zmienionych/zaplanowanych do najbliższego commita plików, statusie brancha i wiele innych. Wynik powinien wyglądać podobnie do następującego: +It's a good idea to use a `git status` command before `git add` or whenever you find yourself unsure of what has changed. This will help prevent any surprises from happening, such as wrong files being added or committed. The `git status` command returns information about any untracked/modified/staged files, the branch status, and much more. The output should be similar to the following: {% filename %}command-line{% endfilename %} $ git status - On branch master + On branch main No commits yet @@ -72,11 +116,11 @@ Dobrym nawykiem jest wpisywanie polecenia `git status` zanim wpiszesz `git add` nothing added to commit but untracked files present (use "git add" to track) -I na końcu zapisujemy zmiany. Przejdź do konsoli i wykonaj poniższe polecenia: +And finally we save our changes. Go to your console and run these commands: {% filename %}command-line{% endfilename %} - $ git add --all . + $ git add . $ git commit -m "My Django Girls app, first commit" [...] 13 files changed, 200 insertions(+) @@ -87,134 +131,51 @@ I na końcu zapisujemy zmiany. Przejdź do konsoli i wykonaj poniższe polecenia ## Przesyłanie kodu do GitHuba -Wejdź na stronę [GitHub.com](https://www.github.com) i załóż darmowe konto użytkownika. (Jeśli zrobiłaś to na warsztatach przygotowawczych to świetnie). Zapamiętaj hasło do swojego konta (dodaj je do swojego menedżera haseł, jeśli go używasz). +Go to [GitHub.com](https://www.github.com) and sign up for a new, free user account. (If you already did that in the workshop prep, that is great!) Be sure to remember your password (add it to your password manager, if you use one). -Następnie utwórz nowe repozytorium i nadaj mu nazwę "my-first-blog" (ang. "mój-pierwszy-blog"). Pozostaw niezaznaczone pole wyboru "initialize with README", pozostaw opcję .gitignore pustą (zrobiłyśmy to ręcznie) i pozostaw licencję jako None. +Then, create a new repository, giving it the name "my-first-blog". Leave the "initialize with a README" checkbox unchecked, leave the .gitignore option blank (we've done that manually) and leave the License as None. ![](images/new_github_repo.png) > **Uwaga** Nazwa `my-first-blog` jest ważna - mogłabyś wybrać jakąś inną, ale będziemy tej nazwy używać wiele razy i za każdym razem musiałabyś pamiętać, żeby zastępować "my-first-blog" swoją wybraną nazwą. Z tego powodu najłatwiej będzie jak użyjesz nazwy `my-first-blog`. -Na następnym obrazku zostanie wyświetlony Twój URL do klonowania repozytorium, którego będziesz używać w niektórych poleceniach. +On the next screen, you'll be shown your repo's clone URL, which you will use in some of the commands that follow: ![](images/github_get_repo_url_screenshot.png) -Teraz musimy podpiąć repozytorium Git na komputerze do tego na GitHubie. +Now we need to hook up the Git repository on your computer to the one up on GitHub. -Wpisz następujące polecenie do konsoli (zamień na swoją nazwę użytkownika, którą podałaś przy tworzeniu konta na GitHubie. Nie zapomnij o usunięciu nawiasów ("<" i ">"), ten URL powinien pasować do URL-a klonującego Twoje repozytorium. +Type the following into your console (replace `` with the username you entered when you created your GitHub account, but without the angle-brackets -- the URL should match the clone URL you just saw). {% filename %}command-line{% endfilename %} $ git remote add origin https://github.com//my-first-blog.git - $ git push -u origin master + $ git push -u origin main -Po wykonaniu komendy push na GitHuba zostaniesz zapytana o swoją nazwę użytkownika i hasło (albo bezpośrednio w wierszu poleceń w oknie terminala albo w wyskakującym okienku). Po poprawnym wpisaniu użytkownika i hasła powinnaś zobaczyć coś takiego: +When you push to GitHub, you'll be asked for your GitHub username and password (either right there in the command-line window or in a pop-up window), and after entering credentials you should see something like this: {% filename %}command-line{% endfilename %} Counting objects: 6, done. Writing objects: 100% (6/6), 200 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) - To https://github.com/ola/my-first-blog.git - * [new branch] master -> master - Branch master set up to track remote branch master from origin. - - - - -Twój kod jest teraz na GitHubie. Możesz to sprawdzić! Znajdujesz się teraz w wyśmienitym towarzystwie - [Django](https://github.com/django/django), [kurs Django Girls](https://github.com/DjangoGirls/tutorial) i wiele innych świetnych projektów open-source trzyma swój kod na GitHubie! :) - -# Wdrażanie bloga na PythonAnywhere - -## Zakładanie konta na PythonAnywhere - -> **Uwaga** Możliwe, że już wcześniej utworzyłaś konto na PythonAnywhere, jeśli przeszłaś przez wszystkie kroki w rozdziale instalacyjnym - nie ma potrzeby, byś robiła to drugi raz. - -{% include "/deploy/signup_pythonanywhere.md" %} - -## Konfigurowanie naszej strony w PythonAnywhere - -Wróć do głównego panelu [PythonAnywhere Dashboard](https://www.pythonanywhere.com/), klikając logo i wybierz opcję uruchomienia konsoli "Bash" - jest to wersja wiersza polecenia PythonAnywhere, podobnie jak na Twoim komputerze. - -![Sekcja 'New Console' na stronie PythonAnywhere z przyciskiem 'bash'](images/pythonanywhere_bash_console.png) - -> **Uwaga** PythonAnywhere jest oparty na Linuksie, więc jeśli pracujesz na Windowsie, to konsola będzie wyglądać trochę inaczej, niż na Twoim komputerze. - -Wdrożenie aplikacji internetowej w PythonAnywhere polega na ściągnięciu kodu z GitHuba, a następnie skonfigurowaniu PythonAnywhere w celu rozpoznania go i rozpoczęciu wyświetlania go jako aplikacji internetowej. Istnieją manualne sposoby robienia tego, ale PythonAnywhere zapewnia narzędzie pomocnicze, które zrobi to wszystko za Ciebie. W pierwszej kolejności zainstalujmy: - -{% filename %}PythonAnywhere command-line{% endfilename %} - - $ pip3.6 install --user pythonanywhere - -To powinno wydrukować rzeczy takie jak `Collecting pythonanywhere`, a skończyć się na linii z napisem `Successfully installed (...) pythonanywhere- (...)`. - -Teraz uruchamiamy pomocnika, aby automatycznie skonfigurować naszą aplikację z GitHubem. Wpisz następujące polecenie do konsoli w PythonAnywhere (nie zapomnij zamienić na Twoją nazwę użytkownika GitHub, tak by Twój URL pasował do klonowanego URL-a z GitHuba). - -{% filename %}PythonAnywhere command-line{% endfilename %} - - $ pa_autoconfigure_django.py https://github.com//my-first-blog.git + * [new branch] main -> main + Branch main set up to track remote branch main from origin. -Jeżeli patrzysz na proces, będziesz mogła zobaczyć: - -- Pobieranie kodu z GitHuba -- Tworzenie środowiska wirtualnego na PythonAnywhere, podobnie jak na Twoim komputerze. -- Aktualizowanie pliku ustawień z niektórych ustawień wdrażania -- Konfigurowanie bazy danych w PythonAnywhere za pomocą polecenia `manage.py migrate` -- Konfigurowanie plików statycznych (dowiemy się o nich później) -- I konfigurowanie PythonAnywhere do obsługi aplikacji internetowej za pomocą interfejsu API - -W PythonAnywhere wszystkie te kroki są zautomatyzowane, ale są to te same kroki, które trzeba wykonać z dowolnym innym dostawcą serwera. - -Najważniejszym w tej chwili jest to, aby zapamiętać, że baza danych w PythonAnywhere jest całkowicie oddzielona od bazy danych na Twoim komputerze, co oznacza, że może mieć inne posty i konta administracyjne. W rezultacie, tak jak zrobiłyśmy to wcześniej na własnym komputerze, musimy zainicjować konto administratora za pomocą `createsuperuser`. PythonAnywhere automatycznie aktywował dla Ciebie Twojego virtualenva, więc jedyne, co musisz zrobić, to uruchomić: - -{% filename %}PythonAnywhere command-line{% endfilename %} - - (ola.pythonanywhere.com) $ python manage.py createsuperuser - - -Wpisz szczegóły dla konta swojego administratora. Najlepiej używać tych samych, których używasz na swoim komputerze, aby uniknąć nieporozumień, chyba że chcesz, aby hasło w PythonAnywhere było bezpieczniejsze. - -Teraz, jeśli chcesz, możesz również rzucić okiem na swój kod w PythonAnywhere używając `ls`: - -{% filename %}PythonAnywhere command-line{% endfilename %} - - (ola.pythonanywhere.com) $ ls - blog db.sqlite3 manage.py mysite requirements.txt static - (ola.pythonanywhere.com) $ ls blog/ - __init__.py __pycache__ admin.py apps.py migrations models.py tests.py static - templates views.py - - -Możesz także przejść do zakładki "Pliki" i poruszać się za pomocą wbudowanej przeglądarki plików w PythonAnywhere. (Ze strony konsoli możesz przejść do innych stron PythonAnywhere za pomocą przycisku menu w prawym górnym rogu. Po przejściu na jedną ze stron, w pobliżu góry zobaczysz linki do innych.) - -## Jesteś na żywo! - -Twoja strona powinna teraz być dostępna w publicznym internecie! Przejdź do zakładki "Sieć" PythonAnywhere, aby uzyskać link do niej. Możesz podzielić się tym, z kimkolwiek chcesz! :) - -> **Uwaga:** Jest to poradnik dla początkujących, a podczas wdrażania tej witryny użyłyśmy kilka skrótów, które nie są idealnym rozwiązaniem z punktu widzenia bezpieczeństwa. Jeśli zdecydujesz się zbudować ten projekt lub rozpocząć nowy, powinnaś przejrzeć [Django deployment checklist](https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/), aby uzyskać jakieś wskazówki dotyczące zabezpieczania witryny. - -## Porady dotyczące debugowania - -Jeśli widzisz błąd podczas uruchamiania skryptu `pa_autoconfigure_django.py`, oto kilka typowych przyczyn: - -- Zapominasz utworzyć Twój PythonAnywhere API token. -- Robisz błąd w GitHub URL -- Jeśli zobaczysz komunikat o błędzie *"Could not find your settings.py"*, prawdopodobnie nie udało Ci się dodać wszystkich plików do Git, i / lub nie przekazałeś ich do pomyślnie do GitHuba. Jeszcze raz spójrz na sekcję Git powyżej - -Jeśli odwiedzając swoją stronę zobaczysz błąd, to pierwszym miejscem, w którym powinnaś poszukać informacji o tym, co się stało, jest Twój **dziennik błędów** (ang. "error log"). Znajdziesz do niego link na stronie [Web](https://www.pythonanywhere.com/web_app_setup/) w PythonAnywhere. Sprawdź, czy znajdują się tam jakieś komunikaty o błędach - te najświeższe znajdują się na samym dole. + -Są tam też dostępne [generalne porady odnośnie debugowania na stronie pomocy PythonAnywhere](http://help.pythonanywhere.com/pages/DebuggingImportError). +Your code is now on GitHub. Go and check it out! You'll find it's in fine company – [Django](https://github.com/django/django), the [Django Girls Tutorial](https://github.com/DjangoGirls/tutorial), and many other great open source software projects also host their code on GitHub. :) -I pamiętaj, Twój mentor jest tutaj, by Ci pomóc! +{% include "/deploy/pythonanywhere.md" %} -# Sprawdź swoją stronę! +# Check out your site! -Domyślna strona Twojej witryny powinna brzmieć "It worked!", tak jak na Twoim lokalnym komputerze. Spróbuj dodać `/admin/` na koniec swojego adresu URL - powinnaś się przenieść do panelu admina. Zaloguj się za pomocą nazwy użytkownika i hasła. Zobaczysz, że możesz dodać nowy Post na serwerze - pamiętaj, posty z Twojej lokalnej, testowej bazy danych nie będą wysyłane na Twojego produkcyjnego bloga. +The default page for your site should say "It worked!", just like it does on your local computer. Try adding `/admin/` to the end of the URL, and you'll be taken to the admin site. Log in with the username and password, and you'll see you can add new Posts on the server -- remember, the posts from your local test database were not sent to your live blog. -Po utworzeniu kilku postów możesz wrócić do konfiguracji lokalnej (nie PythonAnywhere). Od teraz powinnaś pracować na swoim lokalnym komputerze, jeżeli będziesz chciała dokonać zmian na stronie. To częsty sposób pracy w rozwijaniu stron WWW - wprowadzaj zmiany lokalnie, wypychaj je na GitHuba i zaciągaj na swój internetowy serwer WWW. Pozwala to na pracę i eksperymentowanie bez obawy, że zepsujesz działającą stronę. Całkiem nieźle, co nie? +Once you have a few posts created, you can go back to your local setup (not PythonAnywhere). From here you should work on your local setup to make changes. This is a common workflow in web development – make changes locally, push those changes to GitHub, and pull your changes down to your live Web server. This allows you to work and experiment without breaking your live Web site. Pretty cool, huh? -*Przybij piątkę!* Wdrożenia strony na serwery są jednym z najtrudniejszych elementów tworzenia stron internetowych i często ludzie potrzebują kilku dni, zanim wszystko zacznie poprawnie działać. Ale Tobie udało się wdrożyć swoją stronę, jest ona w prawdziwym internecie! +Give yourself a *HUGE* pat on the back! Server deployments are one of the trickiest parts of web development and it often takes people several days before they get them working. But you've got your site live, on the real Internet! \ No newline at end of file diff --git a/pl/deploy/install_git.md b/pl/deploy/install_git.md old mode 100755 new mode 100644 index 681dc9a2f51..773e1310a62 --- a/pl/deploy/install_git.md +++ b/pl/deploy/install_git.md @@ -7,12 +7,16 @@ data-collapse=true ces--> Możesz ściągnąć Gita z [git-scm.com](https://git-scm.com/). Naciśnij "next" na wszystkich krokach z wyjątkiem dwóch: w kroku, w którym prosi o wybranie edytora, powinnaś wybrać Nano, a w kroku zatytułowanym "Adjusting your PATH environment" wybrać "Use Git and optional Unix tools from the Windows Command Prompt" (dolna opcja). Poza tym domyślne ustawienia są w porządku. Upewnij się jeszcze, że w kroku "Configuring the line ending conversions" wybrana jest opcja "Checkout Windows-style, commit Unix-style line endings". -Nie zapomnij zrestartować wiersza polecenia lub Powershell po instalacji zakończonej sukcesem. +During installation, if you are presented with the option of "Adjusting the name of the initial branch in new repositories", please choose to "Override the default" and use "main". This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. + +Do not forget to restart the command prompt or PowerShell after the installation finished successfully. -Ściągnij Gita z [git-scm.com](https://git-scm.com/) i postępuj zgodnie z instrukcją. +Download Git from [git-scm.com](https://git-scm.com/) and follow the instructions. + +During installation, if you are presented with the option of "Adjusting the name of the initial branch in new repositories", please choose to "Override the default" and use "main". This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. > **Uwaga**Jeżeli działasz na OS X 10.6, 10.7 lub 10.8, będziesz musiała zainstalować wersję gita dostępną tutaj: [Git installer for OS X Snow Leopard](https://sourceforge.net/projects/git-osx-installer/files/git-2.3.5-intel-universal-snow-leopard.dmg/download) @@ -27,6 +31,15 @@ data-collapse=true ces--> sudo apt install git ``` +### Adjusting your default branch name + +This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. + +{% filename %}command-line{% endfilename %} + + $ git config --global --add init.defaultBranch main + + {% filename %}command-line{% endfilename %} ```bash -sudo dnf install git +$ sudo dnf install git ``` +### Adjusting your default branch name + +This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. + +{% filename %}command-line{% endfilename %} + + $ git config --global --add init.defaultBranch main + + {% filename %}command-line{% endfilename %} ```bash -sudo zypper install git +$ sudo zypper install git ``` +### Adjusting your default branch name + +This will align your installation of Git with the broad direction of the global developer community, and the "main" branch will be used through the remainder of this tutorial. Please see https://sfconservancy.org/news/2020/jun/23/gitbranchname/ and https://github.com/github/renaming for further discussion of this subject. + +{% filename %}command-line{% endfilename %} + + $ git config --global --add init.defaultBranch main + + \ No newline at end of file diff --git a/pl/deploy/pythonanywhere.md b/pl/deploy/pythonanywhere.md new file mode 100644 index 00000000000..d3d63ae6ae4 --- /dev/null +++ b/pl/deploy/pythonanywhere.md @@ -0,0 +1,88 @@ +# Setting up our blog on PythonAnywhere + +## Sign up for a PythonAnywhere account + +> **Note** You might have already created a PythonAnywhere account earlier during the install steps – if so, no need to do it again. +> +> {% include "/deploy/signup_pythonanywhere.md" %} + + +## Configuring our site on PythonAnywhere + +Go back to the main [PythonAnywhere Dashboard](https://www.pythonanywhere.com/) by clicking on the logo, and choose the option to start a "Bash" console – that's the PythonAnywhere version of a command line, just like the one on your computer. + +![The 'New Console' section on the PythonAnywhere web interface, with a button for 'bash'](images/pythonanywhere_bash_console.png) + +> **Note** PythonAnywhere is based on Linux, so if you're on Windows, the console will look a little different from the one on your computer. Deploying a web app on PythonAnywhere involves pulling down your code from GitHub, and then configuring PythonAnywhere to recognise it and start serving it as a web application. There are manual ways of doing it, but PythonAnywhere provides a helper tool that will do it all for you. Let's install it first: + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ pip{{ book.pa_py_version }} install --user pythonanywhere +``` + +That should print out some things like `Collecting pythonanywhere`, and eventually end with a line saying `Successfully installed (...) pythonanywhere- (...)`. + +Now we run the helper to automatically configure our app from GitHub. Type the following into the console on PythonAnywhere (don't forget to use your GitHub username in place of ``, so that the URL matches the clone URL from GitHub): + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +$ pa_autoconfigure_django.py --python={{ book.pa_py_version }} https://github.com//my-first-blog.git +``` + +As you watch that running, you'll be able to see what it's doing: + +- Downloading your code from GitHub +- Creating a virtualenv on PythonAnywhere, just like the one on your own computer +- Updating your settings file with some deployment settings +- Setting up a database on PythonAnywhere using the `manage.py migrate` command +- Setting up your static files (we'll learn about these later) +- And configuring PythonAnywhere to serve your web app via its API + +On PythonAnywhere all those steps are automated, but they're the same steps you would have to go through with any other server provider. + +The main thing to notice right now is that your database on PythonAnywhere is actually totally separate from your database on your own computer, so it can have different posts and admin accounts. As a result, just as we did on your own computer, we need to initialize the admin account with `createsuperuser`. PythonAnywhere has automatically activated your virtualenv for you, so all you need to do is run: + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +(ola.pythonanywhere.com) $ python manage.py createsuperuser +``` + +Type in the details for your admin user. Best to use the same ones as you're using on your own computer to avoid any confusion, unless you want to make the password on PythonAnywhere more secure. + +Now, if you like, you can also take a look at your code on PythonAnywhere using `ls`: + +{% filename %}PythonAnywhere command-line{% endfilename %} +``` +(ola.pythonanywhere.com) $ ls +blog db.sqlite3 manage.py mysite requirements.txt static +(ola.pythonanywhere.com) $ ls blog/ +__init__.py __pycache__ admin.py apps.py migrations models.py +tests.py views.py +``` + +You can also go to the "Files" page and navigate around using PythonAnywhere's built-in file browser. (From the Console page, you can get to other PythonAnywhere pages from the menu button in the upper right corner. Once you're on one of the pages, there are links to the other ones near the top.) + + +## You are now live! + +Your site should now be live on the public Internet! Click through to the PythonAnywhere "Web" page to get a link to it. You can share this with anyone you want. :) + + +> **Note** This is a beginners' tutorial, and in deploying this site we've taken a few shortcuts which aren't ideal from a security point of view. If and when you decide to build on this project, or start a new project, you should review the [Django deployment checklist](https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/) for some tips on securing your site. + +## Debugging tips + + +If you see an error while running the `pa_autoconfigure_django.py` script, here are a few common causes: + +- Forgetting to create your PythonAnywhere API token. +- Making a mistake in your GitHub URL +- If you see an error saying *"Could not find your settings.py"*, it's probably because you didn't manage to add all your files to Git, and/or you didn't push them up to GitHub successfully. Have another look at the Git section above +- If you previously signed up for a PythonAnywhere account and had an error with collectstatic, you probably have an older version of SQLite (eg 3.8.2) for your account. In that case, sign up for a new account and try the commands in the PythonAnywhere section above. + + +If you see an error when you try to visit your site, the first place to look for some debugging info is in your **error log**. You'll find a link to this on the PythonAnywhere ["Web" page](https://www.pythonanywhere.com/web_app_setup/). See if there are any error messages in there; the most recent ones are at the bottom. + +There are also some [general debugging tips on the PythonAnywhere help site](http://help.pythonanywhere.com/pages/DebuggingImportError). + +And remember, your coach is here to help! diff --git a/pl/deploy/signup_pythonanywhere.md b/pl/deploy/signup_pythonanywhere.md old mode 100755 new mode 100644 diff --git a/pl/django/README.md b/pl/django/README.md old mode 100755 new mode 100644 index ebf1180f23d..d2b2903fd90 --- a/pl/django/README.md +++ b/pl/django/README.md @@ -20,7 +20,7 @@ Kiedy serwer otrzymuje żądanie, przekazuje je dalej do Django, aby ten ustali Wyobraź sobie listonosza niosącego list. Idzie ulicą i porównuje każdy numer domu z adresem na kopercie. List zostawia w skrzynce tego domu, którego adres pasuje. Tak samo działa urlresolver! -W funkcji *widoku* dzieje się wszystko to, co najciekawsze: tutaj możemy połączyć się z bazą danych i wyszukać potrzebne nam informacje. Może użytkownik poprosił o zmianę danych? To tak, jakbyś wysłała list o treści "proszę o zmianę opisu mojego stanowiska pracy". *Widok* może sprawdzić, czy masz takie uprawnienia, a następnie dokona zmiany opisu i odeśle odpowiedź "Zrobione!". Wówczas *widok*generuje odpowiedź, a Django wysyła ją do przeglądarki użytkownika. +W funkcji *widoku* dzieje się wszystko to, co najciekawsze: tutaj możemy połączyć się z bazą danych i wyszukać potrzebne nam informacje. Może użytkownik poprosił o zmianę danych? To tak, jakbyś wysłała list o treści "proszę o zmianę opisu mojego stanowiska pracy". *Widok* może sprawdzić, czy masz takie uprawnienia, a następnie dokona zmiany opisu i odeśle odpowiedź "Zrobione!". Wówczas *widok* generuje odpowiedź, a Django wysyła ją do przeglądarki użytkownika. Powyższy opis jest nieco uproszczony, ale znajomość niuansów technicznych nie jest Ci na razie potrzebna. Wystarczy, że zrozumiesz ogólną zasadę działania. diff --git a/pl/django_admin/README.md b/pl/django_admin/README.md old mode 100755 new mode 100644 index 45176db36aa..95e3b70bace --- a/pl/django_admin/README.md +++ b/pl/django_admin/README.md @@ -52,6 +52,6 @@ Upewnij się, że co najmniej dwa lub trzy posty (ale nie wszystkie) mają ustaw ![Admin Django](images/edit_post3.png) -Jeśli chcesz dowiedzieć się więcej o panelu admina Django, powinnaś sprawdzić dokumentację Django: https://docs.djangoproject.com/en/2.0/ref/contrib/admin/ +If you want to know more about Django admin, you should check Django's documentation: https://docs.djangoproject.com/en/3.2/ref/contrib/admin/ Jest to prawdopodobnie dobry moment, aby wziąć kawę (lub herbatę) lub coś do jedzenia, aby ponownie naładować się energią. Stworzyłaś swój pierwszy model Django - zasługujesz na małą przerwę! \ No newline at end of file diff --git a/pl/django_forms/README.md b/pl/django_forms/README.md old mode 100755 new mode 100644 index e6ed0cb04bb..3715b421e36 --- a/pl/django_forms/README.md +++ b/pl/django_forms/README.md @@ -44,52 +44,64 @@ Oto co za chwilę stworzymy: link do strony, adres URL, widok i szablon. ## Odnośnik do strony z formularzem -Czas otworzyć plik `blog/templates/blog/base.html` w edytorze kodu. Dodajmy wiersz w `div` o nazwie `page-header`: +Before we add the link, we need some icons to use as buttons for the link. For this tutorial, download [file-earmark-plus.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/file-earmark-plus.svg) and save it in the folder `blog/templates/blog/icons/` + +> Note: To download the SVG image, open the context menu on the link (usually by right-clicking on it) and select "Save link as". In the dialog asking you where to save the file, navigate to the `djangogirls` directory of your Django project, and within that to subdirectory `blog/templates/blog/icons/`, and save the file there. + +It's time to open `blog/templates/blog/base.html` in the code editor. Now we can use this icon file inside the base template as follows. In the `div` element inside `header` section, we will add a link before the `h1` element: {% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Zauważ, że chcemy odwołać się do naszego nowego widoku `post_new`. Klasa `"glyphicon glyphicon-plus"` jest dostarczana przez motyw z bootstrapa, którego używamy i wyświetli nam znak plus. +Note that we want to call our new view `post_new`. The [SVG icon](https://icons.getbootstrap.com/icons/file-earmark-plus/) is provided by the [Bootstrap Icons](https://icons.getbootstrap.com/) and it will display a page icon with plus sign. We use a Django template directive called `include`. This will inject the file's content into the Django template. The web browser knows how to handle this type of content without any further processing. + +> You can download all the Bootstrap icons [here](https://github.com/twbs/icons/releases/download/v1.1.0/bootstrap-icons-1.1.0.zip). Unzip the file and copy all the SVG image files into a new folder inside `blog/templates/blog/` called `icons`. That way you can access an icon like `pencil-fill.svg` using the file path `blog/templates/blog/icons/pencil-fill.svg` -Po dodaniu powyższej linii Twój plik HTML powinien wyglądać następująco: +After editing the line, your HTML file should now look like this: {% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% load static %} + Django Girls blog - - + - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` -Po zapisaniu i odświeżeniu strony http://127.0.0.1:8000 zobaczyłaś znajomo wyglądający błąd `NoReverseMatch`, zgadza się? OK! +After saving and refreshing the page http://127.0.0.1:8000 you will see a familiar `NoReverseMatch` error. Is that the case? Good! ## Adres URL -Otwieramy plik `blog/urls.py` w edytorze kodu i dodajemy wiersz: +We open `blog/urls.py` in the code editor and add a line: {% filename %}blog/urls.py{% endfilename %} @@ -97,7 +109,7 @@ Otwieramy plik `blog/urls.py` w edytorze kodu i dodajemy wiersz: path('post/new', views.post_new, name='post_new'), ``` -Ostatecznie kod będzie wyglądał tak: +And the final code will look like this: {% filename %}blog/urls.py{% endfilename %} @@ -112,11 +124,11 @@ urlpatterns = [ ] ``` -Po odświeżeniu strony zobaczymy błąd `AttributeError`, ponieważ nie mamy jeszcze zaimplementowanego widoku `post_new`. Dodajmy go teraz. +After refreshing the site, we see an `AttributeError`, since we don't have the `post_new` view implemented. Let's add it right now. ## Widok post_new -Czas otworzyć plik `blog/views.py` w edytorze kodu i dodać poniższe linijki obok innych wierszy z `from`: +Time to open the `blog/views.py` file in the code editor and add the following lines with the rest of the `from` rows: {% filename %}blog/views.py{% endfilename %} @@ -124,7 +136,7 @@ Czas otworzyć plik `blog/views.py` w edytorze kodu i dodać poniższe linijki o from .forms import PostForm ``` -No i nasz *widok*: +And then our *view*: {% filename %}blog/views.py{% endfilename %} @@ -134,20 +146,20 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Aby stworzyć nowy formularz dla modelu `Post`, musimy wywołać funkcję `PostForm()` i przekazać ją do szablonu. Do tego *widoku* jeszcze wrócimy, ale póki co, stwórzmy szybko szablon dla formularza. +To create a new `Post` form, we need to call `PostForm()` and pass it to the template. We will go back to this *view*, but for now, let's quickly create a template for the form. ## Szablon -Musimy utworzyć plik `post_edit.html` w katalogu `blog/templates/blog` i otowrzyć go w edytorze kodu. Aby nasz formularz zadziałał, niezbędnych jest kilka rzeczy: +We need to create a file `post_edit.html` in the `blog/templates/blog` directory, and open it in the code editor. To make a form work we need several things: * Musimy wyświetlić formularz. Możemy to zrobić np. za pomocą polecenia {% raw %}`{{ form.as_p }}`{% endraw %}. -* Powyższa linijka musi znajdować się wewnątrz znacznika formularza HTML: <`form method="POST">...`. +* The line above needs to be wrapped with an HTML form element: `
...
`. * Potrzebny nam przycisk `Zapisz`. Tworzymy go jako przycisk w HTML: ``. * I na koniec jeszcze, zaraz po znaczniku otwierającym `
`musimy dodać {% raw %}`{% csrf_token %}`{% endraw %}. To bardzo ważne, gdyż ta linijka sprawia, że Twoje formularze są bezpieczne! Jeśli o tym zapomnisz i spróbujesz zapisać formularz, Django nie pozostawi tego bez komentarza: -![Strona CSRF Forbidden](images/csrf2.png) +![CSFR Forbidden page](images/csrf2.png) -OK. Podsumujmy, jak powinien wyglądać kod HTML w pliku `post_edit.html`: +OK, so let's see how the HTML in `post_edit.html` should look: {% filename %}blog/templates/blog/post_edit.html{% endfilename %} @@ -158,24 +170,24 @@ OK. Podsumujmy, jak powinien wyglądać kod HTML w pliku `post_edit.html`:

New post

{% csrf_token %} {{ form.as_p }} - +
{% endblock %} ``` -Czas odświeżyć stronę! Hura! Twój formularz został wyświetlony! +Time to refresh! Yay! Your form is displayed! -![Nowy formularz](images/new_form2.png) +![New form](images/new_form2.png) -Ale zaraz, zaraz! Co się stanie, gdy wpiszesz coś w pola z `tytułem` i `treścią`, a następnie spróbujesz to zapisać? +But, wait a minute! When you type something in the `title` and `text` fields and try to save it, what will happen? -Nic! Znów jesteśmy na tej samej stronie, a nasza treść zniknęła... a nowego wpisu nie ma. Co poszło źle? +Nothing! We are once again on the same page and our text is gone… and no new post is added. So what went wrong? -Odpowiedź brzmi: nic. Mamy coś jeszcze do zrobienia w naszym *widoku*. +The answer is: nothing. We need to do a little bit more work in our *view*. ## Zapisujemy formularz -Otwórz jeszcze raz plik `blog/views.py`. w edytorze kodu. W tym momencie wszystko, co mamy w widoku `post_new` to: +Open `blog/views.py` once again in the code editor. Currently all we have in the `post_new` view is the following: {% filename %}blog/views.py{% endfilename %} @@ -185,9 +197,9 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Gdy prześlemy formularz, wracamy do tego samego widoku, ale tym razem mamy nieco więcej danych w zapytaniu (zmiennej `request`) - a dokładnie w `request.POST` (Nazwa POST nie ma nic wspólnego z naszymi blogowymi postami. POST wzięło się od angielskiego czasownika "post", który oznacza wysłać, nadać). Pamiętasz, że w pliku HTML nasza definicja `
` zawierała atrybut `method="POST"`? Wszystkie pola z formularza znajdują się teraz w `request.POST`. Nie zmieniaj nazwy `POST` na cokolwiek innego (inną prawidłową wartością dla `method` jest `GET`, ale nie mamy czasu na omawianie różnic). +When we submit the form, we are brought back to the same view, but this time we have some more data in `request`, more specifically in `request.POST` (the naming has nothing to do with a blog "post"; it's to do with the fact that we're "posting" data). Remember how in the HTML file, our `` definition had the variable `method="POST"`? All the fields from the form are now in `request.POST`. You should not rename `POST` to anything else (the only other valid value for `method` is `GET`, but we have no time to explain what the difference is). -A więc w naszym *widoku* mamy dwie oddzielne sytuacje do obsłużenia. Pierwsza: gdy wchodzimy na stronę po raz pierwszy i chcemy pusty formularz. Druga: gdy ponownie znajdziemy się w *widoku* wraz ze wszystkimi danymi wpisanymi przez nas w formularzu. Czyli musimy dodać wyrażenie warunkowe (użyjemy do tego `if`): +So in our *view* we have two separate situations to handle: first, when we access the page for the first time and we want a blank form, and second, when we go back to the *view* with all form data we just typed. So we need to add a condition (we will use `if` for that): {% filename %}blog/views.py{% endfilename %} @@ -198,7 +210,7 @@ else: form = PostForm() ``` -To jest czas na uzupełnienie kropek `[...]`. Jeżeli zmienna `method` jest równa `POST`, to chcemy zbudować formularz `PostForm` z danymi z formularza, zgadza się? Możemy zrobić to następująco: +It's time to fill in the dots `[...]`. If `method` is `POST` then we want to construct the `PostForm` with data from the form, right? We will do that as follows: {% filename %}blog/views.py{% endfilename %} @@ -206,9 +218,9 @@ To jest czas na uzupełnienie kropek `[...]`. Jeżeli zmienna `method` jest rów form = PostForm(request.POST) ``` -Następnie sprawdźmy, czy formularz jest wypełniony poprawnie (wszystkie wymagane pola są uzupełnione i żadna nieprawidłowa wartość nie zostanie zapisana). Użyjmy do tego `form.is_valid()`. +The next thing is to check if the form is correct (all required fields are set and no incorrect values have been submitted). We do that with `form.is_valid()`. -Sprawdzamy, czy formularz jest wypełniony poprawnie. Jeśli tak, możemy go zapisać! +We check if the form is valid and if so, we can save it! {% filename %}blog/views.py{% endfilename %} @@ -220,9 +232,9 @@ if form.is_valid(): post.save() ``` -Tak właściwie robimy teraz dwie rzeczy: zapisujemy formularz przy pomocy `form.save` oraz dodajemy autora (jako że nasz `PostForm` nie zawierał pola `author`, a jest ono wymagane). `commit=False` sygnalizuje, że jeszcze nie chcemy zapisywać modelu `Post` - najpierw chcemy dodać autora. Przez większość czasu będziesz używała `form.save()` bez `commit=False`, ale w tym przypadku musimy zrobić to w ten sposób. `post.save()` zachowa zmiany (razem z dodanym autorem) i nasz nowy wpis na blogu jest gotowy! +Basically, we have two things here: we save the form with `form.save` and we add an author (since there was no `author` field in the `PostForm` and this field is required). `commit=False` means that we don't want to save the `Post` model yet – we want to add the author first. Most of the time you will use `form.save()` without `commit=False`, but in this case, we need to supply it. `post.save()` will preserve changes (adding the author) and a new blog post is created! -Ostatecznie, byłoby wspaniale, gdybyśmy mogły przejść od razu na stronę `post_detail` i zobaczyć nasz nowy wpis, prawda? Aby to było możliwe, potrzebujemy jeszcze jednego importu: +Finally, it would be awesome if we could immediately go to the `post_detail` page for our newly created blog post, right? To do that we need one more import: {% filename %}blog/views.py{% endfilename %} @@ -230,7 +242,7 @@ Ostatecznie, byłoby wspaniale, gdybyśmy mogły przejść od razu na stronę `p from django.shortcuts import redirect ``` -Dodaj go na samym początku pliku. I teraz możemy powiedzieć: "przejdź na stronę `post_detail`, żeby zobaczyć nowo utworzony wpis": +Add it at the very beginning of your file. And now we can say, "go to the `post_detail` page for the newly created post": {% filename %}blog/views.py{% endfilename %} @@ -238,9 +250,9 @@ Dodaj go na samym początku pliku. I teraz możemy powiedzieć: "przejdź na str return redirect('post_detail', pk=post.pk) ``` -`post_detail` to nazwa widoku, do którego chcemy przejść. Pamiętasz, że ten *widok* potrzebuje zmiennej `pk`? Aby ją przekazać do widoków stosujemy `pk=post.pk`, gdzie `post` jest nowo utworzonym wpisem! +`post_detail` is the name of the view we want to go to. Remember that this *view* requires a `pk` variable? To pass it to the views, we use `pk=post.pk`, where `post` is the newly created blog post! -No dobrze, pogadałyśmy sobie, to może teraz zobaczymy, jak wygląda cały nasz *widok*, co? +OK, we've talked a lot, but we probably want to see what the whole *view* looks like now, right? {% filename %}blog/views.py{% endfilename %} @@ -259,39 +271,45 @@ def post_new(request): return render(request, 'blog/post_edit.html', {'form': form}) ``` -Zobaczmy, czy zadziała. Przejdź na stronę http://127.0.0.1:8000/post/new/, dodaj `tytuł` i `tekst`, zapisz... i voilà! Nowy wpis został dodany, a my zostałyśmy przekierowane na stronę `post_detail`! +Let's see if it works. Go to the page http://127.0.0.1:8000/post/new/, add a `title` and `text`, save it… and voilà! The new blog post is added and we are redirected to the `post_detail` page! -Zapewne dostrzegłaś, że ustalamy datę publikacji przed zapisaniem postu. Później wprowadzimy przycisk publikacji *publish* w kursie **Django Girls: Rozszerzenia**. +You might have noticed that we are setting the publish date before saving the post. Later on, we will introduce a *publish button* in **Django Girls Tutorial: Extensions**. -Wspaniale! +That is awesome! -> Jako że niedawno używałyśmy interfejsu admina Django, system w tym momencie jest przekonany, że jesteśmy zalogowane. Niektóre sytuacje mogą doprowadzić do tego, że zostaniemy wylogowane (np. zamknięcie przeglądarki czy restart bazy danych, itd.). Jeżeli zauważysz, że przy tworzeniu wpisu pojawia się błąd związany z brakiem zalogowanego użytkownika, przejdź na stronę stronę panelu admina http://127.0.0.1:8000/admin i zaloguj się jeszcze raz. Na pewien czas problem się rozwiąże. W rozdziale **Praca domowa: zabezpiecz swoją stronę!** - zaraz po głównym kursie - czeka na Ciebie permanentne rozwiązanie tego problemu. +> As we have recently used the Django admin interface, the system currently thinks we are still logged in. There are a few situations that could lead to us being logged out (closing the browser, restarting the DB, etc.). If, when creating a post, you find that you are getting errors referring to the lack of a logged-in user, head to the admin page http://127.0.0.1:8000/admin and log in again. This will fix the issue temporarily. There is a permanent fix awaiting you in the **Homework: add security to your website!** chapter after the main tutorial. -![Błąd logowania użytkownika](images/post_create_error.png) +![Logged in error](images/post_create_error.png) ## Walidacja formularza -Teraz pokażemy Ci, jak fajne potrafią być formularze w Django. Wpis na blogu potrzebuje uzupełnionych pól `title` i `text`. W naszym modelu `Post` nie powiedzieliśmy (z wyjątkiem `published_date`), że te pola nie są wymagane, więc Django domyślnie uważa, że muszą zostać wypełnione. +Now, we will show you how cool Django forms are. A blog post needs to have `title` and `text` fields. In our `Post` model we did not say that these fields (as opposed to `published_date`) are not required, so Django, by default, expects them to be set. -Spróbuj zapisać formularz bez uzupełnionych pól `title` i `text`. Zgadnij, co się stanie? +Try to save the form without `title` and `text`. Guess what will happen! -![Walidacja formularza](images/form_validation2.png) +![Form validation](images/form_validation2.png) -Django dba o walidację pól w naszym formularzu, upewniając się, czy są uzupełnione poprawnie. Prawda, że niesamowite? +Django is taking care to validate that all the fields in our form are correct. Isn't it awesome? ## Edycja formularza -Teraz już wiemy, jak dodać nowy formularz. Ale co w przypadku, gdy zapragniemy zmienić już istniejący? Proces jest bardzo podobny do tego, który przeszłyśmy przed chwilą. Stwórzmy szybko kilka ważnych rzeczy. (jeżeli masz problem ze zrozumieniem czegoś, zapytaj osobę prowadzącą kurs lub przejrzyj poprzednie rozdziały, gdyż wszystkie kroki mamy już omówione.) +Now we know how to add a new post. But what if we want to edit an existing one? This is very similar to what we just did. Let's create some important things quickly. (If you don't understand something, you should ask your coach or look at the previous chapters, since we covered all these steps already.) + +First, let's save the icon which represents the edit button. Download [pencil-fill.svg](https://raw.githubusercontent.com/twbs/icons/main/icons/pencil-fill.svg) and save it to the location `blog/templates/blog/icons/`. -Otwórz `blog/templates/blog/post_detail.html` w edytorze kodu i dodaj poniższą linijkę +Open `blog/templates/blog/post_detail.html` in the code editor and add the following code inside `article` element: {% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html - + ``` -dzięki czemu nasz szablon będzie wyglądał tak: +so that the template will look like this: {% filename %}blog/templates/blog/post_detail.html{% endfilename %} @@ -299,20 +317,24 @@ dzięki czemu nasz szablon będzie wyglądał tak: {% extends 'blog/base.html' %} {% block content %} -
+
+ {% endblock %} ``` -Otwieramy plik `blog/urls.py` w edytorze kodu dodajemy wiersz: +Open `blog/urls.py` in the code editor, and add this line: {% filename %}blog/urls.py{% endfilename %} @@ -320,9 +342,9 @@ Otwieramy plik `blog/urls.py` w edytorze kodu dodajemy wiersz: path('post//edit/', views.post_edit, name='post_edit'), ``` -Wykorzystamy jeszcze raz szablon `blog/templates/blog/post_edit.html`, więc ostatnią rzeczą, której nam brakuje, jest *widok*. +We will reuse the template `blog/templates/blog/post_edit.html`, so the last missing thing is a *view*. -Otwórz `blog/views.py` w edytorze kodu i dodaj poniższy kod na samym końcu tego pliku: +Let's open `blog/views.py` in the code editor and add this at the very end of the file: {% filename %}blog/views.py{% endfilename %} @@ -342,7 +364,7 @@ def post_edit(request, pk): return render(request, 'blog/post_edit.html', {'form': form}) ``` -To wygląda prawie tak samo, jak nasz widok `post_new`, nieprawdaż? Ale nie do końca. Po pierwsze: przekazujemy dodatkowy parametr `pk` z urls. Dalej - pobieramy model wpisu `Post` do edycji za pomocą `get_object_or_404(Post, pk=pk)`. Gdy tworzymy formularz, przekazujemy ten wpis pod zmienną `instance` zarówno w trakcie zapisywania formularza… +This looks almost exactly the same as our `post_new` view, right? But not entirely. For one, we pass an extra `pk` parameter from `urls`. Next, we get the `Post` model we want to edit with `get_object_or_404(Post, pk=pk)` and then, when we create a form, we pass this post as an `instance`, both when we save the form… {% filename %}blog/views.py{% endfilename %} @@ -350,7 +372,7 @@ To wygląda prawie tak samo, jak nasz widok `post_new`, nieprawdaż? Ale nie do form = PostForm(request.POST, instance=post) ``` -…jak i zaraz po otwarciu formularza z wpisem do edycji: +…and when we've just opened a form with this post to edit: {% filename %}blog/views.py{% endfilename %} @@ -358,76 +380,84 @@ form = PostForm(request.POST, instance=post) form = PostForm(instance=post) ``` -OK. Przetestujmy, jak to działa! Przejdź na stronę `post_detail`. W górnym prawym rogu powinnaś znaleźć przycisk edycji: +OK, let's test if it works! Let's go to the `post_detail` page. There should be an edit button in the top-right corner: -![Przycisk edycji](images/edit_button2.png) +![Edit button](images/edit_button2.png) -Po kliknęciu w niego zobaczysz formularz z naszym wpisem: +When you click it you will see the form with our blog post: -![Edycja formularza](images/edit_form2.png) +![Edit form](images/edit_form2.png) -Zmodyfikuj jego tytuł lub treść wedle uznania, a następnie zapisz zmiany! +Feel free to change the title or the text and save the changes! -Gratulacje! Twoja aplikacja staje się coraz bardziej kompletna! +Congratulations! Your application is getting more and more complete! -Jeżeli potrzebujesz więcej informacji o formularzach Django, zajrzyj do dokumentacji: https://docs.djangoproject.com/en/2.0/topics/forms/ +If you need more information about Django forms, you should read the documentation: https://docs.djangoproject.com/en/3.2/topics/forms/ ## Bezpieczeństwo -Super, że możemy tworzyć posty klikając w link! Jest niestety jeden problem - aktualnie każdy, kto odwiedzi Twoją stronę, może stworzyć nowy post. Zróbmy tak, aby przycisk był widoczny tylko dla Ciebie i nikogo innego. +Being able to create new posts by clicking a link is awesome! But right now, anyone who visits your site will be able to make a new blog post, and that's probably not something you want. Let's make it so the button shows up for you but not for anyone else. -Otwórzmy `blog/templates/blog/base.html` w edytorze kodu, znajdźmy nasz `page-header` `div` i zalinkujmy tag, który umieściłyśmy tam wcześniej. Powinien wyglądać tak: +Open `blog/templates/blog/base.html` in the code editor, find our `div` inside `header` and the anchor element you put in there earlier. It should look like this: {% filename %}blog/templates/blog/base.html{% endfilename %} ```html - + + {% include './icons/file-earmark-plus.svg' %} + ``` -Dodamy kolejny tag `{% if %}`, który sprawi, że link będzie widoczny tylko dla użytkowników zalogowanych jako admin. W tej grupie na razie jesteś tylko Ty! Zmień `` tag, by wyglądał w ten sposób: +We're going to add another `{% if %}` tag to this, which will make the link show up only for users who are logged into the admin. Right now, that's just you! Change the `` element to look like this: {% filename %}blog/templates/blog/base.html{% endfilename %} ```html {% if user.is_authenticated %} - + + {% include './icons/file-earmark-plus.svg' %} + {% endif %} ``` -Ten `{% if %}` spowoduje, że link zostanie wysłany do przeglądarki tylko wtedy, kiedy użytkownik chcący wyświetlić tę stronę jest zalogowany. To nie chroni tworzenia wpisów w 100%, ale jest to dobry pierwszy krok. Zagadnieniu bezpieczeństwa poświęcimy więcej miejsca w rozszerzeniu do tego kursu. +This `{% if %}` will cause the link to be sent to the browser only if the user requesting the page is logged in. This doesn't protect the creation of new posts completely, but it's a good first step. We'll cover more security in the extension lessons. -Pamiętasz ikonkę edycji, która przed chwilą dodałyśmy do naszej strony szczegółów? Chcemy też dodać tę samą zmianę tutaj tak, by inne osoby nie były w stanie edytować istniejących postów. +Remember the edit icon we just added to our detail page? We also want to add the same change there, so other people won't be able to edit existing posts. -Otwórzmy `blog/templates/blog/post_detail.html` w edytorze kodu i dodajmy poniższą linijkę: +Open `blog/templates/blog/post_detail.html` in the code editor and find this line: {% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html - + + {% include './icons/pencil-fill.svg' %} + ``` -Zamień ją na: +Change it to this: {% filename %}blog/templates/blog/post_detail.html{% endfilename %} ```html {% if user.is_authenticated %} - + + {% include './icons/pencil-fill.svg' %} + {% endif %} ``` -Ponieważ jesteś najprawdopodobniej zalogowana, jeżeli odświeżysz stronę, nie zobaczysz żadnej zmiany. Podejrzyj stronę w innej przeglądarce lub chociaż w trybie incognito (nazywanym "InPrivate" w Windows Edge) i zobaczysz, że ten link i ikonka się nie pojawiają! +Since you're likely logged in, if you refresh the page, you won't see anything different. Load the page in a different browser or an incognito window (called "InPrivate" in Windows Edge), though, and you'll see that the link doesn't show up, and the icon doesn't display either! ## Jeszcze jedno: czas na wdrożenie! -Dobrze byłoby wiedzieć, że nasza witryna nadal działa na PythonAnywhere, prawda? +Let's see if all this works on PythonAnywhere. Time for another deploy! * Po pierwsze zapiszmy nasze zmiany i wyślijmy je na GitHuba: {% filename %}command-line{% endfilename %} $ git status - $ git add --all . + $ git add . $ git status $ git commit -m "Added views to create/edit blog post inside the site." $ git push @@ -442,8 +472,8 @@ Dobrze byłoby wiedzieć, że nasza witryna nadal działa na PythonAnywhere, pra [...] -(Pamiętaj by podmienić `` na Twoją właściwą nazwę użytkownika PythonAnywhere, bez nawiasów ostrokątnych). +(Remember to substitute `` with your actual PythonAnywhere subdomain, without the angle-brackets.) * Nareszcie przeskakujemy do do ["Web" page](https://www.pythonanywhere.com/web_app_setup/) (użyj przycisku menu w prawym górnym rogu konsoli) i naciśnij **Reload**. Odśwież swój blog https://yourname.pythonanywhere.com, aby zobaczyć zmiany. -I to już wszystko! Gratulacje :) \ No newline at end of file +And that should be it. Congrats! :) \ No newline at end of file diff --git a/pl/django_installation/README.md b/pl/django_installation/README.md index b68fba400f9..ab5473fe08b 100644 --- a/pl/django_installation/README.md +++ b/pl/django_installation/README.md @@ -2,6 +2,6 @@ > **Uwaga** Jeśli używasz już Chromebooka, pomiń ten rozdział i upewnij się, że postąpiłeś zgodnie z instrukcją [Instalowanie Chromebook](../chromebook_setup/README.md). > -> **Uwaga** Jeśli wykonałaś krok Instalacja, to masz już wszystko zrobione - możesz przejść od razu do następnego kroku! +> **Note** If you already worked through the [installation steps](../installation/README.md) then you've already done this – you can go straight to the next chapter! {% include "/django_installation/instructions.md" %} \ No newline at end of file diff --git a/pl/django_installation/instructions.md b/pl/django_installation/instructions.md old mode 100755 new mode 100644 index 9449f22b4f8..9ced476660f --- a/pl/django_installation/instructions.md +++ b/pl/django_installation/instructions.md @@ -37,7 +37,7 @@ Aby utworzyć nowego `virtualenv`'a, musisz otworzyć okno wiersza polecenia i w C:\Users\Name\djangogirls> python -m venv myvenv -Gdzie `myvenv` to nazwa Twojego `virtualenv`'a. Nazwa może być dowolna, ale lepiej używać tylko małych liter, bez spacji i polskich znaków. Dobrze jest też trzymać się krótkich nazw - będziesz do nich często wracała! +Gdzie `myvenv` to nazwa Twojego `virtualenv`'a. Nazwa może być dowolna, ale lepiej używać tylko małych liter, bez spacji i polskich znaków. It is also a good idea to keep the name short – you'll be referencing it a lot! @@ -79,7 +79,7 @@ Możemy stworzyć `virtualenv`'a w Linuksie i OS X poprzez użycie jedynie polec > {% filename %}command-line{% endfilename %} > > $ sudo apt install python-virtualenv -> $ virtualenv --python=python3.6 myvenv +> $ virtualenv --python=python{{ book.py_version }} myvenv > > > **UWAGA:** Jeśli wystąpi błąd taki jak @@ -93,14 +93,14 @@ Możemy stworzyć `virtualenv`'a w Linuksie i OS X poprzez użycie jedynie polec > > {% filename %}command-line{% endfilename %} > -> sudo apt install python3.6-venv +> sudo apt install python{{ book.py_version }}-venv > ## Praca z virtualenv -Powyższa instrukcja utworzy katalog o nazwie `myvenv` (albo o nazwie, którą wybrałaś) zawierający nasze środowisko wirtualne (czyli w zasadzie zbiór katalogów i plików). +The command above will create a directory called `myvenv` (or whatever name you chose) that contains our virtual environment (basically a bunch of directories and files). @@ -112,7 +112,7 @@ Uruchom wirtualne środowisko za pomocą polecenia: C:\Użytkownicy\Nazwa\djangogirls> myvenv\Scripts\activate -> **Uwaga:** W systemie Windows 10 możesz otrzymać błąd w programie Windows PowerShell, który mówi, `wykonywanie skryptów jest wyłączone w tym systemie`. W tym przypadku, otwórz inny Windows PowerShell z opcją "Uruchom jako Administrator". Następnie spróbuj, wpisując następujące polecenie przed rozpoczęciem środowiska wirtualnego: +> **NOTE:** On Windows 10 you might get an error in the Windows PowerShell that says `execution of scripts is disabled on this system`. W tym przypadku, otwórz inny Windows PowerShell z opcją "Uruchom jako Administrator". Następnie spróbuj, wpisując następujące polecenie przed rozpoczęciem środowiska wirtualnego: > > {% filename %}command-line{% endfilename %} > @@ -121,6 +121,15 @@ Uruchom wirtualne środowisko za pomocą polecenia: > The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies help topic at http://go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): A > + + +> **NOTE:** For users of the popular editor VS Code, which comes with an integrated terminal based off windows PowerShell, if you wish to stick with the integrated terminal, you may run the following command to activate your virtual environment: +> +> $ . myvenv\Scripts\activate.ps1 +> +> +> The advantage is that you don't have to switch between editor windows and command-line windows + -O tym, że Twój `virtualenv` jest uruchomiony, dowiesz się, gdy zobaczysz w swojej konsoli prompt poprzedzony przedrostkiem `(myvenv)`. +You will know that you have `virtualenv` started when you see that the prompt in your console is prefixed with `(myvenv)`. -W trakcie pracy ze środowiskiem wirtualnym `python` będzie automatycznie odnosił się do właściwej wersji, dzięki czemu możesz używać polecenia `python` zamiast `python3`. +When working within a virtual environment, `python` will automatically refer to the correct version so you can use `python` instead of `python3`. -Świetnie, wszystkie potrzebne elementy są już gotowe. Nareszcie możemy zainstalować Django! +OK, we have all important dependencies in place. We can finally install Django! -## Instalowanie Django +## Installing Django {#django} -Teraz, gdy Twój `virtualenv` jest już uruchomiony, możesz zainstalować Django. +Now that you have your `virtualenv` started, you can install Django. -Zanim jednak to zrobimy, powinniśmy się upewnić, że mamy najnowszą wersję `pip`, oprogramowania, które używamy do zainstalowania Django: +Before we do that, we should make sure we have the latest version of `pip`, the software that we use to install Django: {% filename %}command-line{% endfilename %} @@ -163,28 +172,30 @@ Zanim jednak to zrobimy, powinniśmy się upewnić, że mamy najnowszą wersję ### Instalacja pakietów z pliku wymagań -Plik wymagań zawiera listę zależności, które zainstalujemy za pomocą polecenia `pip install`: +A requirements file keeps a list of dependencies to be installed using `pip install`: -Najpierw stwórz plik `requirements.txt` wewnątrz katalogu `djangogirls/` używając edytora kodu, który wcześniej zainstalowałaś. Aby to zrobić, otwórz nowy plik w edytorze kodu, a następnie zapisz go jako ` requirements.txt ` w folderze ` djangogirls / . Twój katalog będzie wyglądał następująco:

+First create a `requirements.txt` file inside of the `djangogirls/` folder, using the code editor that you installed earlier. You do this by opening a new file in the code editor and then saving it as `requirements.txt` in the `djangogirls/` folder. Your directory will look like this: -
djangogirls
-└───requirements.txt
-`
+ djangogirls + ├── myvenv + │ └── ... + └───requirements.txt + -W swoim pliku `djangogirls/requirements.txt` powinnaś dodać następujący tekst: +In your `djangogirls/requirements.txt` file you should add the following text: {% filename %}djangogirls/requirements.txt{% endfilename %} Django~={{ book.django_version }} -Teraz możesz uruchomić `pip install -r requirements.txt`, aby zainstalować Django. +Now, run `pip install -r requirements.txt` to install Django. {% filename %}command-line{% endfilename %} (myvenv) ~$ pip install -r requirements.txt Collecting Django~={{ book.django_version }} (from -r requirements.txt (line 1)) - Downloading Django-{{ book.django_version }}-py3-none-any.whl (7.1MB) + Downloading Django-{{ book.django_version }}-py3-none-any.whl (7.9MB) Installing collected packages: Django Successfully installed Django-{{ book.django_version }} @@ -192,14 +203,14 @@ Teraz możesz uruchomić `pip install -r requirements.txt`, aby zainstalować Dj -> Jeżeli w trakcie wywoływania polecenia pip w Windows otrzymasz błąd, sprawdź czy ścieżka Twojego projektu nie zawiera spacji, kresek lub znaków specjalnych (np. `C:\Users\User Name\djangogirls`). Jeżeli tak, sugerujemy przeniesienie projektu do innego katalogu bez spacji, kresek i znaków specjalnych (propnujemy `C:\djangogirls`). Utwórz nowy virtualenv w nowym katalogu, następnie usuń stary i spróbuj ponownie wykonać powyższe polecenie. (Przenoszenie katalogu virtualenv nie będzie działać ponieważ virtualenv używa ścieżek bezwzględnych.) +> If you get an error when calling pip on Windows, please check if your project pathname contains spaces, accents or special characters (for example, `C:\Users\User Name\djangogirls`). If it does, please consider using another place without spaces, accents or special characters (suggestion: `C:\djangogirls`). Create a new virtualenv in the new directory, then delete the old one and try the above command again. (Moving the virtualenv directory won't work since virtualenv uses absolute paths.) -> Twoja linia poleceń może się zamrozić po próbie zainstalowania Django. Jeśli tak się stanie, zamiast powyższego polecenia użyj: +> Your command line might freeze when you try to install Django. If this happens, instead of the above command use: > > {% filename %}command-line{% endfilename %} > @@ -211,8 +222,8 @@ data-collapse=true ces--> -> Jeśli po użyciu polecenia pip w Ubuntu 12.04 otrzymasz błąd, użyj polecenia `python -m pip install -U --force-reinstall pip`, aby naprawić instalacją pip'a w środowisku wirtualnym. +> If you get an error when calling pip on Ubuntu 12.04 please run `python -m pip install -U --force-reinstall pip` to fix the pip installation in the virtualenv. -To wszystko! Teraz (nareszcie) jesteś gotowa do stworzenia aplikacji w Django! \ No newline at end of file +That's it! You're now (finally) ready to create a Django application! \ No newline at end of file diff --git a/pl/django_models/README.md b/pl/django_models/README.md old mode 100755 new mode 100644 index 281c8cb43d0..60c22faf2bb --- a/pl/django_models/README.md +++ b/pl/django_models/README.md @@ -77,26 +77,29 @@ Zauważysz, że nowy katalog `blog` został utworzony i zawiera kilka plików. K djangogirls ├── blog - │   ├── __init__.py │   ├── admin.py │   ├── apps.py + │   ├── __init__.py │   ├── migrations │   │   └── __init__.py │   ├── models.py │   ├── tests.py - | ├── urls.py │   └── views.py ├── db.sqlite3 ├── manage.py ├── mysite + │   ├── asgi.py │   ├── __init__.py │   ├── settings.py │   ├── urls.py │   └── wsgi.py + ├── myvenv + │   └── ... └── requirements.txt + -Po stworzeniu aplikacji, musimy dać znać Django, że powinien jej używać. Robimy to w pliku `mysite/settings.py` - otwórz go w swoim edytorze kodu. Musimy odnaleźć nagłówek `INSTALLED_APPS` i dodać wiersz o treści `'blog',` tuż przed nawiasem zamykającym `]`. Czyli efekt końcowy powinien wyglądać tak: +Po stworzeniu aplikacji, musimy dać znać Django, że powinien jej używać. Robimy to w pliku `mysite/settings.py` - otwórz go w swoim edytorze kodu. We need to find `INSTALLED_APPS` and add a line containing `'blog',` just above `]`. Czyli efekt końcowy powinien wyglądać tak: {% filename %}mysite/settings.py{% endfilename %} @@ -121,13 +124,12 @@ Otwórz plik `blog/models.py` w swoim edytorze kodu, usuń z niego całą zawart {% filename %}blog/models.py{% endfilename %} ```python -from django.conf import settings from django.db import models from django.utils import timezone class Post(models.Model): - author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + author = models.ForeignKey('auth.User', on_delete=models.CASCADE) title = models.CharField(max_length=200) text = models.TextField() created_date = models.DateTimeField( @@ -162,7 +164,7 @@ Teraz dodamy właściwości, o których wspomniałyśmy już wcześniej: `title` - `models.DateTimeField` - to jest data i godzina. - `models.ForeignKey` - to jest odnośnik do innego modelu. -Nie będziemy tutaj wyjaśniać drobiazgowo każdego elementu kodu, gdyż zajęłoby to zbyt dużo czasu. Zajrzyj do dokumentacji Django, jeżeli chcesz dowiedzieć się więcej o polach modelu oraz jak definiować rzeczy inne niż opisane powyżej (https://docs.djangoproject.com/en/2.0/ref/models/fields/#field-types). +Nie będziemy tutaj wyjaśniać drobiazgowo każdego elementu kodu, gdyż zajęłoby to zbyt dużo czasu. Zajrzyj do dokumentacji Django, jeżeli chcesz dowiedzieć się więcej o polach modelu oraz jak definiować typy inne niż opisywane powyżej (https://docs.djangoproject.com/en/3.2/ref/models/fields/#field-types). A co to takiego `def publish(self):`? To jest dokładnie metoda publikująca wpis (`publish`), o której wspominaliśmy wcześniej. Wyraz `def` oznacza, że mamy do czynienia z funkcją/metodą, a `publish` to nazwa metody. Możesz zmienić nazwę metody, jeśli chcesz. Zasadą jest, że używamy małych liter oraz znaków podkreślenia zamiast spacji. Na przykład metodę, która oblicza średnią cenę, można nazwać `calculate_average_price`. @@ -180,9 +182,9 @@ Został nam ostatni krok, a mianowicie dodanie naszego nowego modelu do bazy dan (myvenv) ~/djangogirls$ python manage.py makemigrations blog Migrations for 'blog': - blog/migrations/0001_initial.py: + blog/migrations/0001_initial.py - - Create model Post + - Create model Post **Uwaga:** Pamiętaj, aby zapisać pliki, które edytujesz. W przeciwnym razie Twój komputer wykona poprzednią wersję, która może dać Tobie nieoczekiwane komunikaty o błędach. diff --git a/pl/django_orm/README.md b/pl/django_orm/README.md old mode 100755 new mode 100644 diff --git a/pl/django_start_project/README.md b/pl/django_start_project/README.md old mode 100755 new mode 100644 index ba19ac2d93e..496b881f9d2 --- a/pl/django_start_project/README.md +++ b/pl/django_start_project/README.md @@ -45,13 +45,16 @@ Dla systemu Windows wpisz teraz do swojej konsoli następującą komendę. **Nie `django-admin.py` jest skryptem, który utworzy katalogi i pliki za Ciebie. Powinnaś mieć teraz strukturę katalogów podobną do tej: djangogirls - ├───manage.py - ├───mysite - │ settings.py - │ urls.py - │ wsgi.py - │ __init__.py - └───requirements.txt + ├── manage.py + ├── mysite + │   ├── asgi.py + │   ├── __init__.py + │   ├── settings.py + │   ├── urls.py + │   └── wsgi.py + ├── myvenv + │   └── ... + └── requirements.txt > **Uwaga**: w strukturze katalogów, możesz zobaczyć również katalog `myvenv`, który stworzyłyśmy wcześniej. @@ -80,7 +83,7 @@ W pliku `settings.py` znajdź linijkę, w której jest napisane `TIME_ZONE` i zm TIME_ZONE = 'Europe/Warsaw' ``` -Kod języka składa się z języka, np. ` en ` dla języka angielskiego lub ` de ` dla języka niemieckiego i kodu kraju, np. ` de ` dla Niemiec lub ` ch ` dla Szwajcarii. Jeżeli angielski nie jest Twoim językiem ojczystym, możesz dodać tę wartość, aby domyślne przyciski i powiadomienia od Django będą w Twoim języku. Tak więc przycisk "Anuluj" zostałby przetłumaczony na język, który tu zdefiniowałaś. [Django jest wyposażone w mnóstwo przygotowanych tłumaczeń](https://docs.djangoproject.com/en/2.0/ref/settings/#language-code). +Kod języka składa się z języka, np. ` en ` dla języka angielskiego lub ` de ` dla języka niemieckiego i kodu kraju, np. ` de ` dla Niemiec lub ` ch ` dla Szwajcarii. Jeżeli angielski nie jest Twoim językiem ojczystym, możesz dodać tę wartość, aby domyślne przyciski i powiadomienia od Django będą w Twoim języku. Tak więc przycisk "Anuluj" zostałby przetłumaczony na język, który tu zdefiniowałaś. [Django comes with a lot of prepared translations](https://docs.djangoproject.com/en/3.2/ref/settings/#language-code). Jeżeli chcesz używać innego języka, zmień jego kod, modyfikując następujący wiersz: @@ -96,7 +99,7 @@ Musimy także dodać ścieżkę do plików statycznych. (Dowiemy się więcej o ```python STATIC_URL = '/static/' -STATIC_ROOT = os.path.join(BASE_DIR, 'static') +STATIC_ROOT = BASE_DIR / 'static' ``` Gdy ` DEBUG ` jest ` True ` i ` ALLOWED_HOSTS ` jest puste, host jest sprawdzany pod kątem ` ['localhost', '127.0.0.1', '[::1]']`. To nie będzie pasować do naszej nazwy hosta w PythonAnywhere po wdrożeniu naszej aplikacji, więc zmienimy następujące ustawienie: @@ -110,6 +113,48 @@ ALLOWED_HOSTS = ['127.0.0.1', '.pythonanywhere.com'] > ** Uwaga **: jeśli używasz Chromebooka, dodaj ten wiersz u dołu pliku settings.py: `MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'` > > Dodaj również `.c9users.io` do `ALLOWED_HOSTS`, jeżeli używasz cloud9 +> +> If you are hosting your project on `Glitch.com`, let us protect the Django secret key that needs to remain confidential (otherwise, anyone remixing your project could see it): +> +> - Najpierw utworzymy losowy tajny klucz. Ponownie otwórz terminal Glitch i wpisz następujące polecenie: +> +> {% filename %}command-line{% endfilename %} +> +> ```bash +> python -c 'z django.core.management.utils import get_random_secret_key; \ +> print(get_random_secret_key())' +> ``` +> +> Powinno to wyświetlić długi, losowy ciąg, idealny do użycia jako tajny klucz dla Twojej nowej strony internetowej Django. Najpierw utworzymy losowy tajny klucz. Ponownie otwórz terminal Glitch i wpisz następujące polecenie: +> +> - Utwórz plik .env w katalogu głównym projektu i dodaj do niego następującą właściwość: +> +> {% filename %}.env{% endfilename %} +> +> ```bash +> # Here, inside the single quotes, you can cut and paste the random key generated above +> SECRET='3!0k#7ds5mp^-x$lqs2%le6v97h#@xopab&oj5y7d=hxe511jl' +> ``` +> +> - Then update the Django settings file to inject this secret value and set the Django web site name: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> import os +> +> SECRET_KEY = os.getenv('SECRET') +> ``` +> +> - And a little further down in the same file, we inject the name of your new Glitch website: +> +> {% filename %}mysite/settings.py{% endfilename %} +> +> ```python +> ALLOWED_HOSTS = [os.getenv('PROJECT_DOMAIN') + ".glitch.me"] +> ``` +> +> The `PROJECT_DOMAIN` value is automatically generated by Glitch. It will correspond to the name of your project. ## Inicjalizacja bazy danych @@ -123,7 +168,7 @@ Została ona już ustawiona w tej części pliku `mysite/settings.py`: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'NAME': BASE_DIR / 'db.sqlite3', } } ``` @@ -134,13 +179,13 @@ Aby utworzyć bazę danych dla naszego bloga, wykonajmy następujące polecenie (myvenv) ~/djangogirls$ python manage.py migrate Operations to perform: - Apply all migrations: auth, admin, contenttypes, sessions + Apply all migrations: admin, auth, contenttypes, sessions Running migrations: - Rendering model states... DONE Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK + Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK @@ -150,6 +195,9 @@ Aby utworzyć bazę danych dla naszego bloga, wykonajmy następujące polecenie Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK + Applying auth.0010_alter_group_name_max_length... OK + Applying auth.0011_update_proxy_permissions... OK + Applying auth.0012_alter_user_first_name_max_length... OK Applying sessions.0001_initial... OK @@ -171,35 +219,48 @@ Jeżeli korzystasz z Chromebooka, wykorzystaj komendę poniżej: (myvenv) ~/djangogirls$ python manage.py runserver 0.0.0.0:8080 -Jeśli pracujesz na Windowsie i zobaczysz w tym momencie `UnicodeDecodeError`, użyj następującej komendy: +or this one if you are using Glitch: + +{% filename %}Glitch.com terminal{% endfilename %} + + $ refresh + + + +If you are on Windows and this fails with `UnicodeDecodeError`, use this command instead: {% filename %}command-line{% endfilename %} (myvenv) ~/djangogirls$ python manage.py runserver 0:8000 -Teraz sprawdź, czy Twoja strona działa. Otwórz przeglądarkę (Firefox, Chrome, Safari, Internet Explorer lub jakąkolwiek inną) i wprowadź ten adres: +Now you need to check that your website is running. Open your browser (Firefox, Chrome, Safari, Internet Explorer or whatever you use) and enter this address: {% filename %}browser{% endfilename %} http://127.0.0.1:8000/ -Jeśli używasz Chromebooka i Cloud9, kliknij adres URL w wyskakującym okienku, które powinno pojawić się w prawym górnym rogu okna poleceń, w którym działa serwer WWW. Adres URL powinien wygladąć tak: +If you're using a Chromebook and Cloud9, instead click the URL in the pop-up window that should have appeared in the upper right corner of the command window where the web server is running. The URL will look something like: {% filename %}browser{% endfilename %} https://.vfs.cloud9.us-west-2.amazonaws.com -Gratulacje! Właśnie stworzyłaś swoją pierwszą stronę i uruchomiłaś ją za pomocą serwera! Prawda, że wspaniale? +or on Glitch: + + https://name-of-your-glitch-project.glitch.me + + +Congratulations! You've just created your first website and run it using a web server! Isn't that awesome? ![Install worked!](images/install_worked.png) -Kiedy serwer internetowy jest uruchomiony, nie możesz zobaczyć nowego wiersza polecenia do wprowadzania dodatkowych poleceń. Terminal przyjmie nowy tekst, ale nie wykona nowego polecenia. Dzieje się tak dlatego, że serwer internetowy ciągle działa oraz oczekuje nowych żądań. +Note that a command window can only run one thing at a time, and the command window you opened earlier is running the web server. As long as the web server is running and waiting for additional incoming requests, the terminal will accept new text but will not execute new commands. > Sprawdziliśmy, jak działają serwery internetowe w rozdziale **"Jak działa Internet"**. -Aby wpisać dodatkowe polecenia podczas działania serwera WWW, otwórz nowe okno terminala i aktywuj swoje wirtualne środowisko (virtualenv) - aby przejrzeć instrukcje dotyczące otwierania drugiego okna terminala, patrz [Wprowadzenie do wiersza poleceń](../intro_to_command_line/README.md). Aby zatrzymać serwer, wróć do okienka, w którym został on uruchomiony i wciśnij CTRL+C - klawisze Control i C jednocześnie (jeśli używasz systemu Windows to możesz też spróbować skrótu Ctrl+Break). +To type additional commands while the web server is running, open a new terminal window and activate your virtualenv -- to review instructions on how to open a second terminal window, see [Introduction to the command line](../intro_to_command_line/README.md). To stop the web server, switch back to the window in which it's running and press CTRL+C - Control and C keys together (on Windows, you might have to press Ctrl+Break). -Gotowa na następny krok? Czas stworzyć treść! \ No newline at end of file +Ready for the next step? It's time to create some content! \ No newline at end of file diff --git a/pl/django_templates/README.md b/pl/django_templates/README.md old mode 100755 new mode 100644 index cf29c520d39..e5919730106 --- a/pl/django_templates/README.md +++ b/pl/django_templates/README.md @@ -20,7 +20,7 @@ Aby wyświetlić zmienną w szablonie Django, używamy podwójnych nawiasów kla {{ posts }} ``` -Spróbuj tak zrobić w szablonie` blog/templates/blog/post_list.html`. Otwórz to w edytorze kodu i zastąp wszystko od drugiego `
` do trzeciego `
` wierszem `{{ posts }}`. Zapisz plik i odśwież stronę, by zobaczyć rezultat: +Spróbuj tak zrobić w szablonie` blog/templates/blog/post_list.html`. Otwórz go w edytorze kodu i zastąp istniejące `
{% endfor %} ``` @@ -80,7 +80,7 @@ Dobrze byłoby sprawdzić, czy twoja strona wciąż będzie działała w publicz $ git status [...] - $ git add --all . + $ git add . $ git status [...] $ git commit -m "Modified templates to display posts from database." diff --git a/pl/django_urls/README.md b/pl/django_urls/README.md old mode 100755 new mode 100644 index f43938fc7e4..6694c0ab899 --- a/pl/django_urls/README.md +++ b/pl/django_urls/README.md @@ -6,7 +6,7 @@ Zaczynamy budować naszą pierwszą stronę internetową: będzie to miejsce dla Adres URL to adres w internecie. Możesz zobaczyć URL-a za każdym razem, gdy odwiedzasz stronę internetową - jest on widoczny w pasku adresu przeglądarki internetowej. (Tak! `127.0.0.1:8000` jest adresem URL! Też `https://djangogirls.org` jest adresem URL.) -![Adres URL](images/url.png) +![URL](images/url.png) Każda strona w internecie potrzebuje własnego adresu URL. W ten sposób aplikacja wie, co wyświetlić użytkownikowi, który otworzy dany URL. W Django używamy tak zwanego `URLconf` (konfiguracji URL). URLconf to zestaw wzorców, które Django spróbuje dopasować do żądanego adresu URL, aby znaleźć poprawny widok. @@ -90,14 +90,26 @@ urlpatterns = [ ] ``` -Jak widzisz, teraz przyporządkowujemy widok (`view`) o nazwie `post_list` do strony głównej. Ten wzorzec URL zostanie dopasowany do pustego ciągu znaków, a Django zignoruje nazwę domeny (np. http://127.0.0.1:8000/), która poprzedza pełną ścieżkę URL. Ten wzorzec będzie wskazówką dla Django, że `views.post_list` jest właściwym miejscem dla każdego, kto wejdzie na stronę poprzez adres 'http://127.0.0.1:8000/'. +Jak widzisz, teraz przyporządkowujemy widok (`view`) o nazwie `post_list` do strony głównej. This URL pattern will match an empty string and the Django URL resolver will ignore the domain name (i.e., http://127.0.0.1:8000/) that prefixes the full URL path. Ten wzorzec będzie wskazówką dla Django, że `views.post_list` jest właściwym miejscem dla każdego, kto wejdzie na stronę poprzez adres 'http://127.0.0.1:8000/'. Ostatnia część, `name='post_list` jest nazwą URL, która będzie używana do zidentyfikowania widoku. Nazwa może być taka sama jak nazwa widoku albo kompletnie inna. W projekcie będziemy później używać nazw URL, więc ważne jest nazwanie każdego URL-a w aplikacji. Powinnyśmy również starać się używać nazw URL unikalnych i prostych do zapamiętania. Jeśli teraz spróbujesz odwiedzić stronę http://127.0.0.1:8000/, zobaczysz komunikat "niedostępna strona internetowa". Wynika to z faktu, że serwer (pamiętałaś o wpisaniu ` runserver`?) nie jest już uruchomiony. Spójrz na okno konsoli serwera, aby dowiedzieć się, dlaczego. -![Błąd](images/error1.png) +{% filename %}{{ warning_icon }} command-line{% endfilename %} -Twoja konsola pokazuje błąd, ale nie martw się - w rzeczywistości jest to całkiem użyteczne: mówi Ci, że** brak atrybutu 'post_list'**. To jest nazwa widoku (*view*), którą Django próbuje znaleźć i użyć, ale jeszcze go nie utworzyłyśmy. Na tym etapie Twój `/admin/ ` również nie będzie działać. Nie martw się, zajmiemy się tym. Jeżeli pojawiła Ci się wiadomość o innym błędzie, spróbuj zrestartować swój serwer. Aby to zrobić, przejdź do wiersza polecenia w którym uruchomiony jest serwer strony, zatrzymaj serwer wciskając Ctrl+C (klawisze Control i C równocześnie), a następnie uruchom go jeszcze raz poleceniem `python manage.py runserver`. + return _bootstrap._gcd_import(name[level:], package, level) + File "", line 1030, in _gcd_import + File "", line 1007, in _find_and_load + File "", line 986, in _find_and_load_unlocked + File "", line 680, in _load_unlocked + File "", line 850, in exec_module + File "", line 228, in _call_with_frames_removed + File "/Users/ola/djangogirls/blog/urls.py", line 5, in + path('', views.post_list, name='post_list'), + AttributeError: module 'blog.views' has no attribute 'post_list' + -> Jeśli chciałabyś dowiedzieć się więcej na temat konfiguracji URL w Django, zajrzyj do oficjalnej dokumentacji: https://docs.djangoproject.com/en/2.0/topics/http/urls/ \ No newline at end of file +Twoja konsola pokazuje błąd, ale nie martw się - w rzeczywistości jest to całkiem użyteczne: mówi Ci, że** brak atrybutu 'post_list'**. To jest nazwa widoku (*view*), którą Django próbuje znaleźć i użyć, ale jeszcze go nie utworzyłyśmy. Na tym etapie Twój `/admin/ ` również nie będzie działać. Nie martw się, zajmiemy się tym. Jeżeli pojawiła Ci się wiadomość o innym błędzie, spróbuj zrestartować swój serwer. To do that, in the console window that is running the web server, stop it by pressing Ctrl+C (the Control and C keys together). On Windows, you might have to press Ctrl+Break. Then you need to restart the web server by running a `python manage.py runserver` command. + +> If you want to know more about Django URLconfs, look at the official documentation: https://docs.djangoproject.com/en/3.2/topics/http/urls/ \ No newline at end of file diff --git a/pl/django_views/README.md b/pl/django_views/README.md old mode 100755 new mode 100644 index 5a12f76f8cf..0bb9bad2363 --- a/pl/django_views/README.md +++ b/pl/django_views/README.md @@ -41,4 +41,4 @@ Znowu błąd! Przeczytaj, o co chodzi tym razem: Przynajmniej pokazuje, że serwer jest uruchomiony ponownie, ale nadal nie wygląda dobrze, prawda? Nie martw się, to po prostu błąd strony, nic strasznego! Podobnie jak komunikaty o błędach w konsoli, są one całkiem przydatne. Możesz przeczytać, że *TemplateDoesNotExist*. Naprawmy ten błąd i stwórzmy szablon - ale to już w następnym rozdziale! -> Więcej na temat widoków Django dowiesz się czytając oficjalną dokumentację: https://docs.djangoproject.com/en/2.0/topics/http/views/ \ No newline at end of file +> Learn more about Django views by reading the official documentation: https://docs.djangoproject.com/en/3.2/topics/http/views/ \ No newline at end of file diff --git a/pl/dynamic_data_in_templates/README.md b/pl/dynamic_data_in_templates/README.md old mode 100755 new mode 100644 index cd75e0a1040..232df3a678a --- a/pl/dynamic_data_in_templates/README.md +++ b/pl/dynamic_data_in_templates/README.md @@ -56,7 +56,10 @@ def post_list(request): return render(request, 'blog/post_list.html', {}) ``` -Ostatnią częścią, której nam brakuje, jest przekazanie QuerySetu `posts` do szablonu. Nie martw się - omówimy sposób wyświetlania go w późniejszym rozdziale. +To display our QuerySet on our blog's post list, we have two things left to do: + +1. Pass the `posts` QuerySet to the template context, by changing the `render` function call. We'll do this now. +2. Modify the template to display the `posts` QuerySet. We'll cover this in a later chapter. Zauważ, że tworzymy *zmienną* dla naszego QuerySetu: `posts`. Potraktuj ją jako nazwę naszego QuerySetu. Od tej pory będziemy odnosić się do niej tylko za pomocą tej nazwy. @@ -78,4 +81,4 @@ def post_list(request): I to wszystko! Czas, żebyśmy wróciły do naszego szablonu i wyświetliły ten QuerySet! -Jeżeli chciałabyś poczytać trochę więcej na temat QuerySetów w Django, powinnaś rzucić okiem tutaj: https://docs.djangoproject.com/en/2.0/ref/models/querysets/ \ No newline at end of file +Want to read a little bit more about QuerySets in Django? You should look here: https://docs.djangoproject.com/en/3.2/ref/models/querysets/ \ No newline at end of file diff --git a/pl/extend_your_application/README.md b/pl/extend_your_application/README.md old mode 100755 new mode 100644 index c142ac94954..3d48fcc4e50 --- a/pl/extend_your_application/README.md +++ b/pl/extend_your_application/README.md @@ -2,7 +2,7 @@ # Rozbudowa aplikacji -Przeszłyśmy już wszystkie kroki niezbędne do uruchomienia naszej strony: wiemy, jak opisać nasze modele, widoki, adresy URL i szablony. Umiemy również sprawić, aby nasza strona wyglądała ładniej. +We've already completed all the different steps necessary for the creation of our website: we know how to write a model, URL, view and template. We also know how to make our website pretty. Czas na odrobinę praktyki! @@ -19,30 +19,30 @@ Zaczniemy od dodania linku wewnątrz pliku `blog/templates/blog/post_list.html`. {% block content %} {% for post in posts %} -
-
+
+
+

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} {% endblock %} ``` -{% raw %}Chcemy, aby tytuł wpisu był linkiem prowadzącym do strony ze szczegółami wpisu. Zmieńmy `

{{ post.title }}

`, aby zawierał link do strony szczegółów wpisu:{% endraw %} +{% raw %}Chcemy, aby tytuł wpisu był linkiem prowadzącym do strony ze szczegółami wpisu. Let's change `

{{ post.title }}

` so that it links to the post's detail page:{% endraw %} {% filename %}{{ warning_icon }} blog/templates/blog/post_list.html{% endfilename %} ```html -

{{ post.title }}

+

{{ post.title }}

``` {% raw %}Czas wyjaśnić, co oznacza tajemnicze `{% url 'post_detail' pk=post.pk %}`. Jak można podejrzewać, zapis `{% %}` oznacza, że używamy tagów szablonu Django. Tym razem używamy takiego, który generuje dla nas adres URL!{% endraw %} Fragment `post_detail` oznacza, że Django będzie oczekiwał URL w `blog/urls.py` o nazwie name=post_detail -A co z `pk=post.pk`? `pk` jest skrótem od primary key (ang. klucz podstawowy), który jest unikalną nazwą dla każdego rekordu bazy danych. Ponieważ nie ustaliłyśmy, czym jest klucz podstawowy w naszym modelu `Post`, Django stworzyło taki klucz dla nas (standardowo jest to liczba, która rośnie o jeden przy każdym kolejnym rekordzie, np. 1, 2, 3) i dodało go jako pole pod nazwą `pk` do każdego naszego posta. Możemy dostać się do klucza podstawowego przez wpisanie `post.pk`, tak samo jak otrzymujemy dostęp do innych pól (`title`, `author`, itd.) w naszym obiekcie `Post`! +A co z `pk=post.pk`? `pk` is short for primary key, which is a unique identifier for each record in a database. Every Django model has a field which serves as its primary key, and whatever other name it has, it can also be referred to as "pk". Because we didn't specify a primary key in our `Post` model, Django creates one for us (by default, a field named "id" holding a number that increases for each record, i.e. 1, 2, 3) and adds it as a field to each of our posts. We access the primary key by writing `post.pk`, the same way we access other fields (`title`, `author`, etc.) in our `Post` object! Teraz, gdy wejdziemy na adres http://127.0.0.1:8000/, ujrzymy błąd (co było do przewidzenia, bo nie mamy jeszcze ustawionego adresu URL ani widoku *view* dla `post_detail`). Będzie to wyglądać tak: @@ -78,13 +78,25 @@ To oznacza, że gdy wpiszesz w przeglądarce adres `http://127.0.0.1:8000/post/5 OK, dodałyśmy nowy wzorzec URL do `blog/urls.py`! Odświeżmy stronę: http://127.0.0.1:8000/ Boom! Serwer znów przestał działać. Spójrz w konsolę - jak oczekiwałyśmy, zdarzył się tam kolejny błąd! -![AttributeError](images/attribute_error2.png) +{% filename %}{{ warning_icon }} command-line{% endfilename %} + + return _bootstrap._gcd_import(name[level:], package, level) + File "", line 1030, in _gcd_import + File "", line 1007, in _find_and_load + File "", line 986, in _find_and_load_unlocked + File "", line 680, in _load_unlocked + File "", line 850, in exec_module + File "", line 228, in _call_with_frames_removed + File "/Users/ola/djangogirls/blog/urls.py", line 6, in + path('post//', views.post_detail, name='post_detail'), + AttributeError: module 'blog.views' has no attribute 'post_detail' + Pamiętasz, jaki jest następny krok? Dodanie widoku! ## Dodajmy widok dla poszczególnego wpisu -Tym razem nasz *widok* otrzymuje dodatkowy parametr `pk`. Nasz *widok* musi go "złapać", zgadza się? A więc zdefiniujmy funkcję tak: `def post_detail(request, pk):`. Zwróć uwagę, że musimy użyć dokładnie tej samej nazwy jak ta, której użyłyśmy w urls (`pk`). Pominięcie tej zmiennej jest niepoprawne i spowoduje błąd! +Tym razem nasz *widok* otrzymuje dodatkowy parametr `pk`. Nasz *widok* musi go "złapać", zgadza się? A więc zdefiniujmy funkcję tak: `def post_detail(request, pk):`. Note that this parameter must have the exact same name as the one we specified in `urls` (`pk`). Also note that omitting this variable is incorrect and will result in an error! Teraz chcemy wyświetlić jeden i tylko jeden wpis na blogu. Aby to zrobić, możemy użyć querysetów w następujący sposób: @@ -140,7 +152,7 @@ O nie! Kolejny błąd! Ale wiemy już, jak sobie z nim poradzić, prawda? Musimy Stwórzmy teraz plik o nazwie `post_detail.html` w folderze `blog/templates/blog` i otwórzmy go w edytorze. -Będzie to wyglądać tak: +Wprowadź następujący kod: {% filename %}blog/templates/blog/post_detail.html{% endfilename %} @@ -148,15 +160,15 @@ Będzie to wyglądać tak: {% extends 'blog/base.html' %} {% block content %} -
+
{% if post.published_date %} -
+
+ {% endif %}

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endblock %} ``` @@ -177,7 +189,7 @@ Dobrze byłoby sprawdzić, czy Twoja strona dalej będzie dobrze działać na Py {% filename %}command-line{% endfilename %} $ git status - $ git add --all . + $ git add . $ git status $ git commit -m "Added view and template for detailed blog post as well as CSS for the site." $ git push @@ -211,4 +223,4 @@ Komenda `manage.py collectstatic` jest trochę podobna do `manage.py migrate`. W W każdym razie, jesteśmy już gotowe do przejścia na stronę ["Web"](https://www.pythonanywhere.com/web_app_setup/) (klikając w menu umieszczonym w prawym górnym rogu). Następnie kliknij **Reload** i spójrz na stronę https://subdomain.pythonanywhere.com, aby zobaczyć rezultat. -I to już wszystko! Gratulacje :) \ No newline at end of file +And that should be it. Congrats! :) \ No newline at end of file diff --git a/pl/how_the_internet_works/README.md b/pl/how_the_internet_works/README.md old mode 100755 new mode 100644 index f89572eaaae..21b1b1d252c --- a/pl/how_the_internet_works/README.md +++ b/pl/how_the_internet_works/README.md @@ -6,9 +6,9 @@ Możemy się założyć, że używasz go każdego dnia. Ale czy naprawdę wiesz, co się dzieje, gdy wpisujesz w przeglądarce adres https://djangogirls.org i wciskasz `enter`? -Aby zrozumieć, jak działa internet, powinnaś najpierw dowiedzieć się, czym tak naprawdę jest strona internetowa - a jest ona zbiorem plików zapisanych na dysku twardym. Tak samo jak Twoje zdjęcia, muzyka czy filmy. Aczkolwiek strony internetowe różnią się od nich tym, że zawierają kod komputerowy zwany HTML. +Aby zrozumieć, jak działa internet, powinnaś najpierw dowiedzieć się, czym tak naprawdę jest strona internetowa, a jest ona zbiorem plików zapisanych na dysku twardym --tak jak filmy, muzyka lub zdjęcia. Aczkolwiek strony internetowe różnią się od nich tym, że zawierają kod komputerowy zwany HTML. -Jeśli nie miałaś wcześniej do czynienia z programowaniem, może być Ci na początku trudno zrozumieć HTML, ale przeglądarki internetowe (takie jak Chrome, Safari, Firefox itd.) uwielbiają go. Zostały one zaprojektowane po to, by czytać ten kod, przetwarzać go i postępować zgodnie z jego instrukcjami. Prezentują pliki, z których składa się Twoja strona - by wyglądała dokładnie tak jak Ty chcesz. +Jeśli do tej pory nie miałaś stycznoście z programowaniem, na początku może być Ci trudno zrozumieć czym jest HTML ale Twoje przeglądarki (takie jak Chrome, Safari, Firefox itp.) go uwielbiają. Zostały one zaprojektowane po to, by czytać ten kod, przetwarzać go i postępować zgodnie z jego instrukcjami. Prezentują pliki, z których składa się Twoja strona - by wyglądała dokładnie tak jak Ty chcesz. Tak jak w przypadku każdego innego pliku, musimy umiejscowić pliki HTML na dysku twardym. Do przechowywania plików HTML używamy specjalnych, potężnych komputerów zwanych *serwerami (ang. servers)*. Serwery nie posiadają monitorów, myszy ani klawiatur, ponieważ ich głownym celem jest przechowywanie danych i serwowanie ich. Dlatego są one nazywane *serwerami* -- ponieważ służą do *serwowania* danych. diff --git a/pl/html/README.md b/pl/html/README.md old mode 100755 new mode 100644 index 56c296a4a7c..b122af800e3 --- a/pl/html/README.md +++ b/pl/html/README.md @@ -33,13 +33,14 @@ Popatrz, jak Twoja strona wygląda teraz: http://127.0.0.1:8000/ ![Rysunek 11.1](images/step1.png) -Nie ma błędu! Gratulacje! :) Niestety, twoja aplikacja nie wyświetla niczego poza pustą stroną, ponieważ Twój szablon również jest pusty. Naprawmy to. +No error anymore! Congratulations! :) However, your website isn't actually publishing anything except an empty page, because your template is empty too. We need to fix that. Otwórz Twój nowy plik w edytorze kodu i dodaj poniższe: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html +

Hi there!

@@ -52,10 +53,11 @@ I jak twoja strona wygląda teraz? Odwiedź stronę http://127.0.0.1:8000/, żeb ![Rysunek 11.2](images/step3.png) -Zadziałało! Dobra robota :) +It worked. Nice work there! :) -* Najbardziej podstawowy znacznik, ``, jest zawsze na początku każdej strony internetowej, zaś `` jest zawsze na końcu. Jak widzisz, cała zawartość strony zawiera się pomiędzy znacznikiem otwierającym `` i zamykającym `` -* `

` jest znacznikiem akapitów; `

` zamyka każdy akapit +* The line `` is not a HTML tag. It only declares the document type. Here, it informs the browser that document type is [HTML5](https://html.spec.whatwg.org/#the-doctype). This is always the beginning of any HTML5 file. +* The most basic tag, ``, is always the beginning of html content and `` is always the end. As you can see, the whole content of the website goes between the beginning tag `` and closing tag `` +* `

` is a tag for paragraph elements; `

` closes each paragraph ## Head i body @@ -72,6 +74,7 @@ Przykładowo, element tytułu strony możesz umieścić wewnątrz ``, o ta {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + Ola's blog @@ -109,40 +112,49 @@ Teraz nieco się pobawmy i spróbujmy dostosować nasz szablon! Oto kilka znaczn * `link` tworzy link * `
  • pierwsza pozycja
  • druga pozycja
` tworzy listę, taką samą jak ta! * `
` tworzy sekcję na stronie +* `` definiuje zestaw linków nawigacyjnych +* `
` specifies independent, self-contained content +* `
` definiuje sekcję w dokumencie +* `
` określa nagłówek dokumentu lub sekcji +* `
` określa główną zawartość dokumentu +* `` defines some content aside from the content it is placed in (like a sidebar) +* `
` definiuje stopkę dla dokumentu lub sekcji +* `` definiuje określony czas (lub datetime) Tutaj możesz zobaczyć przykład pełnego szablonu, skopiuj i wklej go do `blog/templates/blog/post_list.html`: {% filename %}blog/templates/blog/post_list.html{% endfilename %} ```html + Django Girls blog - + -
-

published: 14.06.2014, 12:14

+
+

My first post

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

-
+ -
-

published: 14.06.2014, 12:14

+
+

My second post

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut f.

-
+ ``` -Stworzyliśmy tutaj trzy sekcje `div`. +Utworzyliśmy tutaj jedną sekcję `nagłówek` i dwie `pozycje`. -* Pierwszy `div` zawiera w sobie tytuł naszego bloga - jest to nagłówek i link -* Kolejne dwa elementy `div` zawierają nasze wpisy wraz z opublikowaną datą, `h2` z klikalnym tytułem wpisu oraz dwa elementy `p` (akapity) z tekstem, jeden z datą i drugi z treścią naszego wpisu. +* Element `nagłówek` zawiera tytuł naszego bloga - nagłówek i link +* The two `article` elements contain our blog posts with a published date in a `time` element, a `h2` element with a post title that is clickable and a `p` (paragraph) element for text of our blog post. Daje nam to taki efekt: @@ -169,11 +181,9 @@ Upewnij się, że jesteś w folderze `djangogirls` i powiedz `git`owi aby dodał {% filename %}command-line{% endfilename %} - $ git add --all . + $ git add . -> **Uwaga:** `--all` (czyli "wszystko") oznacza, że `git` weźmie pod uwagę pliki, które usunęłaś (domyślnie rozpoznaje zmiany tylko w nowych lub już istniejących plikach). Pamiętaj również (vide rozdział 3), że `.` oznacza aktualny katalog. - Zanim prześlemy wszystkie pliki, sprawdźmy, co faktycznie `git` zamierza przesłać (wszystkie pliki, które `git` prześle do repozytorium, powinny być zaznaczone na zielono): {% filename %}command-line{% endfilename %} @@ -188,7 +198,7 @@ Już blisko do końca. Teraz czas poprosić gita, aby zapisał te zmiany w histo $ git commit -m "Zmieniony kod HTML na stronie." -> **Uwaga:** Nie zapomnij umieścić informacji o zmianach w cudzysłowie (" "). +> **Note** Make sure you use double quotes around the commit message. Jak już wszystko to zrobimy, możemy wysłać (push) nasze zmiany na Githuba: diff --git a/pl/installation/README.md b/pl/installation/README.md old mode 100755 new mode 100644 index b61a0054c5b..ea0dd0dc9dd --- a/pl/installation/README.md +++ b/pl/installation/README.md @@ -19,36 +19,35 @@ Jeśli uczestniczysz w wydarzeniu Django Girls: Na tych warsztatach będziesz budować blog. W tym celu, podczas przechodzenia przez tutorial, zostaniesz poinstruowana, jak zainstalować na Twoim komputerze różnego rodzaju oprogramowanie i jak skonfigurować kilka kont online, które będą Ci potrzebne. Ta strona zbiera wszystkie instrukcje dotyczące instalacji i rejestracji w jednym miejscu (co jest przydatne w niektórych formach warsztatów). {% include "/chromebook_setup/instructions.md" %} +data-id="chromebook_setup" data-collapse=true ces--> {% include "/chromebook_setup/instructions.md" %} -# Krótkie wprowadzenie do wiersza polecenia +# Krótkie wprowadzenie do wiersza poleceń {#command-line} -Wiele z poniższych kroków odnosi się do "konsoli", "terminala", "wiersza poleceń" lub "linii poleceń" - wszystkie one oznaczają to samo: okno na komputerze, w którym można wprowadzać polecenia. Gdy dojdziesz do głównego tutoriala, dowiesz się więcej o wierszu polecenia. Na razie najważniejszą rzeczą jaką musisz wiedzieć to to, jak otworzyć okno wiersza polecenia i jak ono wygląda: -{% include "/intro_to_command_line/open_instructions.md" %} +Wiele z poniższych kroków odnosi się do "konsoli", "terminala", "wiersza poleceń" lub "linii poleceń" - wszystkie one oznaczają to samo: okno na komputerze, w którym można wprowadzać polecenia. Gdy dojdziesz do głównego tutoriala, dowiesz się więcej o wierszu polecenia. Na razie najważniejszą rzeczą jaką musisz wiedzieć to to, jak otworzyć okno wiersza polecenia i jak ono wygląda: {% include "/intro_to_command_line/open_instructions.md" %} -# Zainstaluj Pythona +# Zainstaluj Pythona {#python} {% include "/python_installation/instructions.md" %} -# Zainstaluj edytor kodu +# Zainstaluj edytor kodu {#code-editor} -{% include "/code_editor/instructions.md" %} +{% include "/code_editor/instructions.md" %} -# Utwórz środowisko wirtualne i zainstaluj Django +# Skonfiguruj virtualenv i zainstaluj Django {#virtualenv} {% include "/django_installation/instructions.md" %} -# Zainstaluj Gita +# Zainstaluj Gita {#git} {% include "/deploy/install_git.md" %} -# Utwórz konto na GitHubie +# Utwórz konto na GitHubie {#github-account} Przejdź do strony [ GitHub.com ](https://www.github.com) i zarejestruj nowe, bezpłatne konto użytkownika. Pamiętaj, aby zapamiętać swoje hasło (dodaj je do swojego menedżera haseł, jeśli go używasz). -# Utwórz konto na PythonAnywhere +# Utwórz konto na PythonAnywhere {#pythonanywhere-account} {% include "/deploy/signup_pythonanywhere.md" %} @@ -66,4 +65,4 @@ Gratulacje, jesteś gotowa, by zacząć pracę! Jeśli masz trochę czasu przed # Ciesz się warsztatami! -Kiedy zaczniesz warsztaty, będziesz mogła przejść od razu do rozdziału [Twój pierwszy projekt w Django!](../django_start_project/README.md), ponieważ już przebrnęłaś przez materiał z wcześniejszych rozdziałów. +Kiedy zaczniesz warsztaty, będziesz mogła przejść od razu do rozdziału [Twój pierwszy projekt w Django!](../django_start_project/README.md), ponieważ już przebrnęłaś przez materiał z wcześniejszych rozdziałów. \ No newline at end of file diff --git a/pl/intro_to_command_line/README.md b/pl/intro_to_command_line/README.md old mode 100755 new mode 100644 index 974e2afa23d..fe3ed46f195 --- a/pl/intro_to_command_line/README.md +++ b/pl/intro_to_command_line/README.md @@ -6,7 +6,7 @@ Za chwilę napiszesz swoją pierwszą linijkę kodu. Jesteś już podekscytowana **Pozwól, że przedstawimy Ci, Twojego pierwszego przyjaciela: wiersz polecenia!** -Następujące kroki pokażą Ci, jak wykorzystać tajemnicze czarne okno, które używają wszyscy hakerzy. Na początku może to wyglądać nieco przerażająco ale tak naprawdę to tylko zachęta do wpisywania komend. +Następujące kroki pokażą Ci, jak wykorzystać tajemnicze czarne okno, którego używają wszyscy hakerzy. Na początku może to wyglądać nieco przerażająco ale tak naprawdę to tylko zachęta do wpisywania komend. > **Uwaga** Podczas tego kursu będziemy używać terminów "katalog" i "folder" zamiennie, ponieważ oznaczają one tę samą rzecz. @@ -136,7 +136,7 @@ OS X i Linux posiada polecenie `man`, które wyświetla Ci pomoc dla danego pole - + Dodawanie przyrostka`/?` do większości poleceń powoduje, że zostają wyświetlone strony pomocy. Konieczne może być przewinięcie okna polecenia, aby zobaczyć wszystkie informacje. Spróbuj `cd /?`. @@ -165,11 +165,11 @@ Co znajduje się w środku? Fajnie byłoby się tego dowiedzieć. Sprawdźmy: {% filename %}command-line{% endfilename %} > dir - Directory of C:\Users\olasitarska - 05/08/2014 07:28 PM Applications - 05/08/2014 07:28 PM Desktop - 05/08/2014 07:28 PM Downloads - 05/08/2014 07:28 PM Music + Directory of C:\Users\olasitarska + 05/08/2020 07:28 PM Applications + 05/08/2020 07:28 PM Desktop + 05/08/2020 07:28 PM Downloads + 05/08/2020 07:28 PM Music ... @@ -288,10 +288,10 @@ Małe wyzwanie dla Ciebie: wewnątrz świeżo utworzonego katalogu `cwiczenie` s {% filename %}command-line{% endfilename %} - > cd excercise + > cd practice > mkdir test > dir - 05/08/2014 07:28 PM test + 05/08/2020 07:28 PM test diff --git a/pl/intro_to_command_line/open_instructions.md b/pl/intro_to_command_line/open_instructions.md index 213b0e814d8..09ef06f8fa7 100644 --- a/pl/intro_to_command_line/open_instructions.md +++ b/pl/intro_to_command_line/open_instructions.md @@ -1,4 +1,3 @@ - W zależności od wersji systemu Windows i klawiatury, jedna z poniższych instrukcji powinna otworzyć okno poleceń (być może trzeba trochę poeksperymentować, ale nie musisz wypróbowywać wszystkich tych sugestii): @@ -26,4 +25,4 @@ Przejdź do Applications → Utilities → Terminal. Prawdopodobnie jest to w Applications → Accessories → Terminal, or Applications → System → Terminal, ale może to zależeć od systemu. Jeśli tego tu nie ma, możesz spróbować z wyszukiwarką Google. :) - + \ No newline at end of file diff --git a/pl/python_installation/README.md b/pl/python_installation/README.md old mode 100755 new mode 100644 index d4671cd98dd..6571b2b69c1 --- a/pl/python_installation/README.md +++ b/pl/python_installation/README.md @@ -10,6 +10,6 @@ Początki Pythona sięgają późnych lat 80., a jego głównym założeniem jes > **Uwaga** Jeśli używasz już Chromebook, pomiń ten rozdział i upewnij się, że postąpiłeś zgodnie z instrukcją [Instalowanie Chromebook](../chromebook_setup/README.md). > -> **Uwaga** Jeśli zrobiłaś to już wcześniej w rozdziale 'Instalacja', nie ma potrzeby instalować Pythona po raz drugi - przejdź od razu do następnego rozdziału! +> **Note** If you already worked through the [installation steps](../installation/README.md), there's no need to do this again – you can skip straight ahead to the next chapter! {% include "/python_installation/instructions.md" %} \ No newline at end of file diff --git a/pl/python_installation/instructions.md b/pl/python_installation/instructions.md old mode 100755 new mode 100644 index 9cdf244ec74..71873ebef3a --- a/pl/python_installation/instructions.md +++ b/pl/python_installation/instructions.md @@ -2,7 +2,9 @@ > > Niniejszy podrozdział powstał w oparciu o kurs Geek Girls Carrots (https://github.com/ggcarrots/django-carrots) -Framework Django został napisany w Pythonie. Potrzebujemy Pythona, żeby móc zrobić cokolwiek w Django. Zacznijmy zatem od zainstalowania go! Chcemy zainstalować Pythona 3.6, więc jeżeli posiadasz jakąkolwiek wcześniejszą wersję, będziesz musiała ją uaktualnić. Jeśli masz już w wersji 3.4 lub nowszej, powinno być dobrze. +Framework Django został napisany w Pythonie. Potrzebujemy Pythona, żeby móc zrobić cokolwiek w Django. Zacznijmy zatem od zainstalowania go! Chcemy zainstalować Pythona 3.6, więc jeżeli posiadasz jakąkolwiek wcześniejszą wersję, będziesz musiała ją uaktualnić. If you already have version {{ book.py_min_version }} or higher you should be fine. + +Please install normal Python as follows, even when you have Anaconda installed on your computer. @@ -11,56 +13,59 @@ Najpierw sprawdź, czy na komputerze działa 32- lub 64-bitowa wersja systemu Wi * Wciśnij klawisz Windows i klawisz Pause/Break w tym samym czasie * Otwórz panel sterowania z menu systemu Windows, a następnie przejdź do Zabezpieczenia Systemu, a następnie System * Wciśnij przycisk Windows, a następnie przejdź do Settings>System>About +* Search the Windows Start menu for "System Information". To do that, click the Start button or press the Windows key, then begin to type `System Information`. It will start making suggestions as soon as you type. You can select the entry once it shows up. -Możesz ściągnąć Pythona dla Windowsa ze strony https://www.python.org/downloads/windows/. Kliknij w link "Latest Python 3 Release - Python x.x.x". Jeżeli Twój komputer pracuje na **64-bitowej** wersji Windowsa, ściągnij **Windows x86-64 executable installer**. W innym wypadku ściągnij **Windows x86 executable installer**. Po ściągnięciu instalatora, powinnaś go uruchomić (klikając dwukrotnie w niego) i postępować według wyświetlanych instrukcji. +Możesz ściągnąć Pythona dla Windowsa ze strony https://www.python.org/downloads/windows/. Kliknij w link "Latest Python 3 Release - Python x.x.x". Jeżeli twój komputer pracuje na **64-bitowej** wersji Windowsa, ściągnij **Windows x86-64 executable installer**. W innym wypadku ściągnij **Windows x86 executable installer**. Po ściągnięciu instalatora, powinnaś go uruchomić (klikając dwukrotnie w niego) i postępować według wyświetlanych instrukcji. -Jedna rzecz, na którą trzeba uważać: podczas instalacji zauważysz okno zaznaczone jako "Setup". Upewnij się, że zaznaczyłaś opcję "Add Python 3.6 to PATH" lub ''Add Python to your environment variables" i kliknęłaś "Install Now", jak pokazano tutaj (może to wyglądać trochę inaczej, jeśli instalujesz inną wersję). +Jedna rzecz, na którą trzeba uważać: podczas instalacji zauważysz okno zaznaczone jako "Setup". Make sure you tick the "Add Python {{ book.py_version }} to PATH" or 'Add Python to your environment variables" checkbox and click on "Install Now", as shown here (it may look a bit different if you are installing a different version): ![Nie zapomnij dodać Pythona do ścieżki systemowej (ang. Path)](../python_installation/images/python-installation-options.png) Kiedy instalacja się zakończy, możesz zobaczyć okienko dialogowe z linkiem, który możesz śledzić, aby dowiedzieć się więcej o Pythonie lub wersji, którą zainstalowałaś. Zamknij lub anuluj to okienko - nauczysz się więcej w tym tutorialu! -Uwaga: jeżeli używasz starszej wersji Windowsa (7, Vista lub jakikolwiek starszy) i podczas instalacji Python 3.6.x dostaniesz błąd, możesz: - -1. zainstalować wszystkie uaktualnienia systemu Windows i spróbować instalacji Pythona 3.6 jeszcze raz; lub -2. zainstalować [starszą wersję Pythona](https://www.python.org/downloads/windows/), np. [3.4.6](https://www.python.org/downloads/release/python-346/). - -Jeżeli zainstalujesz starszą wersję Pythona, ekrany instalatora mogą wyglądać nieznacznie inaczej niż pokazane wyżej. Upewnij się, że przewinęłaś do "Add python.ext to Path", kliknęłaś przycisk po lewej i wybrałaś "Will be installed on local hard drive": +Note: If you are using an older version of Windows (7, Vista, or any older version) and the Python {{ book.py_version }} installer fails with an error, then install all Windows Updates and try to install Python again. If you still have the error, try installing Python version {{ book.py_min_release }} from [Python.org](https://www.python.org/downloads/windows/). -![Dodawanie Pythona do zmiennej Path, starsze wersje](../python_installation/images/add_python_to_windows_path.png) +> Django {{ book.django_version }} needs Python {{ book.py_min_version }} or greater, which does not support Windows XP or earlier versions. -> **Uwaga** Zanim zainstalujesz Pythona na OS X, musisz się upewnić, że ustawienia twojego Maca pozwolą na instalację pakietów, które nie pochodzą z App Store'a. Przejdź do Preferencji systemowych (znajdziesz je w folderze Aplikacje), kliknij "Ochrona i prywatność" i przejdź do zakładki "Ogólne". Jeżeli w "Dopuszczaj aplikacje pobrane z:" jest ustawione na "App Store", zmień to na "App Store i od zidentyfikowanych deweloperów". +> **Note** Before you install Python on OS X, you should ensure your Mac settings allow installing packages that aren't from the App Store. Go to System Preferences (it's in the Applications folder), click "Security & Privacy," and then the "General" tab. If your "Allow apps downloaded from:" is set to "Mac App Store," change it to "Mac App Store and identified developers." -Przejdź na stronę https://www.python.org/downloads/release/python-361/ i pobierz instalator Pythona: +You need to go to the website https://www.python.org/downloads/mac-osx/ and download the latest Python installer: * Pobierz plik o nazwie *Mac OS X 64-bit/32-bit installer*, -* Kliknij dwukrotnie na *python-3.6.1-macosx10.6.pkg*, by uruchomić instalator. +* Double click *python-{{ book.py_release }}-macosx10.9.pkg* to run the installer. -Jest bardzo prawdopodobne, że masz już zainstalowanego Pythona wraz z systemem. Aby się upewnić (a także sprawdzić jego wersję) otwórz konsolę i wpisz następujące polecenie: +It is very likely that you already have Python installed out of the box. To check if you have it installed (and which version it is), open a console and type the following command: {% filename %}command-line{% endfilename %} $ python3 --version - Python 3.6.1 + Python {{ book.py_release }} -Jeżeli masz zainstalowaną inną 'mikrowersję' Pythona, np. 3.6.0, to nie ma potrzeby, byś dokonywała aktualizacji. Jeżeli nie masz zainstalowanego Pythona lub chciałabyś zainstalować go w innej wersji, skorzystaj z jednego z poniższych sposobów: +If you have a different version of Python installed, at least {{ book.py_min_version }} (e.g. {{ book.py_min_release }}), then you don't have to upgrade. If you don't have Python installed, or if you want a different version, first check what Linux distribution you are using with the following command: + +{% filename %}command-line{% endfilename %} + + $ grep '^NAME=' /etc/os-release + + +Afterwards, depending on the result, follow one of the following installation guides below this section. -Wpisz w konsoli poniższe polecenie: +Type this command into your console: {% filename %}command-line{% endfilename %} @@ -72,14 +77,14 @@ Wpisz w konsoli poniższe polecenie: -Użyj następującego polecenia w konsoli: +Use this command in your console: {% filename %}command-line{% endfilename %} $ sudo dnf install python3 -Jeżeli używasz starszej wersji Fedory, możesz dostać wiadomość o błędzie, że polecenie `dnf` nie zostało znalezione. W takim wypadku zamiast tego użyj polecenia `yum`. +If you're on older Fedora versions you might get an error that the command `dnf` is not found. In that case, you need to use `yum` instead. @@ -95,18 +100,18 @@ Użyj następującego polecenia w konsoli: -Sprawdź, czy instalacja zakończyła się pomyślnie - otwórz wiersz polecenia i uruchom polecenie `python3`: +Verify the installation was successful by opening a command prompt and running the `python3` command: {% filename %}command-line{% endfilename %} $ python3 --version - Python 3.6.1 + Python {{ book.py_release }} -Pokazana wersja może różnić się od 3.6.1 - powinna pasować do wersji, którą zainstalowałeś. +The version shown may be different from {{ book.py_release }} -- it should match the version you installed. -**Uwaga:** jeżeli pracujesz na Windowsie i dostajesz wiadomość o błędzie, że `python3` nie został znaleziony, spróbuj użyć `python` (bez `3`) oraz sprawdź, czy być może w taki sposób uruchomisz Pythona 3.4. +**NOTE:** If you're on Windows and you get an error message that `python3` wasn't found, try using `python` (without the `3`) and check if it still might be a version of Python that is {{ book.py_min_version }} or higher. If that doesn't work either, you may open a new command prompt and try again; this happens if you use a command prompt left open from before the Python installation. * * * -W razie jakichkolwiek wątpliwości albo jeśli coś poszło nie tak i nie wiesz, co dalej robić, zapytaj mentora lub osobę prowadzącą kurs! Czasami nie wszystko idzie tak, jak powinno i najlepszym wyjściem z sytuacji jest poprosić o pomoc kogoś bardziej doświadczonego. \ No newline at end of file +If you have any doubts, or if something went wrong and you have no idea what to do next, please ask your coach! Sometimes things don't go smoothly and it's better to ask for help from someone with more experience. \ No newline at end of file diff --git a/pl/python_introduction/README.md b/pl/python_introduction/README.md old mode 100755 new mode 100644 index 16155044556..759edb547a6 --- a/pl/python_introduction/README.md +++ b/pl/python_introduction/README.md @@ -6,31 +6,15 @@ Napiszmy jakiś kod! -## Wiersz polecenia Pythona +{% include "/python_introduction/prompt.md" %} -> Dla czytelniczek w domu: tę część uwzględnia wideo [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U). +## Your first Python command! -Aby rozpocząć zabawę z Pythonem, musisz otworzyć jego *wiersz polecenia* na swoim komputerze. Powinnaś już wiedzieć, jak to zrobić - nauczyłyśmy się tego w rozdziale [Wprowadzenie do interfejsu wiersza polecenia](../intro_to_command_line/README.md). +After running the Python command, the prompt changed to `>>>`. For us this means that for now we may only use commands in the Python language. You don't have to type in `>>>` – Python will do that for you. -Gdy już będziesz gotowa, postępuj według instrukcji poniżej. +If you want to exit the Python console at any point, type `exit()` or use the shortcut `Ctrl + Z` for Windows and `Ctrl + D` for Mac/Linux. Then you won't see `>>>` any longer. -Chcemy otworzyć konsolę Pythona. Wpisz `python`, jeśli pracujesz na Windowsie, lub `python3`, jeśli pracujesz na MacOS/Linuxie i wciśnij `enter`. - -{% filename %}command-line{% endfilename %} - - $ python3 - Python 3.6.1 (...) - Type "help", "copyright", "credits" or "license" for more information. - >>> - - -## Twoje pierwsze polecenie w Pythonie! - -Po uruchomieniu Pythona wiersz polecenia wygląda tak: `>>>`. Jest to sygnał dla nas, że od tego momentu możemy używać wyłącznie instrukcji języka Python. Nie musisz wpisywać `>>>` - Python zrobi to za Ciebie. - -Jeśli w którymkolwiek momencie zechcesz wyjść z konsoli Pythona, wpisz polecenie `exit()` albo użyj kombinacji klawiszy `Ctrl + Z` w Windows lub `Ctrl + D` w Macu/Linuksie. Wtedy już nie będziesz więcej widzieć `>>>`. - -Teraz jeszcze nie chcemy wyjść z konsoli Pythona. Chcemy się jeszcze kilku rzeczy nauczyć. Zacznijmy od wpisania działania matematycznego, np. `2 + 3` i naciśnięcia `entera`. +For now, we don't want to exit the Python console. We want to learn more about it. Let's start by typing some math, like `2 + 3` and hitting `enter`. {% filename %}command-line{% endfilename %} @@ -39,26 +23,26 @@ Teraz jeszcze nie chcemy wyjść z konsoli Pythona. Chcemy się jeszcze kilku rz 5 ``` -Nieźle! Widzisz, jak pojawiła się odpowiedź? Python zna się na matematyce! Powinnaś spróbować innych działań, np.: +Nice! See how the answer popped out? Python knows math! You could try other commands like: - `4 * 5` - `5 - 1` - `40 / 2` -By wykonać potęgowanie, powiedzmy podnieść 2 do potęgi 3, musimy wpisać: {% filename %}command-line{% endfilename %} +To perform exponential calculation, say 2 to the power 3, we type: {% filename %}command-line{% endfilename %} ```python >>> 2 ** 3 8 ``` -Pobaw się tym przez chwilę, a potem wróć tutaj. :) +Have fun with this for a little while and then get back here. :) -Ja widzisz, Python jest świetnym kalkulatorem. Jeżeli zastanawiasz się, co możesz z nim jeszcze zrobić… +As you can see, Python is a great calculator. If you're wondering what else you can do… -## Tekstowy typ danych (string) +## Strings -A jakby tak wpisać swoje własne imię? Wpisz swoje imię używając cudzysłowów, w ten sposób: +How about your name? Type your first name in quotes like this: {% filename %}command-line{% endfilename %} @@ -67,18 +51,18 @@ A jakby tak wpisać swoje własne imię? Wpisz swoje imię używając cudzysłow 'Ola' ``` -Właśnie stworzyłaś swój pierwszy string! Jest to ciąg znaków, który może być przetwarzany przez komputer. String musi zawsze zaczynać się i kończyć tym samym znakiem. Może to być apostrof (`'`) lub cudzysłów (`"`) - nie ma różnicy! Sygnalizują one Pythonowi, że wszystko, co znajduje się pomiędzy nimi, jest stringiem. +You've now created your first string! It's a sequence of characters that can be processed by a computer. The string must always begin and end with the same character. This may be single (`'`) or double (`"`) quotes (there is no difference!) The quotes tell Python that what's inside of them is a string. -Stringi mogą być łączone. Spróbuj tak: +Strings can be strung together. Try this: {% filename %}command-line{% endfilename %} ```python ->>> "Czesc " + "Ola" -'Czesc Ola' +>>> "Hi there " + "Ola" +'Hi there Ola' ``` -Da się również mnożyć stringi za pomocą liczb: +You can also multiply strings with a number: {% filename %}command-line{% endfilename %} @@ -87,9 +71,9 @@ Da się również mnożyć stringi za pomocą liczb: 'OlaOlaOla' ``` -Jeśli chciałabyś użyć apostrofu wewnątrz stringu, możesz to zrobić na dwa sposoby. +If you need to put an apostrophe inside your string, you have two ways to do it. -Za pomocą cudzysłowu: +Using double quotes: {% filename %}command-line{% endfilename %} @@ -98,7 +82,7 @@ Za pomocą cudzysłowu: "Runnin' down the hill" ``` -lub poprzedzając apostrof odwróconym ukośnikiem (``): +or escaping the apostrophe with a backslash (`\`): {% filename %}command-line{% endfilename %} @@ -107,7 +91,7 @@ lub poprzedzając apostrof odwróconym ukośnikiem (``): "Runnin' down the hill" ``` -Fajnie, co? Możesz także wyświetlić swoje imię wielkimi literami. Wpisz: +Nice, huh? To see your name in uppercase letters, type: {% filename %}command-line{% endfilename %} @@ -116,9 +100,9 @@ Fajnie, co? Możesz także wyświetlić swoje imię wielkimi literami. Wpisz: 'OLA' ``` -Właśnie użyłaś **metody** `upper` na swoim stringu! Metoda (jak `upper()`) to sekwencja instrukcji, które Python wykonuje na podanym obiekcie (`"Ola"`) jak tylko ją wywołasz. +You just used the `upper` **method** on your string! A method (like `upper()`) is a sequence of instructions that Python has to perform on a given object (`"Ola"`) once you call it. -Jeżeli chcesz poznać liczbę liter, którą zawiera twoje imię, istnieje **funkcja** również do tego! +If you want to know the number of letters contained in your name, there is a **function** for that too! {% filename %}command-line{% endfilename %} @@ -127,22 +111,22 @@ Jeżeli chcesz poznać liczbę liter, którą zawiera twoje imię, istnieje **fu 3 ``` -Zastanawiasz się, dlaczego czasami wywołujemy funkcję z `.` na końcu stringu (jak tutaj: `"Ola".upper()`), a czasami najpierw wywołujemy funkcję, a dopiero potem umieszczamy string w nawiasach? Ano, w niektórych przypadkach funkcje są związane z obiektami. Tak jak `upper()`, która może być użyta wyłącznie na stringach. Taką funkcję nazywamy wówczas **metodą**. Są również funkcje, które nie są powiązane z niczym konkretnym i mogą być używane na różnych typach obiektów, jak na przykład `len()`. Dlatego przekazujemy `"Ola"` jako parametr dla funkcji `len`. +Wonder why sometimes you call functions with a `.` at the end of a string (like `"Ola".upper()`) and sometimes you first call a function and place the string in parentheses? Well, in some cases, functions belong to objects, like `upper()`, which can only be performed on strings. In this case, we call the function a **method**. Other times, functions don't belong to anything specific and can be used on different types of objects, just like `len()`. That's why we're giving `"Ola"` as a parameter to the `len` function. ### Podsumowanie -OK, wystarczy już stringów. Jak dotąd nauczyłaś się o: +OK, enough of strings. So far you've learned about: - **wiersz polecenia** - wpisywanie komend (kodu) w wierszu polecenia Pythona powoduje, że Python zwraca wyniki - **liczby i stringi** - w Pythonie liczb używamy do działań matematycznych, a stringów do obiektów tekstowych - **operatory** - takie jak `+` i `*`, łączą wartości produkując nowe - ** funkcje** - takie jak `upper()` i `len()`, wykonują działania na obiektach. -Są to podstawy każdego języka programowania, jakiego przyjdzie Ci się uczyć. Gotowa na coś trudniejszego? Mamy nadzieję, że tak! +These are the basics of every programming language you learn. Ready for something harder? We bet you are! -## Błędy +## Errors -Spróbujmy czegoś nowego. Czy możemy sprawdzić długość liczby w taki sam sposób, jak długość naszego imienia? Wpisz `len(304023)` i wciśnij `enter`: +Let's try something new. Can we get the length of a number the same way we could find out the length of our name? Type in `len(304023)` and hit `enter`: {% filename %}{{ warning_icon }} command-line{% endfilename %} @@ -153,9 +137,9 @@ Traceback (most recent call last): TypeError: object of type 'int' has no len() ``` -Dostałyśmy nasz pierwszy błąd! Ikona {{ warning_icon }} to sposób, w jaki będziemy Ciebie informować, że kod, który zaraz wykonasz, nie powinien zadziałać poprawnie. Popełnianie błędów (nawet intencjonalnie) to ważna część nauki! +We got our first error! The {{ warning_icon }} icon is our way of giving you a heads up that the code you are about to run won't work as expected. Making mistakes (even intentional ones) are an important part of learning! -Komunikat mówi nam, że obiekty typu "int" (liczby całkowite, ang. integer) nie mają długości. Zatem co możemy zrobić? Może mogłybyśmy przekazać naszą liczbę jako string? Stringi mają ustaloną długość, zgadza się? +It says that objects of type "int" (integers, whole numbers) have no length. So what can we do now? Maybe we can write our number as a string? Strings have a length, right? {% filename %}command-line{% endfilename %} @@ -164,56 +148,56 @@ Komunikat mówi nam, że obiekty typu "int" (liczby całkowite, ang. integer) ni 6 ``` -Działa! Użyłyśmy funkcji `str` wewnątrz funkcji `len`. Funkcja `str()` konwertuje wszystko do postaci stringów. +It worked! We used the `str` function inside of the `len` function. `str()` converts everything to strings. - Funkcja `str` przekształca wartości na **stringi** - Funkcja `int` przekształca wartości na **liczby** -> Ważne: możemy zamienić liczby na tekst, ale nie zawsze możemy zamienić tekst na liczby - czym w ogóle powinien być wynik działania `int('hello')`? +> Important: we can convert numbers into text, but we can't necessarily convert text into numbers – what would `int('hello')` be anyway? -## Zmienne +## Variables -Ważnym zagadnieniem w programowaniu są zmienne. Zmienna to nic innego jak nazwa nadana jakiejś wartości, którą potem możemy się posługiwać. Programiści używają zmiennych do przechowywania danych, dzięki czemu ich kod jest bardziej czytelny i nie muszą każdorazowo zastanawiać się, co jest czym. +An important concept in programming is variables. A variable is nothing more than a name for something so you can use it later. Programmers use these variables to store data, make their code more readable and so they don't have to keep remembering what things are. -Przypuśćmy, że chcemy stworzyć nową zmienną zwaną `imie`: +Let's say we want to create a new variable called `name`: {% filename %}command-line{% endfilename %} ```python ->>> imie = "Ola" +>>> name = "Ola" ``` -Napisałyśmy własnie, że imie równa się Ola. +We type name equals Ola. -Jak już zauważyłaś, Twój program nie wyświetlił niczego tak, jak to robił wcześniej. Zatem skąd wiemy, że zmienna faktycznie istnieje? Wpisz `imie` i wciśnij `enter`: +As you've noticed, your program didn't return anything like it did before. So how do we know that the variable actually exists? Enter `name` and hit `enter`: {% filename %}command-line{% endfilename %} ```python ->>> imie +>>> name 'Ola' ``` -Jupi! Twoja pierwsza zmienna! :) Zawsze możesz zmienić, do czego się ona odnosi: +Yippee! Your first variable! :) You can always change what it refers to: {% filename %}command-line{% endfilename %} ```python ->>> imie = "Sonja" ->>> imie +>>> name = "Sonja" +>>> name 'Sonja' ``` -Możesz także używać jej w funkcjach: +You can use it in functions too: {% filename %}command-line{% endfilename %} ```python ->>> len(imie) +>>> len(name) 5 ``` -Super, co? Zmienne mogą być czymkolwiek - liczbami również! Spróbuj: +Awesome, right? Now, variables can be anything – numbers too! Try this: {% filename %}command-line{% endfilename %} @@ -224,45 +208,45 @@ Super, co? Zmienne mogą być czymkolwiek - liczbami również! Spróbuj: 24 ``` -Ale co by było, gdybyśmy użyły złej nazwy? Masz pomysł, co mogłoby się stać? Sprawdźmy! +But what if we used the wrong name? Can you guess what would happen? Let's try! {% filename %}{{ warning_icon }} command-line{% endfilename %} ```python ->>> miasto = "Tokyo" ->>> masto +>>> city = "Tokyo" +>>> ctiy Traceback (most recent call last): File "", line 1, in -NameError: name 'masto' is not defined +NameError: name 'ctiy' is not defined ``` -Błąd! Jak widzisz, Python ma różne rodzaje błędów, a ten nosi nazwę **NameError**. Python zwróci Ci taki błąd, gdy będziesz próbowała używać nazwy, która nie została jeszcze utworzona. Gdybyś w przyszłości natrafiła na niego, sprawdź w swoim kodzie czy nie popełniłaś literówek w nazwach zmiennych. +An error! As you can see, Python has different types of errors and this one is called a **NameError**. Python will give you this error if you try to use a variable that hasn't been defined yet. If you encounter this error later, check your code to see if you've mistyped any names. -Poświęć chwilę czasu na zabawę i przekonaj się, co możesz z tym zrobić! +Play with this for a while and see what you can do! -## Funkcja print +## The print function -Spróbuj tego: +Try this: {% filename %}command-line{% endfilename %} ```python ->>> imie = 'Maria' ->>> imie +>>> name = 'Maria' +>>> name 'Maria' ->>> print(imie) +>>> print(name) Maria ``` -Kiedy wpisujesz po prostu `imie`, interpreter Pythona zwraca *odwzorowanie* stringa będącego wartością zmiennej 'imie', czyli litery M-a-r-i-a zamknięte w pojedynczym cudzysłowie''. Natomiast gdy napiszesz `print(imie)`, Python wypisze zawartość zmiennej na ekran, bez żadnego cudzysłowu, co wygląda lepiej. +When you just type `name`, the Python interpreter responds with the string *representation* of the variable 'name', which is the letters M-a-r-i-a, surrounded by single quotes, ''. When you say `print(name)`, Python will "print" the contents of the variable to the screen, without the quotes, which is neater. -Jak się później przekonamy, `print()` jest szczególnie użyteczny, gdy chcemy wypisać coś z wnętrza funkcji lub gdy zechcemy wypisać wartości w kilku wierszach. +As we'll see later, `print()` is also useful when we want to print things from inside functions, or when we want to print things on multiple lines. -## Listy +## Lists -Oprócz stringów i liczb całkowitych, Python dysponuje szeregiem różnych typów obiektów. Teraz zapoznamy się z typem zwanym **listą**. Listy są dokładnie tym, co myślisz: obiektami, które są listami innych obiektów. :) +Beside strings and integers, Python has all sorts of different types of objects. Now we're going to introduce one called **list**. Lists are exactly what you think they are: objects which are lists of other objects. :) -Śmiało, stwórzmy listę: +Go ahead and create a list: {% filename %}command-line{% endfilename %} @@ -271,101 +255,101 @@ Oprócz stringów i liczb całkowitych, Python dysponuje szeregiem różnych typ [] ``` -Tak, lista jest pusta. Niespecjalnie przydatne, co? Stwórzmy listę numerów totolotka. Nie chcemy się powtarzać za każdym razem, więc tutaj również posłużymy się zmienną: +Yes, this list is empty. Not very useful, right? Let's create a list of lottery numbers. We don't want to repeat ourselves all the time, so we will put it in a variable, too: {% filename %}command-line{% endfilename %} ```python ->>> wyniki = [3, 42, 12, 19, 30, 59] +>>> lottery = [3, 42, 12, 19, 30, 59] ``` -Dobrze, mamy listę! Co możemy z nią zrobić? Zobaczmy ile liczb znajduje się w tej liście. Masz pomysł, jakiej funkcji powinnaś użyć? Już z niej korzystałaś! +All right, we have a list! What can we do with it? Let's see how many lottery numbers there are in a list. Do you have any idea which function you should use for that? You know this already! {% filename %}command-line{% endfilename %} ```python ->>> len(wyniki) +>>> len(lottery) 6 ``` -Tak! `len()` może zwrócić Ci liczbę obiektów zawartych w liście. Prawda że przydatne? To może teraz posortujmy listę: +Yes! `len()` can give you a number of objects in a list. Handy, right? Maybe we will sort it now: {% filename %}command-line{% endfilename %} ```python ->>> wyniki.sort() +>>> lottery.sort() ``` -Polecenie to niczego nie zwraca, po prostu zmieniło kolejność liczb zawartych w liście. Wypiszmy jej zawartość jeszcze raz i zobaczmy co się stało: +This doesn't return anything, it just changed the order in which the numbers appear in the list. Let's print it out again and see what happened: {% filename %}command-line{% endfilename %} ```python ->>> print(wyniki) +>>> print(lottery) [3, 12, 19, 30, 42, 59] ``` -Jak widzisz, liczby na liście są teraz uporządkowane według wartości od najniższej do najwyższej. Gratulacje! +As you can see, the numbers in your list are now sorted from the lowest to highest value. Congrats! -A gdybyśmy zapragnęły odwrócić kolejność? Zróbmy to! +Maybe we want to reverse that order? Let's do that! {% filename %}command-line{% endfilename %} ```python ->>> wyniki.reverse() ->>> print(wyniki) +>>> lottery.reverse() +>>> print(lottery) [59, 42, 30, 19, 12, 3] ``` -Jeżeli chcesz dodać coś do swojej listy, możesz to zrobić wpisując polecenie: +If you want to add something to your list, you can do this by typing this command: {% filename %}command-line{% endfilename %} ```python ->>> wyniki.append(199) ->>> print(wyniki) +>>> lottery.append(199) +>>> print(lottery) [59, 42, 30, 19, 12, 3, 199] ``` -Jeśli chcesz wyświetlić tylko pierwszą liczbę, możesz to uczynić używając **indeksów**. Indeks jest numerem mówiącym nam, w którym miejscu listy znajduje się dany element. Programiści zaczynają liczenie od zera, zatem pierwszy element Twojej listy znajduje się w miejscu oznaczonym indeksem 0, następny z indeksem 1, i tak dalej. Spróbuj tego: +If you want to show only the first number, you can do this by using **indexes**. An index is the number that says where in a list an item occurs. Programmers prefer to start counting at 0, so the first object in your list is at index 0, the next one is at 1, and so on. Try this: {% filename %}command-line{% endfilename %} ```python ->>> print(wyniki[0]) +>>> print(lottery[0]) 59 ->>> print(wyniki[1]) +>>> print(lottery[1]) 42 ``` -Jak widzisz, możesz uzyskać dostęp do każdego z elementów Twojej listy za pomocą jej nazwy oraz numeru indeksu wewnątrz nawiasów kwadratowych. +As you can see, you can access different objects in your list by using the list's name and the object's index inside of square brackets. -By skasować coś z twojej listy, musisz użyć **indeksów**, których nauczyłyśmy się powyżej i metody `pop()`. Spróbujmy zobaczyć, jak to działa na przykładzie i powtórzmy sobie to, czego się nauczyłyśmy wyżej. Usuńmy pierwszy element z naszej listy. +To delete something from your list you will need to use **indexes** as we learned above and the `pop()` method. Let's try an example and reinforce what we learned previously; we will be deleting the first number of our list. {% filename %}command-line{% endfilename %} ```python ->>> print(wyniki) +>>> print(lottery) [59, 42, 30, 19, 12, 3, 199] ->>> print(wyniki[0]) +>>> print(lottery[0]) 59 ->>> wyniki.pop(0) +>>> lottery.pop(0) 59 ->>> print(wyniki) +>>> print(lottery) [42, 30, 19, 12, 3, 199] ``` -Wszystko zadziałało zgodnie z planem! +That worked like a charm! -Żeby było zabawniej, sprawdź inne indeksy: 6, 7, 1000, -1, -6 czy -1000. Sprawdż, czy jesteś w stanie przewidzieć rezultat przed użyciem instrukcji. Czy otrzymane rezultaty mają sens? +For extra fun, try some other indexes: 6, 7, 1000, -1, -6 or -1000. See if you can predict the result before trying the command. Do the results make sense? -Wykaz wszystkich metod dostępnych dla list znajdziesz w odpowiednim rozdziale dokumentacji Pythona: https://docs.python.org/3/tutorial/datastructures.html +You can find a list of all available list methods in this chapter of the Python documentation: https://docs.python.org/3/tutorial/datastructures.html -## Słowniki +## Dictionaries -> Dla czytelniczek w domu: ten rozdział jest również omówiony w wideo [Installing Python Code Editor](https://www.youtube.com/watch?v=ZX1CVvZLE6c). +> For readers at home: this part is covered in the [Python Basics: Dictionaries](https://www.youtube.com/watch?v=ZX1CVvZLE6c) video. -Słownik przypomina nieco listę, jednak różni się tym, że dostęp do wartości uzyskujemy za pomocą klucza, a nie liczbowego indeksu. Kluczem może być dowolny ciąg znaków lub liczba. Pusty słownik tworzymy tak: +A dictionary is similar to a list, but you access values by looking up a key instead of a numeric index. A key can be any string or number. The syntax to define an empty dictionary is: {% filename %}command-line{% endfilename %} @@ -374,111 +358,111 @@ Słownik przypomina nieco listę, jednak różni się tym, że dostęp do warto {} ``` -To pokazuje, że właśnie stworzyłaś pusty słownik. Hura! +This shows that you just created an empty dictionary. Hurray! -A teraz spróbuj wpisać poniższą instrukcję (spróbuj użyć własnych danych): +Now, try writing the following command (try substituting your own information, too): {% filename %}command-line{% endfilename %} ```python ->>> uczestniczka = {'imie' : 'Ola', 'kraj' : 'Polska', 'ulubione_liczby' : [7, 42, 92]} +>>> participant = {'name': 'Ola', 'country': 'Poland', 'favorite_numbers': [7, 42, 92]} ``` -Za pomocą tej instrukcji stworzyłaś właśnie zmienną o nazwie `uczestniczka` zawierającą trzy pary klucz-wartość: +With this command, you just created a variable named `participant` with three key–value pairs: - Klucz `imie` wskazuje na wartość `'Ola'` (obiekt typu `string`), - `kraj` wskazuje na wartość `'Polska'` (kolejny `string`), - zaś `ulubione_liczby` odnoszą się do `[7, 42, 92]` (obiekt typu `list` zawierający trzy liczby). -Za pomocą poniższej składni możesz sprawdzać wartości poszczególnych kluczy: +You can check the content of individual keys with this syntax: {% filename %}command-line{% endfilename %} ```python ->>> print(uczestniczka['imie']) +>>> print(participant['name']) Ola ``` -Widzisz, zupełnie jak w liście. Ale nie trzeba pamiętać numeru indeksu, wystarczy nazwa klucza. +See, it's similar to a list. But you don't need to remember the index – just the name. -A co się stanie, gdy poprosimy Pythona o wartość klucza, który nie istnieje? Masz pomysł? Spróbujmy tak zrobić i zobaczmy efekt! +What happens if we ask Python the value of a key that doesn't exist? Can you guess? Let's try it and see! {% filename %}{{ warning_icon }} command-line{% endfilename %} ```python ->>> uczestniczka['wiek'] +>>> participant['age'] Traceback (most recent call last): File "", line 1, in -KeyError: 'wiek' +KeyError: 'age' ``` -Spójrz, kolejny błąd! Tym razem **KeyError**. Python próbuje Ci pomóc i wskazuje, że klucz `'wiek'` nie istnieje w tym słowniku. +Look, another error! This one is a **KeyError**. Python is helpful and tells you that the key `'age'` doesn't exist in this dictionary. -Kiedy powinniśmy używać słownika, a kiedy listy? To bardzo dobre pytanie! Zastanów się nad rozwiązaniem, zanim spojrzysz na odpowiedź poniżej. +When should you use a dictionary or a list? Well, that's a good point to ponder. Think about the answer before looking at it in the next line. - Potrzebujesz ułożyć elementy w określonej kolejności? Wybierz listę. - Potrzebujesz powiązać wartości z kluczami, żeby mieć później łatwiejszy dostęp do nich (używając klucza)? Użyj słownika. -Słowniki, podobnie jak listy, są *mutowalne*, co oznacza, że po ich utworzeniu można je nadal zmieniać. Możesz dodać do stworzonego już słownika nowe pary klucz-wartość, w taki sposób: +Like lists, using the `len()` function on the dictionaries returns the number of key–value pairs in the dictionary. Go ahead and type in this command: {% filename %}command-line{% endfilename %} ```python ->>> uczestniczka['ulubiony_jezyk'] = 'Python' +>>> len(participant) +3 ``` -Podobnie jak w przypadku list, metoda `len()` zwraca liczbę par klucz-wartość w danym słowniku. Śmiało, wpisz polecenie: +Dictionaries, like lists, are *mutable*, meaning that they can be changed after they are created. You can add new key–value pairs to a dictionary after it is created, like this: {% filename %}command-line{% endfilename %} ```python ->>> len(uczestniczka) -4 +>>> participant['favorite_language'] = 'Python' ``` -Mam nadzieję, że jak dotąd jest to zrozumiałe. :) Gotowa na dalszą zabawę ze słownikami? W następnej linijce czeka nas jeszcze więcej niesamowitości. +I hope it makes sense up to now. :) Ready for some more fun with dictionaries? Read on for some amazing things. -Za pomocą polecenia `pop()` możesz usunąć element ze słownika. Założmy, że chciałabyś usunąć wpis oznaczony kluczem `'ulubione_liczby'`. Wpisz następującą instrukcję: +You can use the `pop()` method to delete an item in the dictionary. Say, if you want to delete the entry corresponding to the key `'favorite_numbers'`, type in the following command: {% filename %}command-line{% endfilename %} ```python ->>> uczestniczka.pop('ulubione_liczby') +>>> participant.pop('favorite_numbers') [7, 42, 92] ->>> uczestniczka -{'kraj': 'Polska', 'ulubiony_jezyk': 'Python', 'imie': 'Ola'} +>>> participant +{'country': 'Poland', 'favorite_language': 'Python', 'name': 'Ola'} ``` -Jak widać z wyświetlonego rezultatu, para klucz-wartość odpowiadająca kluczowi 'ulubione_liczby' została usunięta. +As you can see from the output, the key–value pair corresponding to the 'favorite_numbers' key has been deleted. -Ponadto możesz także zmienić wartość odpowiadającą kluczowi, który już istnieje w słowniku. Napisz: +As well as this, you can also change a value associated with an already-created key in the dictionary. Type this: {% filename %}command-line{% endfilename %} ```python ->>> uczestniczka['kraj'] = 'Niemcy' ->>> uczestniczka -{'kraj': 'Niemcy', 'ulubiony_jezyk': 'Python', 'imie': 'Ola'} +>>> participant['country'] = 'Germany' +>>> participant +{'country': 'Germany', 'favorite_language': 'Python', 'name': 'Ola'} ``` -Jak widać, wartość klucza `'kraj'` została zmieniona z `'Polska'` na `'Niemcy'`. :) Ekscytujące? Hura! Właśnie nauczyłaś się kolejnej niesamowitej rzeczy. +As you can see, the value of the key `'country'` has been altered from `'Poland'` to `'Germany'`. :) Exciting? Hurrah! You just learned another amazing thing. ### Podsumowanie -Doskonale! Wiesz już sporo o programowaniu. W tej części nauczyłaś się o: +Awesome! You know a lot about programming now. In this last part you learned about: - **błędach** - umiesz już czytać ze zrozumieniem błędy pojawiające się, gdy Python nie rozumie polecenia, które mu wydałaś - **zmiennych** - nazwach dla obiektów, dzięki którym programuje się łatwiej, a Twój kod jest czytelniejszy - **listach** - listach obiektów uporządkowanych w określonej kolejności - **słownikach** - zbiorach obiektów przechowywanych w postaci par klucz-wartość -Gotowa na następną część? :) +Excited for the next part? :) -## Porównywanie rzeczy +## Compare things -> Dla czytelniczek w domu: tę część uwzględnia wideo [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4). +> For readers at home: this part is covered in the [Python Basics: Comparisons](https://www.youtube.com/watch?v=7bzxqIKYgf4) video. -Istotną częścią programowania jest porównywanie różnych rzeczy. Co najłatwiej porównać? Liczby! Zobaczmy, jak to działa: +A big part of programming involves comparing things. What's the easiest thing to compare? Numbers! Let's see how that works: {% filename %}command-line{% endfilename %} @@ -493,13 +477,15 @@ True True >>> 5 != 2 True +>>> len([1, 2, 3]) > len([4, 5]) +True ``` -Dałyśmy Pythonowi różne liczby do porównania. Jak widać, potrafi on nie tylko porównywać liczby, ale również wyniki działań. Fajnie, nie? +We gave Python some numbers to compare. As you can see, not only can Python compare numbers, but it can also compare values of mathematical expressions like `2 * 2` and function results like the `2` returned by `len([4, 5])`. Nice, huh? -Zastanawiasz się, dlaczego stawiamy dwa znaki równości `==` obok siebie, gdy sprawdzamy, czy liczby są równe? Pojedynczego znaku równości `=` używamy do nadawania wartości zmiennym. Zawsze, ale to **zawsze** musisz używać dwóch znaków równości `==`, gdy chcesz sprawdzić, czy dane elementy są równe. Możemy również stwierdzić, że dwie rzeczy nie są sobie równe. Aby to zrobić, używamy symbolu `!=`, tak jak to zostało pokazane na przykładzie powyżej. +Do you wonder why we put two equal signs `==` next to each other to compare if numbers are equal? We use a single `=` for assigning values to variables. You always, **always** need to put two of them – `==` – if you want to check if things are equal to each other. We can also state that things are unequal to each other. For that, we use the symbol `!=`, as shown in the example above. -Użyjmy Pythona do wykonania dwóch innych zadań: +Give Python two more tasks: {% filename %}command-line{% endfilename %} @@ -510,14 +496,14 @@ True False ``` -`>` i `<` są zrozumiałe, ale co oznaczają `>=` i `<=`? Czytamy je w ten sposób: +We've seen `>` and `<`, but what do `>=` and `<=` mean? Read them like this: - x `>` y oznacza: x jest większe od y - x `<` y oznacza: x jest mniejsze od y - x `<=` y oznacza: x jest mniejsze lub równe y - x `>=` y oznacza: x jest większe lub równe y -Świetnie! A chcesz zrobić coś jeszcze? Spróbuj tak: +Awesome! Wanna do one more? Try this: {% filename %}command-line{% endfilename %} @@ -530,12 +516,12 @@ False True ``` -Możesz przekazać Pythonowi tyle liczb, ile Ci się podoba, a on zawsze zwróci Ci wynik! Prawda, że sprytne? +You can give Python as many numbers to compare as you want, and it will give you an answer! Pretty smart, right? - **and** - gdy używasz operatora `and`, oba porównania muszą być prawdziwe (True), żeby całe wyrażenie było prawdziwe - **or** - gdy używasz operatora `or`, tylko jedno z obu porównań musi być prawdziwe, aby całe wyrażenie było prawdziwe -Znasz powiedzenie "porównywać jabłka z gruszkami"? Zobaczmy, jak działa jego odpowiednik w Pythonie: +Have you heard of the expression "comparing apples to oranges"? Let's try the Python equivalent: {% filename %}{{ warning_icon }} command-line{% endfilename %} @@ -546,20 +532,20 @@ Traceback (most recent call last): TypeError: '>' not supported between instances of 'int' and 'str' ``` -Widać, że podobnie jak w powiedzeniu, Python nie jest w stanie porównać liczby (`int`) ze stringiem (`str`). Zamiast tego zwraca nam **TypeError** i mówi nam, że te dwa typy nie mogą być porównywane ze sobą. +Here you see that just like in the expression, Python is not able to compare a number (`int`) and a string (`str`). Instead, it shows a **TypeError** and tells us the two types can't be compared together. -## Obiekt logiczny (Boolean) +## Boolean -Przypadkiem się właśnie dowiedziałaś o istnieniu innego typu obiektów w Pythonie. Nazywa się on **Boolean**. +Incidentally, you just learned about a new type of object in Python. It's called **Boolean**. -Są tylko dwa obiekty logiczne: +There are only two Boolean objects: - True - prawda - False - fałsz -Jednak żeby Python mógł to zrozumieć, powinnaś zawsze zapisywać je tak: True (pierwsza litera wielka, reszta to małe litery). **true, TRUE, tRUE nie zadziałają -- tylko True jest poprawne.** (to samo dotyczy False.) +But for Python to understand this, you need to always write it as 'True' (first letter uppercase, with the rest of the letters lowercased). **true, TRUE, and tRUE won't work – only True is correct.** (The same applies to 'False' as well.) -Wartości logiczne mogą także być zmiennymi! Zobacz tutaj: +Booleans can be variables, too! See here: {% filename %}command-line{% endfilename %} @@ -569,7 +555,7 @@ Wartości logiczne mogą także być zmiennymi! Zobacz tutaj: True ``` -Możesz też zrobić tak: +You can also do it this way: {% filename %}command-line{% endfilename %} @@ -579,27 +565,27 @@ Możesz też zrobić tak: False ``` -Poćwicz i pobaw się wartościami logicznymi wpisując następujące instrukcje: +Practice and have fun with Booleans by trying to run the following commands: - `True and True` - `False and True` - `True or 1 == 1` - `1 != 2` -Gratulacje! Wartości logiczne są jedną z najfajniejszych możliwości w programaniu, a Ty właśnie nauczyłaś się ich używać! +Congrats! Booleans are one of the coolest features in programming, and you just learned how to use them! # Zapisujemy! -> Dla czytelniczek w domu: tę część uwzględnia wideo [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk). +> For readers at home: this part is covered in the [Python Basics: Saving files and "If" statement](https://www.youtube.com/watch?v=dOAg6QVAxyk) video. -Do tej pory pisałyśmy cały nasz kod Pythona w interpreterze, co zmusza nas do pisania linijka po linijce. Prawdziwe programy są zapisywane w plikach i uruchamiane przez **interpreter** lub **kompilator** naszego języka programowania. Dotąd uruchamiałyśmy nasze programy w **interpreterze** Pythona, wprowadzając za każdym razem najwyżej jedną linijkę kodu. Ale w następnych zadaniach będziemy potrzebowały dodać więcej niż jeden wiersz kodu, więc musimy szybko: +So far we've been writing all our python code in the interpreter, which limits us to entering one line of code at a time. Normal programs are saved in files and executed by our programming language **interpreter** or **compiler**. So far we've been running our programs one line at a time in the Python **interpreter**. We're going to need more than one line of code for the next few tasks, so we'll quickly need to: - wyjść z interpretera Pythona - otworzyć wybrany przez nas edytor kodu - Zapisać kod do nowego pliku Pythona - Uruchomić go! -Aby wyjść z używanego przez nas interpretera Pythona, użyj funkcji `exit()` +To exit from the Python interpreter that we've been using, type the `exit()` function {% filename %}command-line{% endfilename %} @@ -608,9 +594,9 @@ Aby wyjść z używanego przez nas interpretera Pythona, użyj funkcji `exit()` $ ``` -W ten sposób znajdziesz się z powrotem w wierszu polecenia. +This will put you back into the command prompt. -Wcześniej wybrałyśmy Edytor kodu z sekcji [Edytor kodu](../code_editor/README.md). Otwórzmy teraz edytor i napiszmy trochę kodu wewnątrz nowego pliku (lub jeśli używasz Chromebooka, stwórz nowy plik w chmurze IDE i otwórz plik, który będzie zawarty w edytorze kodu): +Earlier, we picked out a code editor from the [code editor](../code_editor/README.md) section. We'll need to open the editor now and write some code into a new file (or if you're using a Chromebook, create a new file in the cloud IDE and open the file, which will be in the included code editor): {% filename %}editor{% endfilename %} @@ -618,73 +604,73 @@ Wcześniej wybrałyśmy Edytor kodu z sekcji [Edytor kodu](../code_editor/README print('Hello, Django girls!') ``` -Oczywiście jesteś już całkiem kompetentną programistką Pythona, więc śmiało - dodaj tam więcej kodu, który poznałaś wcześniej. +Obviously, you're a pretty seasoned Python developer now, so feel free to write some code that you've learned today. -Teraz musimy zapisać plik i nadać mu wymowną nazwę. Nazwijmy go **python_intro.py** i zapiszmy na Pulpicie. Możemy nazwać plik jak tylko nam się podoba, ale jedna rzecz jest istotna: na końcu nazwy musi być **.py**. Rozszerzenie **.py** informuje nasz komputer, że to jest **plik wykonywalny Pythona** i Python może go uruchomić. +Now we need to save the file and give it a descriptive name. Let's call the file **python_intro.py** and save it to your desktop. We can name the file anything we want, but the important part here is to make sure the file ends in **.py**. The **.py** extension tells our operating system that this is a **Python executable file** and Python can run it. -> **Uwaga** Powinnaś zauważyć jedną z najfajniejszych rzeczy, jeśli chodzi o edytor kodu: kolory! Gdy pisałaś w konsoli Pythona, wszystko miało ten sam kolor. Teraz powinnaś zobaczyć, że funkcja `print` jest innego koloru niż string. Nazywa się to "podświetlanie składni" i jest naprawdę użyteczne podczas kodowania. Kolor wyrazów w edytorze będzie dla Ciebie wskazówką, np. łatwo rozpoznasz dzięki temu niezamknięty string albo literówkę w słowie kluczowym (tak jak `def` w funkcji). To jeden z powodów, dla których używamy edytora kodu. :) +> **Note** You should notice one of the coolest thing about code editors: colors! In the Python console, everything was the same color; now you should see that the `print` function is a different color from the string. This is called "syntax highlighting", and it's a really useful feature when coding. The color of things will give you hints, such as unclosed strings or a typo in a keyword name (like the `def` in a function, which we'll see below). This is one of the reasons we use a code editor. :) -Mamy już zapisany plik, a więc czas go uruchomić! Wykorzystując wiadomości poznane w sekcji poświęconej wierszowi polecenia, użyj terminala, aby **zmienić aktualny katalog** na katalog Pulpitu. +With the file saved, it's time to run it! Using the skills you've learned in the command line section, use the terminal to **change directories** to the desktop. -Na Macu polecenie będzie wyglądać mniej-więcej tak: +On a Mac, the command will look something like this: {% filename %}command-line{% endfilename %} $ cd ~/Desktop - + -W Linuksie będzie tak (słowo "Desktop" może zostać przetłumaczone na polski jako "Pulpit"): +On Linux, it will be like this: {% filename %}command-line{% endfilename %} $ cd ~/Desktop + - -(Pamiętaj, że słowo "Desktop" może zostać przetłumaczone na polski jako "Pulpit"): +(Remember that the word "Desktop" might be translated to your local language.) -W wierszu polecenia w systemie Windows będzie tak: +On Windows Command Prompt, it will be like this: {% filename %}command-line{% endfilename %} > cd %HomePath%\Desktop - + -A w Windows Powershell będzie tak: +And on Windows Powershell, it will be like this: {% filename %}command-line{% endfilename %} > cd $Home\Desktop - + -Jeżeli utknęłaś, poproś o pomoc. To właśnie od tego są mentorzy! +If you get stuck, ask for help. That's exactly what the coaches are here for! -Teraz użyj Pythona do uruchomienia kodu z pliku w następujący sposób: +Now use Python to execute the code in the file like this: {% filename %}command-line{% endfilename %} $ python3 python_intro.py Hello, Django girls! + - -Uwaga: w Windowsie 'python3' nie będzie rozpoznawany jako polecenie. W takim wypadku użyj 'python' by wykonać ten plik: +Note: on Windows 'python3' is not recognized as a command. Instead, use 'python' to execute the file: {% filename %}command-line{% endfilename %} @@ -692,15 +678,15 @@ Uwaga: w Windowsie 'python3' nie będzie rozpoznawany jako polecenie. W takim wy > python python_intro.py ``` -Super! Właśnie uruchomiłaś z pliku swój pierwszy program w Pythonie. Wspaniałe uczucie, co? +Alright! You just ran your first Python program that was saved to a file. Feel awesome? -Teraz możemy przejść do niezwykle istotnego narzędzia w programowaniu: +You can now move on to an essential tool in programming: -## If… elif… else +## If … elif … else -Dużo różnych rzeczy w kodzie powinno być uruchamiane tylko wtedy, kiedy zostaną spełnione określone warunki. Dlatego Python posiada coś, co nazywa się **instrukcjami warunkowymi**. +Lots of things in code should be executed only when given conditions are met. That's why Python has something called **if statements**. -Zastąp kod w pliku **python_intro.py** następującym: +Replace the code in your **python_intro.py** file with this: {% filename %}python_intro.py{% endfilename %} @@ -708,7 +694,7 @@ Zastąp kod w pliku **python_intro.py** następującym: if 3 > 2: ``` -Gdybyśmy to teraz zapisały i uruchomiły, pojawiłby się błąd podobny do poniższego: +If we were to save and run this, we'd see an error like this: {% filename %}{{ warning_icon }} command-line{% endfilename %} @@ -716,76 +702,76 @@ Gdybyśmy to teraz zapisały i uruchomiły, pojawiłby się błąd podobny do po File "python_intro.py", line 2 ^ SyntaxError: unexpected EOF while parsing + - -Python oczekuje od nas dalszych instrukcji, które mają zostać wykonane w przypadku, gdy warunek `3 > 2` okaże się prawdziwy (czyli przyjmie wartość `True`). Sprawmy, żeby Python wypisał na ekranie "To działa!". Zmień kod w pliku **python_intro.py** na poniższy: +Python expects us to give further instructions to it which are executed if the condition `3 > 2` turns out to be true (or `True` for that matter). Let’s try to make Python print “It works!”. Change your code in your **python_intro.py** file to this: {% filename %}python_intro.py{% endfilename %} ```python if 3 > 2: - print('To działa!') + print('It works!') ``` -Zauważyłaś, że w kolejnym wierszu nasz kod posiada wcięcie 4 spacji? Musimy tak robić, aby Python wiedział, co ma uruchomić, gdy warunek jest prawdziwy. Możesz używać jednej spacji, ale prawie każdy programista Pythona stosuje 4 spacje, aby kod wyglądał czytelniej. Pojedynczy tabulator również będzie liczył się jako 4 spacje, o ile Twój edytor tekstu został w taki sposób skonfigurowany. Jeżeli dokonałaś już wyboru, nie zmieniaj go! Jeżeli używasz już 4 spacji jako wcięć, wszystkie przyszłe wcięcia wykonuj też za pomocą 4 spacji - inaczej możesz wpaść w kłopoty. +Notice how we've indented the next line of code by 4 spaces? We need to do this so Python knows what code to run if the result is true. You can do one space, but nearly all Python programmers do 4 to make things look neat. A single Tab will also count as 4 spaces as long as your text editor is set to do so. When you made your choice, don't change it! If you already indented with 4 spaces, make any future indentation with 4 spaces, too - otherwise you may run into problems. -Zapisz plik i uruchom go jeszcze raz: +Save it and give it another run: {% filename %}command-line{% endfilename %} ```python $ python3 python_intro.py -To dziala! +It works! ``` -Uwaga: pamiętaj, na Windowsie 'python3' nie jest rozpoznawane jako polecenie. Od tego momentu zamieniaj 'python3' na 'python' by wykonać plik. +Note: Remember that on Windows, 'python3' is not recognized as a command. From now on, replace 'python3' with 'python' to execute the file. ### A co jeśli warunek nie jest prawdziwy? -W poprzednich przykładach kod był wykonywany wtedy, gdy warunki okazywały się prawdziwe (True). Ale Python posiada również wyrażenia `elif` i `else`: +In previous examples, code was executed only when the conditions were True. But Python also has `elif` and `else` statements: {% filename %}python_intro.py{% endfilename %} ```python if 5 > 2: - print('5 jest jednak większe od 2') + print('5 is indeed greater than 2') else: - print('5 nie jest większe od 2') + print('5 is not greater than 2') ``` -Po uruchomieniu wyświetli się: +When this is run it will print out: {% filename %}command-line{% endfilename %} $ python3 python_intro.py - 5 jest jednak większe od 2 - + 5 is indeed greater than 2 + -Gdyby 2 było większą liczbą niż 5, wtedy zostałaby wykonana druga instrukcja. Zobaczmy, jak działa `elif`: +If 2 were a greater number than 5, then the second command would be executed. Let's see how `elif` works: {% filename %}python_intro.py{% endfilename %} ```python name = 'Sonja' if name == 'Ola': - print('Hej Ola!') + print('Hey Ola!') elif name == 'Sonja': - print('Hej Sonja!') + print('Hey Sonja!') else: - print('Hej anonimie!') + print('Hey anonymous!') ``` -i uruchommy go: +and executed: {% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hej Sonja! + Hey Sonja! + +See what happened there? `elif` lets you add extra conditions that run if the previous conditions fail. -Widzisz co się tutaj wydarzyło? `elif` pozwala Ci na dodanie dodatkowego warunku, jeśli poprzedni warunek nie został spełniony. - -Po początkowej instrukcji `if` możesz dodać tyle instrukcji `elif`, ile tylko Ci się podoba. Na przykład: +You can add as many `elif` statements as you like after your initial `if` statement. For example: {% filename %}python_intro.py{% endfilename %} @@ -805,19 +791,19 @@ else: print("My ears are hurting! :(") ``` -Python zbada każdy warunek i wyświetli: +Python runs through each test in sequence and prints: {% filename %}command-line{% endfilename %} $ python3 python_intro.py - "Perfect, I can hear all the details" - + Perfect, I can hear all the details + -## Komentarze +## Comments -Komentarze to linie zaczynające się od `#`. Możesz napisać cokolwiek będziesz chciała za `#`, a Python to zignoruje. Komentarze mogą spowodować, że Twój kod będzie łatwiejszy do zrozumienia przez innych. +Comments are lines beginning with `#`. You can write whatever you want after the `#` and Python will ignore it. Comments can make your code easier for other people to understand. -Zobaczmy, jak to wygląda: +Let's see how that looks: {% filename %}python_intro.py{% endfilename %} @@ -828,11 +814,11 @@ if volume < 20 or volume > 80: print("That's better!") ``` -Nie musisz pisać komentarza dla każdej linijki kodu, ale pamiętaj, że są one pomocne, by wytłumaczyć, czemu program coś robi lub by dodać podsumowanie, gdy program robi coś skomplikowanego. +You don't need to write a comment for every line of code, but they are useful for explaining why your code is doing something, or providing a summary when it's doing something complex. ### Podsumowanie -W ostatnich kilku ćwiczeniach nauczyłaś się: +In the last few exercises you learned about: - **porównywać rzeczy** - w Pythonie do porównywania rzeczy możesz używać operatorów `>`, `>=`, `==`, `<=`, `<` oraz `and`, `or` - **Boolean** - typ obiektu, który może przyjmować jedną z dwóch wartości: `True` (prawda) lub `False` (fałsz) @@ -840,70 +826,70 @@ W ostatnich kilku ćwiczeniach nauczyłaś się: - **if...elif...else** - wyrażenia, które pozwalają Ci uruchamiać kod tylko wtedy, gdy zostaną spełnione określone warunki. - **komentarze** - linie, których Python nie wykona, a które pozwalają Ci dokumentować kod programu -Czas na ostatnią część tego rozdziału! +Time for the last part of this chapter! -## Twoje własne funkcje! +## Your own functions! -> Dla czytelniczek w domu: tę część uwzględnia wideo [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0). +> For readers at home: this part is covered in the [Python Basics: Functions](https://www.youtube.com/watch?v=5owr-6suOl0) video. -Pamiętasz funkcje takie jak `len()`, które możesz uruchamiać w Pythonie? Dobra wiadomość: teraz nauczysz się pisać swoje własne funkcje! +Remember functions like `len()` that you can execute in Python? Well, good news – you will learn how to write your own functions now! -Funkcja jest zestawem poleceń, które Python ma wykonać. Każda funkcja w Pythonie zaczyna się słowem kluczowym `def`, posiada nazwę i może przyjmować parametry. Spróbujmy! Zastąp kod w pliku **python_intro.py** następującym: +A function is a sequence of instructions that Python should execute. Each function in Python starts with the keyword `def`, is given a name, and can have some parameters. Let's give it a go. Replace the code in **python_intro.py** with the following: {% filename %}python_intro.py{% endfilename %} ```python def hi(): - print('Hej!') - print('Jak się masz?') + print('Hi there!') + print('How are you?') hi() ``` -OK, nasza pierwsza funkcja gotowa! +Okay, our first function is ready! -Być może zastanawiasz się, czemu napisałyśmy nazwę funkcji na końcu pliku. Zrobiłyśmy tak, ponieważ Python odczytuje plik i wykonuje go od góry do dołu. Zatem w celu użycia naszej funkcji, musimy ponownie wpisać ją na dole. +You may wonder why we've written the name of the function at the bottom of the file. When we write `def hi():` and the indented lines following, this is us writing instructions for what the `hi()` function should do. Python will read and remember these instructions, but won't run the function yet. To tell Python we want to run the function, we have to call the function with `hi()`. Python reads the file and executes it from top to bottom, so we have to define the function in the file before we call it. -Uruchommy to teraz i sprawdźmy, co się stanie: +Let's run this now and see what happens: {% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hej! - Jak się masz? + Hi there! + How are you? + - -Uwaga: Jeżeli to nie zadziała, nie panikuj! Wynik działania pozwoli Ci ustalić dlaczego: +Note: if it didn't work, don't panic! The output will help you to figure why: - Jeżeli dostajesz `NameError`, znaczy to że prawdopodobnie niepoprawnie coś wpisałaś, więc powinnaś sprawdzić czy użyłaś tej samej nazwy tworząc funkcję w `def hi():` oraz gdy ją wykonujesz w `hi()`. -- Jeżeli dostajesz `IndentationError`, sprawdź czy obydwie linie z `print` mają tę samą liczbę spacji/tabów na początku linii: Python wymaga, by kod wewnątrz funkcji był odpowiednio wcięty. -- Jeżeli nie ma żadnego wyniku działania, sprawdź czy ostanie `hi()` *nie* jest przypadkiem wcięte - jeżeli jest, to ta linia stała się również częścią funkcji i nigdy nie zostanie wykonana. +- Jeżeli dostajesz `IndentationError`, sprawdź czy obydwie linie z `print` mają tę samą liczbę spacji/tabów na początku linii: Python wymaga, by kod wewnątrz funkcji był odpowiednio wcięty. +- Jeżeli nie ma żadnego wyniku działania, sprawdź czy ostanie `hi()` *nie* jest przypadkiem wcięte - jeżeli jest, to ta linia stała się również częścią funkcji i nigdy nie zostanie wykonana. -Zbudujmy naszą pierwszą funkcję z parametrami. Posłużymy się wcześniejszym przykładem - funkcją, która wita każdego, kto ją uruchomi, wraz z imieniem: +Let's build our first function with parameters. We will change the previous example – a function that says 'hi' to the person running it – with a name: {% filename %}python_intro.py{% endfilename %} ```python -def hi(imie): +def hi(name): ``` -Jak widać, teraz nasza funkcja przyjmuje parametr, który nazwałyśmy `imie`: +As you can see, we now gave our function a parameter that we called `name`: {% filename %}python_intro.py{% endfilename %} ```python -def hi(imie): - if imie == 'Ola': - print('Hej Ola!') - elif imie == 'Sonja': - print('Hej Sonja!') +def hi(name): + if name == 'Ola': + print('Hi Ola!') + elif name == 'Sonja': + print('Hi Sonja!') else: - print('Hej nieznajoma!') + print('Hi anonymous!') hi() ``` -Pamiętaj: musiałyśmy dodać cztery dodatkowe spacje (razem osiem) przed funkcją `print`, ponieważ `if` musi dostać informację o tym, co powinno się wydarzyć, gdy warunek zostanie spełniony. Zobaczmy teraz, jak to działa: +Remember: The `print` function is indented four spaces within the `if` statement. This is because the function runs when the condition is met. Let's see how it works now: {% filename %}{{ warning_icon }} command-line{% endfilename %} @@ -911,10 +897,10 @@ Pamiętaj: musiałyśmy dodać cztery dodatkowe spacje (razem osiem) przed funkc Traceback (most recent call last): File "python_intro.py", line 10, in hi() - TypeError: hi() missing 1 required positional argument: 'imie' - + TypeError: hi() missing 1 required positional argument: 'name' + -Ups, błąd. Na szczęście Python zwrócił nam dość przydatny komunikat. Mówi nam, że funkcja `hi()` (ta, którą stworzyłyśmy) posiada jeden wymagany argument (zwany `imie`) i że zapomniałyśmy go przekazać przy wywoływaniu funkcji. Naprawmy to na końcu naszego pliku: +Oops, an error. Luckily, Python gives us a pretty useful error message. It tells us that the function `hi()` (the one we defined) has one required argument (called `name`) and that we forgot to pass it when calling the function. Let's fix it at the bottom of the file: {% filename %}python_intro.py{% endfilename %} @@ -922,15 +908,15 @@ Ups, błąd. Na szczęście Python zwrócił nam dość przydatny komunikat. Mó hi("Ola") ``` -I wykonajmy ponownie: +And run it again: {% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hej Ola! - + Hi Ola! + -A gdybyśmy zmieniły imię? +And if we change the name? {% filename %}python_intro.py{% endfilename %} @@ -938,104 +924,104 @@ A gdybyśmy zmieniły imię? hi("Sonja") ``` -I wykonajmy: +And run it: {% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hej Sonja! + Hi Sonja! + - -A jak myślisz - co się stanie, jak wprowadzimy tam inne imię (jeszcze inne niż Ola i Sonja)? Spróbuj i przekonaj się, czy miałaś rację. Powinno się wyświetlić coś takiego: +Now, what do you think will happen if you write another name in there? (Not Ola or Sonja.) Give it a try and see if you're right. It should print out this: {% filename %}command-line{% endfilename %} - Hej nieznajoma! - + Hi anonymous! + -Prawda, że fajnie? W ten sposób nie musisz powtarzać się za każdym razem, gdy zechcesz zmienić imię osoby, która ma zostać powitana. To właśnie dlatego funkcje są nam potrzebne - żeby nie powtarzać kodu! +This is awesome, right? This way you don't have to repeat yourself every time you want to change the name of the person the function is supposed to greet. And that's exactly why we need functions – you never want to repeat your code! -Zróbmy coś mądrzejszego - mamy więcej niż dwa imiona, a podanie warunku dla każdego byłoby trudne, prawda? Zastąp zawartość pliku następującym kodem: +Let's do something smarter – there are more names than two, and writing a condition for each would be hard, right? Replace the content of your file with the following: {% filename %}python_intro.py{% endfilename %} ```python -def hi(imie): - print('Hej ' + imie + '!') +def hi(name): + print('Hi ' + name + '!') hi("Rachel") ``` -Teraz wywołajmy ten kod: +Let's call the code now: {% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hej Rachel! + Hi Rachel! + +Congratulations! You just learned how to write functions! :) -Gratulacje! Właśnie nauczyłaś się pisać funkcje! :) +## Loops -## Pętle +> For readers at home: this part is covered in the [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0) video. -> Dla czytelniczek w domu: tę część uwzględnia wideo [Python Basics: For Loop](https://www.youtube.com/watch?v=aEA6Rc86HF0). +This is the last part already. That was quick, right? :) -To już ostatnia część. Prawda, że szybko poszło? :) +Programmers don't like to repeat themselves. Programming is all about automating things, so we don't want to greet every person by their name manually, right? That's where loops come in handy. -Jak już wspomniałyśmy, programiści są leniwi i nie lubią się powtarzać. W programowaniu chodzi o automatyzowanie różnych rzeczy, więc nie chcemy witać ręcznie każdej osoby po imieniu, prawda? I tu właśnie przydają nam się pętle. - -Pamiętasz jeszcze listy? Zróbmy listę dziewczyn: +Still remember lists? Let's do a list of girls: {% filename %}python_intro.py{% endfilename %} ```python -dziewczyny = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'Ty'] +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] ``` -Chcemy powitać po imieniu każdą z nich. Mamy do tego funkcję `hi`, zatem użyjmy jej wewnątrz pętli: +We want to greet all of them by their name. We have the `hi` function to do that, so let's use it in a loop: {% filename %}python_intro.py{% endfilename %} ```python -for imie in dziewczyny: +for name in girls: ``` -Wyrażenie `for` zachowuje się podobnie jak `if`, a więc kod pod nimi musi być wcięty 4 spacjami. +The `for` statement behaves similarly to the `if` statement; code below both of these need to be indented four spaces. -Oto kompletny kod, który umieścimy w pliku: +Here is the full code that will be in the file: {% filename %}python_intro.py{% endfilename %} ```python -def hi(imie): - print('Witaj ' + imie + '!') +def hi(name): + print('Hi ' + name + '!') -dziewczyny = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'Ty'] -for imie in dziewczyny: - hi(imie) - print('Kolejna dziewczyna') +girls = ['Rachel', 'Monica', 'Phoebe', 'Ola', 'You'] +for name in girls: + hi(name) + print('Next girl') ``` -A gdy go uruchomimy: +And when we run it: {% filename %}command-line{% endfilename %} $ python3 python_intro.py - Hej Rachel! - Kolejna dziewczyna - Hej Monica! - Kolejna dziewczyna - Hej Phoebe! - Kolejna dziewczyna - Hej Ola! - Kolejna dziewczyna - Hej Ty! - Kolejna dziewczyna - - -Jak widzisz, cokolwiek umieścisz wewnątrz wyrażenia `for` wraz z wcięciem - zostanie powtórzone dla każdego elementu listy `dziewczyny`. - -Możesz także użyć `for` na liczbach, używając metody `range`: + Hi Rachel! + Next girl + Hi Monica! + Next girl + Hi Phoebe! + Next girl + Hi Ola! + Next girl + Hi You! + Next girl + + +As you can see, everything you put inside a `for` statement with an indent will be repeated for every element of the list `girls`. + +You can also use `for` on numbers using the `range` function: {% filename %}python_intro.py{% endfilename %} @@ -1044,7 +1030,7 @@ for i in range(1, 6): print(i) ``` -Co wypisze nam na ekranie: +Which would print: {% filename %}command-line{% endfilename %} @@ -1053,18 +1039,18 @@ Co wypisze nam na ekranie: 3 4 5 + +`range` is a function that creates a list of numbers following one after the other (these numbers are provided by you as parameters). -`range` jest funkcją, która tworzy listę liczb jedna po drugiej (liczby te podajesz jako parametry). - -Zwróć uwagę, że druga z tych liczb nie jest częścią listy stworzonej przez Pythona (to znaczy, że `range(1, 6)` liczy od 1 do 5, ale nie zawiera liczby 6). Dzieje się tak, bo "range" ma przedział jednostronnie otwarty, co oznacza, że zawiera pierwszą wartość z przedziału, ale nie zawiera ostatniej. +Note that the second of these two numbers is not included in the list that is output by Python (meaning `range(1, 6)` counts from 1 to 5, but does not include the number 6). That is because "range" is half-open, and by that we mean it includes the first value, but not the last. -## Podsumowanie +## Summary -To już wszystko. **Wspaniale Ci idzie!** To nie było wcale takie łatwe, możesz zatem być z siebie dumna. My zdecydowanie jesteśmy z Ciebie dumne, że dotarłaś do tego miejsca! +That's it. **You totally rock!** This was a tricky chapter, so you should feel proud of yourself. We're definitely proud of you for making it this far! -Oficjalny, kompletny tutorial Pythona znajdziesz pod adresem https://docs.python.org/3/tutorial/. Pozwoli on Tobie poznać język kompletnie i dogłębnie. Powodzenia! :) +For official and full python tutorial visit https://docs.python.org/3/tutorial/. This will give you a more thorough and complete study of the language. Cheers! :) -Jak myślisz, może czas na małą przerwę? Rozciągnij się, rozprostuj nogi, daj odpocząć oczom zanim przejdziesz do kolejnego rozdziału. :) +You might want to briefly do something else – stretch, walk around for a bit, rest your eyes – before going on to the next chapter. :) -![Babeczka](images/cupcake.png) \ No newline at end of file +![Cupcake](images/cupcake.png) \ No newline at end of file diff --git a/pl/python_introduction/prompt.md b/pl/python_introduction/prompt.md new file mode 100644 index 00000000000..27f422934c0 --- /dev/null +++ b/pl/python_introduction/prompt.md @@ -0,0 +1,17 @@ +## Python prompt + +> For readers at home: this part is covered in the [Python Basics: Integers, Strings, Lists, Variables and Errors](https://www.youtube.com/watch?v=MO63L4s-20U) video. + +To start playing with Python, we need to open up a *command line* on your computer. You should already know how to do that – you learned it in the [Intro to Command Line](../intro_to_command_line/README.md) chapter. + +Once you're ready, follow the instructions below. + +We want to open up a Python console, so type in `python` on Windows or `python3` on Mac OS/Linux and hit `enter`. + +{% filename %}command-line{% endfilename %} +``` +$ python3 +Python {{ book.py_release }} (...) +Type "help", "copyright", "credits" or "license" for more information. +>>> +``` diff --git a/pl/template_extending/README.md b/pl/template_extending/README.md old mode 100755 new mode 100644 index 5f57a77aa93..165ef2b4f3e --- a/pl/template_extending/README.md +++ b/pl/template_extending/README.md @@ -23,34 +23,36 @@ Następnie otwórz ten plik w edytorze kodu i skopiuj całą zawartość pliku ` ```html {% load static %} + Django Girls blog - - + - + -
+
-
+
{% for post in posts %} -
-
+
+
-

{{ post.title }}

+ +

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %}
-
+
``` @@ -61,17 +63,19 @@ Następnie, w `base.html`, zamień całą zawartość `` (wszystko, co zna ```html - -
+ +
-
+
{% block content %} {% endblock %}
-
+
``` @@ -92,13 +96,13 @@ Teraz zapisz `base.html` i otwórz ponownie w edytorze swój `blog/templates/blo ```html {% for post in posts %} -
-
+
+
+

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} ``` @@ -111,13 +115,13 @@ Będziemy chciały użyć tych kliku linii jako części szablonu dla wszystkich ```html {% block content %} {% for post in posts %} -
-
+
+
+

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} {% endblock %} ``` @@ -131,13 +135,13 @@ Została jeszcze jedna rzecz. Musimy połączyć te dwa szablony razem. To wła {% block content %} {% for post in posts %} -
-
+
+
+

{{ post.title }}

{{ post.text|linebreaksbr }}

-
+ {% endfor %} {% endblock %} ``` diff --git a/pl/whats_next/README.md b/pl/whats_next/README.md old mode 100755 new mode 100644 index 5ef9cc794d0..ef159f42963 --- a/pl/whats_next/README.md +++ b/pl/whats_next/README.md @@ -15,8 +15,9 @@ Tak! Jest *wiele* materiałów online do nauki dowolnych umiejętności programi #### Django - Nasza inna książka, [Django Girls Tutorial: Extensions ](https://tutorial-extensions.djangogirls.org/) -- [Oficjalny tutorial Django](https://docs.djangoproject.com/en/2.0/intro/tutorial01/) +- [Oficjalny tutorial Django](https://docs.djangoproject.com/en/3.2/intro/tutorial01/) - [Wideolekcje Getting Started with Django](http://www.gettingstartedwithdjango.com/) +- [Django for Everybody Specialization](https://www.coursera.org/specializations/django) – niektóre wykłady wideo można przesłuchać za darmo i zdobyć certyfikat Coursera biorąc udział w tych kursach #### HTML, CSS i JavaScript