Menulis tambalan pertama anda untuk Django

Kata Pengantar

Tertarik membalas kepada komunitas kecil? Mungkin Anda menemukan bug di Django yang ingin Anda perbaiki, atau mungkin ada fitur kecil yang ingin Anda tambahkan.

Membantu kembali Django itu sendiri adalah jalan terbaik untuk melihat masalah anda sendiri ditangani. Ini mungkin terlihat menakutkan pertama kali, tetapi itu sangat mudah. Kami akan berjalan bersama anda melalui pengolahan seluruhnya, sehingga anda dapat belajar berdasarkan contoh.

Untuk siapa saja tutorial ini?

lihat juga

Jika anda mencari referensi bagaimana mengajukan tambalan, lihat dokumentasi Mengajukan tambalan.

Untuk tutorial ini, kami berharap bahwa anda mempunyai setidaknya pengertian dasar bagaimana Django bekerja. Ini berarti anda harus nyaman melalui tutorial yang ada pada writing your first Django app. Sebagai tambahan, anda harus mempunyai pemahaman bagus dari Phyton itu sendiri. Tetapi jika anda tidak, Dive Into Python adalah luar biasa (dan gratis) buku daring untuk programer pemula Phyton.

Bagi anda yang tidak akrab dengan vesi kendali sistem dan Trac akan menemukan bahwa tutorial ini dan tautannya memasukkan informasi cukup untuk memulai. Bagaimanapun, anda akan mungkin membaca beberapa lebih alat berbeda jika anda berencana sering untuk membantu Django.

Untuk sebagian besar, tutorial ini mencoba menjelaskan sebanyak mungkin, sehingga itu dapat digunakan pada pendengar luas.

Dimana mendapatkan bantuan:

Jika anda mempunyai masalah melalui tutorial ini, siahkan tempatkan pesan ke django-developers atau jatuhkan dengan #django-dev on irc.freenode.net untuk mengobrol dengan pengguna Django lainnya yang mungkin dapat membantu.

Tutorial ini meliputi apa?

Kami akan berjalan bersama anda dalam membantu tambakan ke Django untuk pertama kali. Pada akhir tutorial ini, anda harus mempunyai pengertian dasar dari kedua alat dan pengolahan yang terlibat. Khususnya, kami akan mencangkup berikut:

  • Memasang Git
  • Mengunduh salinan versi pengembangan Django.
  • Menjalankan rangkaian percobaan Django.
  • Menulis percobaan untuk tambalan anda.
  • Menulis kode untuk tambalan anda.
  • Mencoba tambahan anda.
  • Mengajukan pull request
  • Dimana mencari untuk informasi lebih.

Sekali anda selesai dengan tutorial, anda dapat mencari sisa dari Django's documentation on contributing. Itu mengandung banyak informasi hebat dan harus dibaca untuk siapapun yang suka menjadi penyumbang rutin ke Django. Jika anda mendapatkan pertanyaan, itu mungkin mendapatkan jawaban.

Python 3 wajib!

Versi Django ini tidak mendukung Python 2.7. Dapatkan Python 3 di Halaman unduh Python atau menggunakan paket manajer dari sistem operasi yang Anda gunakan.

Untuk pengguna Windows

Ketika memasang Python di Windows, pastikan anda mencentang pilihan "Tambah phyton.exe ke Jalur", sehingga dia selalu tersedia di baris perintah.

Kode Etik

Sebagai penyumbang, anda dapat membantu kami menjaga komunitas Django terbuka dan inklusif. Silahkan baca dan ikuti ``Code of Conduct <https://www.djangoproject.com/conduct/>`_ kami.

Memasang Git

Untuk tutorial ini, anda akan membutuhkan Git terpasang untuk mengunduh versi pengembangan saat ini dari Django dan membangkitkan berkas tambalan untuk perubahan anda buat.

Untuk memeriksa apakah atau tidak anda telah terpasang Git, masukkan git ke baris perintah. Jika anda mendapatkan pesan dimana perintah ini tidak ditemukan, anda akan perlu mengunduh dan memasangnya, lihat Halaman unduh Git.

Jika anda tidak akrab dengan Git, anda dapat selalu menemukan lebih tentang perintahnya (pertama dia dipasang) dengan mengetik git help kedalam baris perintah.

