from fractions import Fraction
values = (7, Fraction(7, 3), 7 / 3)
[(type(value).__name__, value) for value in values][('int', 7), ('Fraction', Fraction(7, 3)), ('float', 2.3333333333333335)]
Setelah menyelesaikan unit ini, pembaca dapat:
Prasyarat lokal: Unit 1, himpunan dan fungsi pada tingkat A30, serta operasi dasar pada vektor berhingga. Unit ini belum memerlukan NumPy.
Pernyataan matematika menentukan himpunan objek dan operasi yang sah. Program membutuhkan tipe data konkret. Keduanya berkaitan, tetapi tidak identik.
| Maksud matematika | Representasi awal | Batas penting |
|---|---|---|
| bilangan bulat | int |
ukuran praktis dibatasi memori |
| bilangan rasional | Fraction |
pembilang dan penyebut dapat membesar |
| pendekatan bilangan real | float |
pembulatan dan rentang berhingga |
| vektor berhingga yang tetap | tuple |
panjang dan jenis komponen harus diperiksa |
| koleksi yang sengaja diubah | list |
alias dapat melihat perubahan yang sama |
from fractions import Fraction
values = (7, Fraction(7, 3), 7 / 3)
[(type(value).__name__, value) for value in values][('int', 7), ('Fraction', Fraction(7, 3)), ('float', 2.3333333333333335)]
Nama tipe tidak membuktikan bahwa nilai memenuhi maksud matematika. Sebuah tuple berpanjang tiga dapat mewakili vektor di ruang tiga dimensi, koordinat warna, atau tiga data yang tidak berhubungan. Kontrak programlah yang memberi makna tambahan itu.
Operator == membandingkan nilai menurut aturan tipe. Operator is memeriksa apakah dua nama menunjuk objek Python yang sama. Untuk alasan reproduksibilitas, jangan mengganti pertanyaan tentang nilai dengan pertanyaan tentang identitas objek.
a = [1, 2, 3]
b = a
c = list(a)
(a == c, a is c, a is b)(True, False, True)
Karena b adalah alias bagi a, perubahan melalui salah satu nama tampak melalui nama lainnya. Sebaliknya, c mula-mula mempunyai nilai sama, tetapi merupakan daftar lain. Efek semacam ini dapat membuat eksperimen bergantung pada urutan eksekusi sel.
Jika suatu vektor dimaksudkan sebagai nilai yang tidak berubah, tuple memberi kontrak yang lebih jujur daripada list. Ini bukan larangan memakai daftar; pilih perubahan hanya ketika perubahan tersebut bagian dari metode.
Fungsi komputasional yang baik menyatakan tiga hal:
Contoh berikut menghitung rata-rata rasional secara eksak.
from fractions import Fraction
def mean_fraction(values):
"""Kembalikan rata-rata eksak dari barisan rasional yang tidak kosong."""
values = tuple(Fraction(value) for value in values)
if not values:
raise ValueError("values tidak boleh kosong")
return sum(values, start=Fraction(0)) / len(values)
mean_fraction([Fraction(1, 3), Fraction(1, 2)])Fraction(5, 12)
Konversi ke tuple membekukan masukan yang benar-benar dipakai fungsi. Jika pemanggil mengubah daftar asal setelah pemanggilan dimulai, perhitungan lokal tidak ikut berubah.
Fungsi berikut mengalikan vektor dengan skalar tanpa mengubah argumennya.
def scale_vector(scalar, vector):
return tuple(scalar * component for component in vector)
v = (2, -1, 4)
(scale_vector(3, v), v)((6, -3, 12), (2, -1, 4))
Untuk masukan yang sama, fungsi murni menghasilkan keluaran yang sama dan tidak mengubah keadaan di luar fungsi. Sifat ini memudahkan pengujian dan pelacakan asal hasil. Program nyata tetap perlu membaca berkas atau menulis keluaran; tempatkan efek tersebut di batas program, bukan tersebar di setiap fungsi matematika.
Invarian adalah sifat yang harus tetap benar selama operasi tertentu. Untuk perkalian skalar pada vektor, beberapa invarian yang dapat diuji ialah:
scale_vector(a*b, v) sama dengan scale_vector(a, scale_vector(b, v)).Tes terhadap banyak contoh dapat mendeteksi pelanggaran implementasi. Bukti aljabar tetap diperlukan untuk menyatakan sifat bagi semua skalar dan semua vektor pada domain yang dimaksud.
Dua eksperimen dapat menghasilkan informasi sama tetapi byte berbeda karena urutan medan, spasi, atau akhir baris. Bila keluaran dipakai sebagai bukti kerja, tentukan bentuk kanonis. Skrip Unit 2:
python source/code/unit02_objects.py --output output/unit02-results.json
menulis JSON UTF-8 dengan nama medan terurut, inden tetap, dan akhir baris LF. Hash berkas lalu mengikat satu urutan byte yang dapat dibandingkan.
Pilih representasi awal untuk setiap objek berikut dan jelaskan batasnya: , pendekatan numerik bagi , dan vektor tetap .
Bedakan nilai eksak dari pendekatan dan nilai tetap dari koleksi yang diubah.
Gunakan Fraction(2, 7) bagi bilangan rasional eksak, float bagi pendekatan numerik terhadap akar dua dengan toleransi yang dinyatakan, dan tuple bagi vektor tetap. float tidak menyimpan akar dua secara eksak, sedangkan tuple tidak dengan sendirinya menjamin bahwa semua komponennya numerik.
Buat dua daftar berbeda dengan nilai [1, 2]. Tunjukkan satu perbandingan yang benar dan satu perbandingan yang salah. Jelaskan hasilnya.
Gunakan == dan is.
Jika a=[1,2] dan b=[1,2], maka a == b benar karena nilainya sama, sedangkan a is b salah karena keduanya objek berbeda. Pertanyaan matematika tentang kesamaan daftar unsur biasanya memakai ==.
Tuliskan prasyarat, hasil, dan kegagalan untuk fungsi yang mengembalikan sisa terkecil taknegatif dari pembagian dengan modulus .
Modulus harus positif.
Prasyarat: a dan m bilangan bulat serta m > 0. Hasil: bilangan bulat r dengan 0 <= r < m dan a-r habis dibagi m. Jika m <= 0, fungsi harus menolak masukan, misalnya dengan ValueError.
Jelaskan mengapa fungsi yang menambahkan elemen ke daftar masukan dapat membuat hasil eksperimen bergantung pada urutan sel notebook. Berikan satu perbaikan.
Nama lain mungkin menunjuk daftar yang sama.
Pemanggilan pertama mengubah daftar yang kemudian dipakai pemanggilan kedua. Menjalankan sel dalam urutan lain memberi keadaan awal berbeda. Perbaikannya dapat berupa mengembalikan daftar baru, memakai tuple bagi nilai tetap, atau membuat perubahan eksplisit serta mengatur ulang keadaan sebelum eksperimen.
Apakah menguji empat invarian scale_vector untuk sejuta vektor membuktikan bahwa implementasinya benar bagi semua masukan? Berikan jawaban yang tepat.
Pisahkan domain yang diuji dari domain universal.
Tidak. Tes tersebut memberi bukti kerja kuat pada sampel dan dapat menemukan contoh penyangkal, tetapi tidak mencakup semua masukan. Kebenaran umum fungsi diperoleh dengan memeriksa definisi implementasi terhadap hukum distributif dan asosiatif pada domain skalar serta komponen yang dinyatakan.
== membandingkan nilai; is membandingkan identitas objek.