Saya ingin dapat menangkap fakta seperti Bob was born in 2000
dan Bill's birthday is May 7th
.
Dalam kedua contoh tersebut, kita hanya mengetahui sebagian dari tanggal lahir orang tersebut. Dalam satu kasus kita hanya tahu tahun; dalam kasus lain kita tahu bulan dan hari, tetapi bukan tahun.
Bagaimana cara saya menangkap informasi ini?
Beberapa contoh cara kerjanya:
Bayangkan pustaka seperti datetime yang memungkinkan None di bidang untuk mewakili yang tidak diketahui. Saya mungkin memiliki kode seperti berikut ini:
date_a = date(2000, 5, None)
date_b = date(2000, 6, None)
difference = date_b - date_a
assert difference.min.days == 1
assert difference.max.days == 60 # Or something close to 60.
assert equal(date_a, date_b) == False
date_c = date(2000, 5, None)
assert equal(date_a, date_c) == Maybe
Ini hanyalah sebuah contoh bagaimana perilaku itu. Saya tidak selalu menginginkan perilaku yang tepat ini.
Jawaban:
Pertama-tama, begitu Anda mulai mendekomposisi tanggal ke dalam komponen penyusunnya, mereka bukan lagi tanggal.
Dengan cara yang sama bahwa tidak mungkin untuk menghapus fungsionalitas melalui subclass tanpa melanggar OOP, tidak mungkin untuk mencampur tanggal dan fraksi tanggal tanpa menyebabkan kebingungan (atau lebih buruk) membuatnya kompatibel seperti pada contoh kode Anda tanpa merusak sesuatu yang lain.
Jika Anda ingin menangkap satu tahun, apa yang salah dengan objek yang berisi bilangan bulat sederhana? Jika Anda ingin mengabadikan satu bulan dan satu hari, mengapa tidak mencatat satu bulan penghitungan dan satu hari bilangan bulat? Mungkin bahkan menyimpannya secara internal di objek tanggal sehingga Anda mendapatkan batas pemeriksaan yang tepat (mis. 31 Februari tidak masuk akal). Namun, tampilkan antarmuka yang berbeda.
Mengapa Anda ingin membandingkan tanggal dengan satu tahun untuk melihat apakah mereka sama, lebih besar, atau lebih kecil? Tidak masuk akal: tidak ada informasi yang cukup untuk membuat perbandingan itu. Namun, ada perbandingan lain yang mungkin masuk akal (ini adalah pseudocode):
sumber
Komentar kedua Robert Harvey berisi jawaban yang benar, tetapi izinkan saya sedikit mengembangkannya.
Tahun kelahiran orang dan tanggal lahir orang adalah entitas yang sama sekali berbeda, jadi Anda tidak perlu (dan sebenarnya Anda tidak boleh) menggunakan mekanisme yang sama untuk keduanya.
Untuk tanggal lahir, Anda dapat merancang
BirthDate
tipe data (atau mungkinYearlyRecurringDate
meskipun saya tidak dapat membuat nama yang layak saat ini) yang hanya akan berisidate
tahun yang konstan, seperti tahun 2000 berdasarkan konvensi. Tahun 2000 adalah pilihan yang baik karena itu adalah lompatan, sehingga tidak akan mengecewakan orang-orang yang berulang tahun pada tanggal 28 Februari.Selama bertahun-tahun kelahiran, Anda dapat merancang sebuah
BirthYear
tipe data (atau mungkinApproximateDate
tipe data) yang akan berisidate
, dan indikator presisi:Year
,Month
,Full
.Manfaat dari pendekatan ini adalah bahwa di jantung hal Anda masih mempertahankan
date
sehingga Anda masih dapat melakukan aritmatika tanggal.sumber
Saya percaya apa yang Anda gambarkan akan menjadi pengganti drop-in untuk
datetime
modul yang mengimplementasikandatetime.datetime
atribut (tahun, bulan, dll) sebagai nilai dengan pengukuran ketidakpastian (bukan hanya nilai).Paket Python ada untuk membantu dengan angka yang tidak pasti (misalnya: paket ketidakpastian ), dan mungkin tidak akan terlalu sulit untuk membuat garpu
datetime
yang menggunakan ketidakpastian pada setiap atribut. Saya juga ingin melihatnya dan bahkan mungkin menggunakannya untuk itu. Argumen pasti bisa dibuat untuk dimasukkannyaudatetime
ke dalam paket ketidakpastian yang terkait sebelumnya.Contoh Anda akan menjadi seperti:
"Nilai sinyal" memiliki banyak masalah, tetapi di samping itu Anda dapat mewakili hal-hal dengan ketidakpastian yang tidak dapat diperoleh nilai sinyal:
Pertimbangan lain adalah bahwa untuk lebih tepatnya ketidakpastian di sini sebenarnya harus bertipe
timedelta
. Saya meninggalkannya sebagai latihan bagi pembaca untuk mencari konstruktor yang ringkas dan lengkap untukudatetime
menggunakantimedelta
ketidakpastian.Jadi pada akhirnya saya akan mengatakan bahwa apa yang Anda gambarkan adalah "mudah" dimodelkan dengan ketidakpastian, tetapi implementasi a
udatetime
secara praktis cukup sulit. Sebagian besar akan mengambil rute "mudah" dan memecah datetime menjadi komponen dan melacak ketidakpastian pada mereka secara independen, tetapi jika Anda merasa ambisiusuncertainties
paket (atau yang lain) mungkin tertarik pada permintaan tarikudatetime
.sumber
Mengapa tidak membuat kelas "periode" yang mengimplementasikan dari ke struktur.
"Bob lahir tahun 2000" ->
Anda kemudian dapat menerapkan berbagai metode pencarian seperti dengan mengurutkan dari dari tanggal. Atribut fuzz memberikan indikasi yang berguna tentang seberapa akurat tanggal sehingga Anda dapat menentukan fuzz == 1 untuk pencocokan tepat, atau fuzz == 31 untuk dalam waktu sekitar satu bulan atau lebih.
sumber