Mendapatkan salinan versi pengembangan Django

Langkah pertama untuk membantu Django adalah mendapatkan sebuah salinan dari kode sumber. Pertama, fork Django on GitHub. Kemudian, dari baris perintah, gunakan perintah cd untuk melayari ke direktori dimana anda akan ingin salinan lokal anda dari Django menjadi langsung.

Unduh gudang kode sumber Django menggunakan perintah berikut:

$ git clone https://github.com/YourGitHubName/django.git
...\> git clone https://github.com/YourGitHubName/django.git

Hubungan lebar pita rendah?

Anda dapat menambah argumen --depth 1 pada git clone untuk melewati pengunduhan semua dari riwayat penyerahan Django, yang mengurangi perpindahan data dari ~250 MB menjadi ~70 MB.

Sekarang dimana anda memiliki salinan lokal Django, anda dapat memasang itu seperti anda memasang paket apapun menggunakan pip. Cara paling nyaman melakukannya adalah dengan menggunakan virtual environment, yaitu fitur dibangun kedalam Python yang mengizinkan anda menjaga direktori terpisah dari paket-paket terpasang untuk setiap dari proyek-proyek anda sehingga mereka tidak mengganggu satu sama lain.

Itu adalah ide bagus menjaga semua lingkungan maya anda dalam satu tempat, sebagai contoh dalam .virtualenvs/ di direktori rumah anda.

Buat lingkungan maya baru dengan menjalankan:

$ python3 -m venv ~/.virtualenvs/djangodev
...\> py -m venv %HOMEPATH%\.virtualenvs\djangodev

Jalur dimana lingkungan baru akan disimpan ke komputer anda.

langkah akhir dalam mengatur lingkungan maya adalah mengaktifkan itu:

$ source ~/.virtualenvs/djangodev/bin/activate

Jika perintah source tidak tersedua, anda dapat mencoba menggunakan titik:

$ . ~/.virtualenvs/djangodev/bin/activate

Untuk pengguna Windows

Untuk mengaktifkan lingkungan maya pada Windows, jalankan:

...\> %HOMEPATH%\.virtualenvs\djangodev\Scripts\activate.bat

Anda harus mengaktifkan lingkungan maya kapanpun anda membuka jendela terminal baru. virtualenvwrapper adalah alat berguna untuk membuat ini lebih nyaman.

Nama dari lingkungan maya diaktivasi sekarang ditampilkan pada baris perintah untuk membantu anda melacak dimana yang anda sedang gunakan. Apapun anda pasang melalui pip selagi nama ini ditampilkan akan dipasang dalam lingkungan maya, terpencil dari lingkungan dan paket-paket sistem-lebar.

Lanjutkan dan pasang klon salinan sebelumnya dari Django:

$ pip install -e /path/to/your/local/clone/django/
...\> pip install -e \path\to\your\local\clone\django\

The installed version of Django is now pointing at your local copy by installing in editable mode. You will immediately see any changes you make to it, which is of great help when writing your first patch.

Creating projects with a local copy of Django

It may be helpful to test your local changes with a Django project. First you have to create a new virtual environment, install the previously cloned local copy of Django in editable mode, and create a new Django project outside of your local copy of Django. You will immediately see any changes you make to Django in your new project, which is of great help when writing your first patch.

Menjalankan rangkaian percobaan Django untuk pertama kali

Ketika membantu Django adalah sangat penting bahwa perubahan kode anda tidak memperkenalkan kesalahan kedalam kawasan lain dari Django. Satu cara untuk memeriksanya bahwa Django masih bekerja setelah anda membuat perubahan anda adalah dengan menjalankan rentetnan percobaan Django. Jika semua percobaan masih lolos, kemudian anda dapat secara wajar yakin bahwa perubahan anda vekerja dan tidak merusak bagian lain Django. Jika anda belum pernah menjalankan deretan percobaan Django, itu adalah ide bagus menjalankan sekali sebelum akrab dengan masukannya.

Sebelum menjalankan deretan percobaan, pasang ketergantungannya dengan men-cd kedalam direktori tests/ dan kemudian menjalankan:

$ pip install -r requirements/py3.txt
...\> pip install -r requirements\py3.txt

