ฉันจะสร้างแบบจำลองวันที่บางส่วนใน Python ได้อย่างไร เช่นปีที่ไม่รู้จักหรือวันที่ไม่รู้จักของเดือน?


11

ฉันต้องการที่จะสามารถจับข้อเท็จจริงเหมือนและBob was born in 2000Bill's birthday is May 7th

ในตัวอย่างทั้งสองเรารู้เพียงส่วนหนึ่งของวันเดือนปีเกิดของบุคคลนั้น ในกรณีหนึ่งเรารู้เพียงปีเท่านั้น ในกรณีอื่นเรารู้เดือนและวัน แต่ไม่ใช่ปี

ฉันจะรวบรวมข้อมูลนี้ได้อย่างไร

ตัวอย่างเล็ก ๆ น้อย ๆ ของการทำงานนี้:

ลองนึกภาพห้องสมุดเช่นวันที่และเวลาที่อนุญาตให้ไม่มีในเขตข้อมูลเพื่อแสดงสิ่งที่ไม่รู้จัก ฉันอาจมีรหัสดังนี้:

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

นี่เป็นเพียงตัวอย่างของพฤติกรรมที่อาจเกิดขึ้น ฉันไม่ต้องการพฤติกรรมที่แม่นยำนี้


โดยทั่วไปวิธีที่คุณจัดการกับสิ่งต่าง ๆ เช่นนี้คือการใช้ตัวอย่างเช่นปี 0001 ใน. NET สำหรับวันที่ไม่มีปีและวันที่ 1 มกราคมเป็นปีโดยไม่มีเดือนและวัน
Robert Harvey

ฉันแก้ไขคำถามของคุณเพื่อลบคำขอสำหรับห้องสมุด คำถามดังกล่าวอยู่นอกหัวข้อในเว็บไซต์นี้

@RobertHarvey ฉันไม่สามารถใช้คำแนะนำของคุณ หากเราเห็นว่าบ๊อบเกิดเมื่อวันที่ 1 มกราคม 2000 เราไม่ทราบว่าสิ่งนี้มีความหมายอย่างไร เราไม่สามารถบอกได้ว่าเขาเกิดในวันแรกของปี 2000 หรือถ้าเขาเกิดมาวันใดวันหนึ่งปี 2000 เราต้องรู้ถึงความแตกต่าง
Buttons840