Jika anda menjumpai sebuah kesalahan selama pemasangan, sistem anda mungkin kehilangan ketergantungan dari satu atau lebih paket-paket Python. Rundingkan dokumentasi paket-paket gagal atau cari Jaringan dengan pesan kesalahan yang anda jumpai.

Sekarang kita siap menjalankan deretan percobaan. Jika anda menggunakan GNU/Linux, macOS, atau beberapa Unix rasa lainnya, jalankan:

$ ./runtests.py
...\> runtests.py 

Sekarang duduk dan santai. Keseluruhan deretan percobaan Django mempunyai ribuan percobaan, dan itu mengambil setidaknya sedikit menit untuk berjalan, bergantung pada kecepatan dari komputer anda.

Selagi deretan percobaan Django berjalan, anda akan melihat aliran karakter mewakili keadaan dari setiap percobaan sampai itu lengkap. E menunjukkan bahwa sebuah kesalahan memunculkan selama percobaan, dan F menunjukkan bahwa tuntutan percobaan gagal. Kedua dari ini dipertimbangkan menjadi kegagalan percobaan. Sementara itu, x dan s menunjukkan diharapkan kegagalan dan melewati percobaan, masing-masing. Titik menunjukkan percobaan lolos.

Lewati percobaan biasanya karena kehilangan pustaka luar yang diwajibkan untuk menjalankan percobaan; lihat Menjalankan semua percobaan untuk daftar dari ketergantungan dan pastikan memasang tiap untuk percobaan terhubung ke perubahan anda sedang buat (kami tidak akan butuh untuk tutorial ini). Beberapa percobaan sangat khusus pada backend basisdata tertentu dan akan dilewati jika tidak dicobakan dengan backend itu. SQLite adalah backend basisdata untuk pengaturan awal. Untuk menjalankan percobaan menggunakan backend berbeda, lihat Gunakan modul pengaturan lain.

Ketika percobaan lengkap, anda akan disapa dengan pesan menginformasikan bahwa deretan percobaan lulus atau gagal. Sejak anda tidak mempunyai perubahan apapun ke kode Django, deretan percobaan seluruhnya harus lulus. Jika anda mendapatkan kegagalan atau kesalahan pastikan anda telah mengikuti langkah sebelumnya dengan benar. Lihat Menjalankan satuan percobaan untuk informasi lebih.

Catat bahwa master Django terakhir mungkin tidak selalu stabil. Ketika mengembangkan terhadap master, anda dapat memeriksa Django's continuous integration builds untuk menentukan jika kegagalan adalah khusus pada mesin anda atau jika mereka juga hadir dalam bangunan resmi Django. Jika anda mengklik untuk menampilkan sebuah bangun tertentu, anda dapat menampilkan "Configuration Matrix" yang menunjukkan kegagalan rusak oleh versi Python dan backend basisdata.

Catatan

Untuk tutorial ini dan tiket yang kita sedang bekerja, percobaan terhadap SQLite adalah cukup, bagaimanapun, ini memungkinkan (dan terkadang butuh) untuk menjalankan percobaan menggunakan basisdata berbeda.

Bekerja pada fitur

Untuk pengajaran tambahan ini, kami akan bekerja pada "tiket palsu" sebagai sebuah kasus pelajaran. Disini adalah rincian gambaran:

Tiket #99999 -- Mengizinkan membuat tos

Django harus menyediakan sebuah fungsi django.shortcuts.make_toast() yang mengembalikan 'toast'.

Kami akan menerapkan fitur ini dan percobaan terkait.

Membuat sebuah cabang untuk tambalan anda

Sebelum membuat perubahan apapun, buat sebuah cabang baru untuk tiket:

$ git checkout -b ticket_99999
...\> git checkout -b ticket_99999

Anda dapat memilih nama apapun yang anda ingin untuk cabang, "ticket_99999" adalah sebuah contoh. Semua perubahan dibuat dalam cabang ini akan khusus pada tiket dan tidak akan mempengaruhi salinan uta,a dari kode yang kami kloning diawal.

Menulis beberapa percobaan untuk tiket anda

Dalam kebanyakan kasus, untuk tambalan diterima kedalam Django dia harus disertakan percobaan. Untuk tambalan perbaikan kesalahan, ini berarti menulis percobaan pemulihan untuk memastikan bahwa kesalahan tidak pernah diperkenalkan kembali kedalam Django kemudian. Percobaan pemulihan harus ditulis dalam cara tersebut yang dia akan gagal selama kesalahan masih ada dan lulus ketika kesalahan telah diperbaiki. Untuk tambalan mengandung fitur baru, anda akan butuh menyertakan percobaan yang memastikan fitur baru bekerja dengan benar. Mereka juga akan gagal ketika fitur baru tidak hadir, dan lalu lulus ketika dia telah diterapkan.

Jalan baik untuk melakukannya ini adalah pertama menulis percobaan baru anda, sebelum membuat perubahan apapun ke kode. Gaya ini dari pengembangan dipanggil test-driven development dan dapat diberlakukan untuk kedua proyek keseluruhan dan tambalan tunggal. Setelah menulis percobaan anda, anda kemudian jalankan mereka untuk memastikan bahwa mereka memang gagal (sejak anda belum memperbaiki kesalahan tersebut atau ditambahkan fitur tersebut). Jika percobaan baru anda tidak gagal, anda akan butuh memperbaiki mereka sehingga mereka melakukannya. Lagipula, percobaan pemulihan yang lulus tanpa memperhatikan apakah kesalahan hadir tidak sangat membantu dalam mencegah kesalahan dari terjadi di jalan.

Sekarang untuk contoh meneruskan kami.

Menulir percobaan untuk tiket #99999

Untuk menyelesaikan tiket ini, kami akan menambahkan sebuah fungsi make_toast() pada tingkat-atas modul django. Pertama kami akan menulis sebuah percobaan yang mencoba menggunakan fungsi dan memeriksa bahwa keluarannya terlihat benar.

Kemudikan ke folder tests/shortcuts/ Django dan buat sebuah berkas baru test_make_toast.py. Tambah kode berikut:

from django.shortcuts import make_toast
from django.test import SimpleTestCase


class MakeToastTests(SimpleTestCase):
    def test_make_toast(self):
        self.assertEqual(make_toast(), 'toast')

Percobaan ini memeriksa bahwa make_toast() mengembalikan 'toast'.

Tetapi percobaan ini terlihat sangat sulit...

Jika anda tidak pernah berurusan dengan percobaan sebelumnya, mereka dapat kelihatan sedikir sulit untuk menulis pandangan pertama. Untungnya, percobaan adalah subyek sangat besar di pemrograman komputer, sehingga terdapat banyak informasi diluar sana:

  • Tampilan bagus pertama pada penulisan percobaan untuk Django dapat ditemukan di dokumentasi pada Menulis dan menjalankan percobaan.
  • Dive Into Python (sebuah buku daring bebas untuk pengembang Phyton pemula) termasuk Perkenalan ke Unit Percobaan hebat.
  • Setelah membaca itu, jika anda ingin sesuatu sedikit daging untuk menengelamkan gigi anda kedalamnya, selalu ada dokumentasi unittest Python.

Menjalankan percobaan baru anda

Sejak kami belum membuat perubahan apapun pada django.shortcuts, percobaan kami harus gagal. Mari kita jalankan semua percobaan dalam folder shortcuts untuk memastikan bahwa itu memang terjadi. cd ke direktori tests/ Django dan jalankan:

$ ./runtests.py shortcuts
...\> runtests.py shortcuts

Jika percobaan berjalan dengan benar, anda harus melihat satu kegagalan berhubungan pada metode percobaan kami tambahkan, dengan kesalahan ini:

ImportError: cannot import name 'make_toast' from 'django.shortcuts'

Jika semua percobaan dilewati, kemudian anda akan ingin memastikan bahwa anda menambahkan percobaan terbaru ditampilkan diatas pada folder dan nama berkas sesuai.

Menulis kode untuk tiket anda

Selanjutnya kami akan menambahkan fungsi make_toast().

Kemudikan ke folder django/ dan buka berkas shortcuts.py. Pada bagian bawah, tambah:

def make_toast():
    return 'toast'

Sekarang kami butuh memastikan bahwa percobaan kami tulis sebelumnya lolos, jadi kami dapat melihat apakah kode kami tambahkan bekerja dengan benar. Kembali, kemudikan ke direktori tests/ Django dan jalankan:

$ ./runtests.py shortcuts
...\> runtests.py shortcuts

Semuanya harus dilewatkan. Jika itu tidak, pastikan anda dengan benar menambahkan fungsi ke berkas benar.