@ RobertHarvey ฉันรู้ว่ามันเป็นเรื่องปกติ แต่ฉันได้เห็นความล้มเหลวที่ไม่ดีมากมายเนื่องจากตัวเลือกที่ไม่ดีของค่าสัญญาณดังกล่าว (นอกจากนี้ฉันไม่คิดว่ามันจะตอบคำถามเนื่องจาก OP ต้องการจัดการกับบางวันที่ไม่ทราบการตั้งค่าเป็นวันที่ 1 มกราคมในกรณีเช่นนี้ไม่อนุญาตให้คุณแยกความแตกต่างวันที่ 1 ม.ค. จริงจากสิ่งแปลกปลอม
Gort the Robot

5
@ Buttons840: จากนั้นคุณจะต้องเขียนคลาสที่ห่อหุ้มพฤติกรรมที่คุณต้องการ คุณควรห่อคลาสวันที่ที่มีอยู่และเพิ่มพฤติกรรมที่คุณต้องการ
Robert Harvey

คำตอบ:


3

ก่อนอื่นเลยเมื่อคุณเริ่มแยกวันที่เป็นส่วนประกอบของมันแล้ววันนั้นจะไม่เป็นวันที่อีกต่อไป

ในทำนองเดียวกับที่ไม่สามารถลบฟังก์ชันการทำงานผ่านคลาสย่อยโดยไม่ทำลาย OOP คุณจะไม่สามารถผสมวันที่และวันที่โดยไม่ทำให้เกิดความสับสน (หรือแย่กว่า) ทำให้เข้ากันได้ในตัวอย่างโค้ดของคุณ

หากคุณต้องการจับภาพหนึ่งปีมีอะไรผิดปกติกับวัตถุที่มีจำนวนเต็มอย่างง่าย? หากคุณต้องการจับภาพเดือนและวันทำไมไม่จับการแจงนับเดือนและวันจำนวนเต็ม? อาจจัดเก็บไว้ภายในวัตถุวันที่เพื่อให้คุณได้รับการตรวจสอบขอบเขตที่เหมาะสม (เช่น 31 กุมภาพันธ์ไม่มีเหตุผล) เปิดเผยอินเตอร์เฟสที่ต่างออกไป

ทำไมคุณต้องการเปรียบเทียบวันที่กับปีเพื่อดูว่าพวกเขาเหมือนกันมากขึ้นหรือน้อยลง? ไม่มีเหตุผล: ไม่มีข้อมูลเพียงพอที่จะทำการเปรียบเทียบ อย่างไรก็ตามมีการเปรียบเทียบอื่น ๆ ที่อาจสมเหตุสมผล (นี่คือ pseudocode):

Year y = Year(2015)
Date d = Date(2015, 01, 01)
assert y.contains(d) == True

2

ความคิดเห็นที่สองของ Robert Harvey มีคำตอบที่ถูกต้อง แต่ขอผมขยายหน่อย

ปีเกิดของผู้คนและวันเกิดของผู้คนนั้นแตกต่างกันอย่างสิ้นเชิงดังนั้นคุณไม่จำเป็นต้อง (และจริงๆแล้วคุณไม่ควร) ใช้กลไกเดียวกันนี้สำหรับทั้งคู่

สำหรับวันเกิดคุณสามารถกำหนดBirthDateประเภทข้อมูล (หรืออาจเป็นได้YearlyRecurringDateว่าฉันไม่สามารถหาชื่อที่เหมาะสมได้ในขณะนี้) ซึ่งจะมีเพียงdateปีคงที่เช่นปี 2000 ตามแบบแผน ปี 2000 เป็นทางเลือกที่ดีเพราะเป็นก้าวกระโดดดังนั้นจะไม่ล้มเหลวกับคนที่เกิดในวันที่ 28 กุมภาพันธ์

สำหรับปีเกิดคุณสามารถประดิษฐ์BirthYearชนิดข้อมูล (หรืออาจจะเป็นApproximateDateชนิดข้อมูล) ซึ่งจะมีdateและตัวบ่งชี้ของความแม่นยำ: Year, ,MonthFull

ประโยชน์ของวิธีการเหล่านี้คือหัวใจของสิ่งต่าง ๆ ที่คุณยังคงรักษาไว้dateเพื่อให้คุณยังคงสามารถคำนวณวันที่ได้


1

ฉันเชื่อว่าสิ่งที่คุณกำลังอธิบายจะเป็นการแทนที่สำหรับdatetimeโมดูลที่ใช้datetime.datetimeคุณลักษณะ (ปี, เดือน, ฯลฯ ) เป็นค่าที่มีการวัดความไม่แน่นอน (แทนที่จะเป็นเพียงค่า)

แพคเกจ Python มีอยู่เพื่อช่วยให้มีจำนวนที่ไม่แน่นอน (เช่น: แพคเกจที่ไม่แน่นอน ) และบางทีมันก็ไม่ยากเกินไปที่จะสร้างทางแยกdatetimeที่ใช้ความไม่แน่นอนในแต่ละแอตทริบิวต์ ฉันก็อยากจะเห็นเหมือนกันและอาจมีประโยชน์สำหรับมันด้วย อาจมีการโต้แย้งอย่างแน่นอนสำหรับการรวมของudatetimeแพคเกจความไม่แน่นอนที่เชื่อมโยงไว้ก่อนหน้านี้

ตัวอย่างของคุณจะเป็นดังนี้:

bob_bday = udatetime(2000, (6,6))  # 2000-06 +/- 6mo
>>> 2000-??-?? T??:??:??
bil_bday = udatetime((1970, 50), 3, 7)  # assume bill is ~40 +/- 40 
>>> [1970+/-40]-03-07 T??:??:??

"ค่าสัญญาณ" มีปัญหามากมาย แต่นอกจากนี้คุณสามารถแสดงสิ่งต่าง ๆ ด้วยความไม่แน่นอนที่ค่าสัญญาณไม่สามารถ:

# ali was born in spring
ali_bday = udatetime((), (4.5, 1.5))
>>> [1970+/-40]-[4.5+/-1.5]-?? T??:??:??

สิ่งที่ต้องพิจารณาอีกประการหนึ่งคือเพื่อให้มีความแม่นยำมากขึ้นความไม่แน่นอนที่นี่ควรเป็นของtimedeltaจริง ฉันปล่อยให้มันเป็นแบบฝึกหัดให้ผู้อ่านหาคอนสตรัคที่รัดกุมและสมบูรณ์แบบสำหรับการudatetimeใช้timedeltaความไม่แน่นอน

ดังนั้นในที่สุดฉันจะบอกว่าสิ่งที่คุณอธิบายคือ "ง่าย" ซึ่งจำลองมาจากความไม่แน่นอน แต่การใช้ a udatetimeนั้นค่อนข้างยาก ส่วนใหญ่จะใช้เส้นทาง "ง่าย" และทำลาย datetime ลงส่วนประกอบและติดตามความไม่แน่นอนเกี่ยวกับพวกเขาเป็นอิสระ แต่ถ้าคุณมีความรู้สึกมีความทะเยอทะยานuncertaintiesแพคเกจ (หรืออื่น) udatetimeอาจจะสนใจในคำขอดึงสำหรับ


0

ทำไมไม่สร้างคลาส "รอบระยะเวลา" ซึ่งใช้จากจากเป็นโครงสร้าง

"Bob เกิดเมื่อปี 2000" ->

period {
   from  {
      yy = 2000;
      mm = 01;
      dd = 01; 
   }
   to {
     yy = 2000;
     mm = 12;
     dd = 31;
   }
   fuzz = 365;
}

จากนั้นคุณสามารถใช้วิธีการค้นหาต่าง ๆ เช่นโดยการถ่ายคร่อมจากวันที่ แอตทริบิวต์ fuzz ให้การบ่งชี้ที่มีประโยชน์เกี่ยวกับความแม่นยำของวันที่ดังนั้นคุณสามารถระบุ fuzz == 1 สำหรับการจับคู่ที่ตรงกันหรือ fuzz == 31 สำหรับภายในหนึ่งเดือน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.