Menjalankan rangkaian percobaan Django untuk kedua kali

Ketika anda telah memeriksa bahwa tambalan anda dan percobaan anda bekerja dengan benar, adalah ide bagus untuk menjalankan deretan percobaan Django keseluruhan hanya untuk menmeriksa bahwa perubahan anda tidak memunculkan kesalahan apapun kedalam kawasan lain Django. Ketika berhasil lulus deretan percobaan keseluruhan tidak menjamin kode anda bebas kesalahan, itu membantu mencirikan banyak kesalahan dan kemunduran yang mungkin tidak diketahui.

Untuk menjalankan seluruh rangkaian percobaan Django, cd kedalam direktori test/ Django dan jalankan:

$ ./runtests.py
...\> runtests.py 

Menulis Dokumentasi

Ini adalah fitur baru, jadi itu harus didokumentasikan. Buka berkas docs/topics/http/shortcuts.txt dan tambah berikut pada akhir dari berkas:

``make_toast()``
================

.. versionadded:: 2.2

Returns ``'toast'``.

Sejak fitur ini akan berada dalam terbitan akan datang itu juga akan ditambahkan ke catatan terbitan untuk versi selanjutnya dari Django. Buka catatan terbitan untuk versi terakhir dalam docs/releases/, yang pada saat penulisan ini 2.2.txt. Tambah sebuah catatan dibawah kepala "Minor Features":

:mod:`django.shortcuts`
~~~~~~~~~~~~~~~~~~~~~~~

* The new :func:`django.shortcuts.make_toast` function returns ``'toast'``.

Untuk informasi lebih dalam menulis dokumen, termasuk penjelasan dari apa semua tentang bit versionadded, lihat Menulis dokumentasi. Halaman itu juga menyertakan sebuah penjelasan dari bagaimana membangun salinan dari dokumentasi secara lokal, sehingga anda dapat meninjau HTML yang akan dibangkitkan.

Pratinjau perubahan anda

Sekarang saatnya melalui semua perubahan dibuat dalam tambalan kami. Untuk melancarkan semua perubahan siap diserahkan, jalankan:

$ git add --all
...\> git add --all

Kemudian tampilkan perbedaan diantara salinan saat ini dari Django (dengan perubahan anda) dan perbaikan yang anda awali periksa di paling awal dengan petunjuk penggunaan:

$ git diff --cached
...\> git diff --cached

Gunakan kunci panah untuk pindah ke atas dan ke bawah.

diff --git a/django/shortcuts.py b/django/shortcuts.py
index 7ab1df0e9d..8dde9e28d9 100644
--- a/django/shortcuts.py
+++ b/django/shortcuts.py
@@ -156,3 +156,7 @@ def resolve_url(to, *args, **kwargs):

     # Finally, fall back and assume it's a URL
     return to
+
+
+def make_toast():
+    return 'toast'
diff --git a/docs/releases/2.2.txt b/docs/releases/2.2.txt
index 7d85d30c4a..81518187b3 100644
--- a/docs/releases/2.2.txt
+++ b/docs/releases/2.2.txt
@@ -40,6 +40,11 @@ database constraints. Constraints are added to models using the
 Minor features
 --------------

+:mod:`django.shortcuts`
+~~~~~~~~~~~~~~~~~~~~~~~
+
+* The new :func:`django.shortcuts.make_toast` function returns ``'toast'``.
+
 :mod:`django.contrib.admin`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt
index 7b3a3a2c00..711bf6bb6d 100644
--- a/docs/topics/http/shortcuts.txt
+++ b/docs/topics/http/shortcuts.txt
@@ -271,3 +271,12 @@ This example is equivalent to::
         my_objects = list(MyModel.objects.filter(published=True))
         if not my_objects:
             raise Http404("No MyModel matches the given query.")
+
+``make_toast()``
+================
+
+.. function:: make_toast()
+
+.. versionadded:: 2.2
+
+Returns ``'toast'``.
diff --git a/tests/shortcuts/test_make_toast.py b/tests/shortcuts/test_make_toast.py
new file mode 100644
index 0000000000..6f4c627b6e
--- /dev/null
+++ b/tests/shortcuts/test_make_toast.py
@@ -0,0 +1,7 @@
+from django.shortcuts import make_toast
+from django.test import SimpleTestCase
+
+
+class MakeToastTests(SimpleTestCase):
+    def test_make_toast(self):
+        self.assertEqual(make_toast(), 'toast')

Ketika anda selesai meninjau tambalan, kenai kunci q untuk kembali ke baris perintah. Jika isi tambalan terlihat oke, waktunya memperbaiki perubahan.

Memperbaiki perubahan di tambalan

Memperbaiki perubahan:

$ git commit
...\> git commit

Ini membuka penyunting teks untuk mengetik pesanperbaikan. Ikuti commit message guidelines dan tulis sebuah pesan seperti:

Fixed #99999 -- Added a shortcut function to make toast.

Mendorong perbaikan dan membuat sebuah pull request

Setelah menyerahkan tambalan, kirim itu ke cabang dari GitHub (mengganti "ticket_99999" dengan nama dari cabang anda jika itu berbeda):

$ git push origin ticket_99999
...\> git push origin ticket_99999

Anda dapat membuat sebuah pull request dengan mengunjungi Django GitHub page. Anda akan melihat cabang anda dibawah "Your recently pushed branches". Klik "Compare & pull request" dekatnya.

Harap jangan melakukan itu untuk tutorial ini. tetapi pada halaman selanjutnya yang memperlihatkan tinjauan dari tambalan, anda akan mengklik "Create pull request".

Langkah-langkah selanjutnya

Selamat, anda telah belajar bagaimana membuat sebuah pull request pada Django! Rincian dari teknik-teknik lebih lanjut anda mungkin butuh adalah di Bekerja dengan Git dan GitHub.

Sekarang anda dapat menaruh keahlian-keahlian tersebut untuk penggunaan bagus dengan membantu memperbaiki kode dasar Django.

Informasi lebih untuk penyumbang baru

Sebelum anda terlalu kedalam menulis tambalan untuk Django, terdapat sedikit informasi lebih di bantuan yang anda harus mungkin lihat pada:

  • Anda harus pastikan membaca dokumentasi Django di claiming tickets and submitting patches. Itu melingkup tata cara Trac, bagaimana menyatakan tiket untuk anda sendiri, gaya pengkodean yang diharapkan untuk tambalan, dan banyak rincian penting lain.
  • Pertama kali penyumbang harus juga membaca documentation for first time contributors. Django. Itu mempunyai banyak saran baik untuk siapa dari kita yang baru untuk dibantu dengan Django.
  • Setelah itu, jika anda masih terburu-buru untuk informasi lebih tentang bantuan, anda dapat selalu menjelajah melalui sisa Django's documentation on contributing. Itu mengandung ton dari informasi berguna dan harus menjadi sumber pertama anda untuk menjawab pertanyaan papun anda mungkin punya.

Temukan tiket sungguhan pertama anda

Ketika anda telah mencari beberapa informasi itu, anda akan siap keluar dan menemukan tiket dari milik anda untuk menulis tambalan. Perhatian khusus ke tiket dengan standar "pemetikan mudah". Tiket ini sering banyak sederhana di alam dan hebat untuk pertama kali penyumbang. Ketika anda akrab dengan membantu ke Django, anda dapat pindah ke menulis tambalan untuk tiket lebih sulit dan rumit.

Jika anda hanya ingin segera mulai (dan tidak siapapun akan menyalahkan anda!), coba lihatlah daftar dari easy tickets that need patches dan easy tickets that have patches which need improvement. Jika anda akrab dengan menulis percobaan, anda dapat juga melihat daftar easy tickets that need tests. Hanya ingat untuk mengikuti panduan berikut tentang menyatakan tiket yang disebutkan di tautan pada dokumentasi Django di claiming tickets and submitting patches.

Apa selanjutnya setelah membuat sebuah pull request?

Setelah tiket mempunyai tambalan, itu butuh ditinjau dengan sekumpulan mata kedua. Setelah mengajukan permintaan penarikan, perbaharui metadata tiket dengan mengatur bendera di tiket untuk mengatakan "punya tambalan", "tidak butuh percobaan", dll, sehingga lainnya dapat menemukannya untuk ditinjau. Membantu tidak perlu selalu berarti menulis tambalan dari awal. Meninjau tambalan yang ada juga sangat membantu. Lihat Mendahulukan tiket untuk rinci.

Back to Top