c++ - وانسابها - معرفة شجرة العائلة بالرقم القومى




دورات في برنامج شجرة العائلة (12)

تأكيدات لا تنجو من الواقع

التأكيدات عادة لا تنجو من الاتصال ببيانات العالم الحقيقي. إنه جزء من عملية هندسة البرمجيات التي تقرر ، والتي البيانات التي تريد التعامل بها والتي هي خارج نطاق.

الرسوم البيانية الأسرة دوري

فيما يتعلق "بالأشجار" العائلية (في الواقع أنها رسوم بيانية كاملة ، بما في ذلك الدورات) ، هناك حكاية لطيفة:

تزوجت من أرملة لديها ابنة نامية. والدي ، الذي كان يزورنا كثيرًا ، وقع في حب ابنتي وزوجها. ونتيجة لذلك ، أصبح والدي ابني ، وأصبحت ابنتي أمي. في وقت لاحق ، أعطيت زوجتي ابنا ، الذي كان شقيق أبي ، وعمّي. زوجة أبي (التي هي أيضا ابنتي وأمي) حصلت على ابن. ونتيجة لذلك ، حصلت على شقيق وحفيد في نفس الشخص. زوجتي الآن جدتي ، لأنها أم أمي. لذلك أنا زوج زوجتي ، وفي الوقت نفسه حفيد زوجتي. وبعبارة أخرى ، أنا جدتي الخاصة.

تصبح الأمور أكثر غرابة ، عندما تأخذ surrogates أو "الأبوة غير الواضحة" بعين الاعتبار.

كيف تتعامل مع ذلك

حدد الدورات على أنها خارج النطاق

يمكنك أن تقرر أن البرنامج الخاص بك لا ينبغي التعامل مع مثل هذه الحالات النادرة. في حالة حدوث مثل هذه الحالة ، يجب على المستخدم استخدام منتج مختلف. وهذا يجعل التعامل مع الحالات الأكثر شيوعًا أكثر قوة ، لأنه يمكنك الاحتفاظ بمزيد من التأكيدات ونموذج بيانات أبسط.

في هذه الحالة ، أضف بعض ميزات الاستيراد والتصدير الجيدة إلى برنامجك ، بحيث يمكن للمستخدم الانتقال بسهولة إلى منتج مختلف عند الضرورة.

اسمح بالعلاقات اليدوية

يمكنك السماح للمستخدم بإضافة علاقات يدوية. هذه العلاقات ليست "مواطنين من الدرجة الأولى" ، أي أن البرمجيات تأخذها كما هي ، ولا تحققها ولا تتعامل معها في نموذج البيانات الرئيسي.

يمكن للمستخدم بعد ذلك التعامل مع الحالات النادرة باليد. سيظل نموذج البيانات الخاص بك بسيطًا جدًا وستظل تأكيداتك على قيد الحياة.

كن حذرا مع العلاقات اليدوية. هناك إغراء لجعلها قابلة للتكوين تمامًا وبالتالي إنشاء نموذج بيانات قابل للتكوين بالكامل. هذا لن ينجح: لن يتم قياس البرنامج الخاص بك ، سوف تحصل على الأخطاء الغريبة وأخيرا ستصبح واجهة المستخدم غير قابلة للاستخدام. يسمى هذا النمط المضاد "الترميز الناعم" ، و "WTF اليومي" مليء بأمثلة لذلك.

اجعل نموذج البيانات الخاص بك أكثر مرونة ، وتخطي التأكيدات ، واختبار الثوابت

يتمثل الملاذ الأخير في جعل نموذج بياناتك أكثر مرونة. سيكون عليك تخطي جميع التأكيدات وتقريب نموذج بياناتك على رسم بياني كامل. كما يظهر المثال أعلاه ، من الممكن بسهولة أن تكون جدك الخاص ، حتى يمكنك الحصول على دورات.

في هذه الحالة ، يجب عليك اختبار البرنامج على نطاق واسع. كان عليك تخطي جميع التأكيدات تقريبًا ، لذلك هناك فرصة جيدة للحصول على أخطاء إضافية.

استخدم مولد بيانات اختبار للتحقق من حالات الاختبار غير المعتادة. توجد مكتبات تحقق سريعة لـ Haskell أو Erlang أو C لجافا / سكالا هناك ScalaCheck و ScalaCheck . تتمثل إحدى أفكار الاختبار في محاكاة مجموعة عشوائية من السكان ، والسماح لها بالتقاط عشوائي ، ثم السماح لبرنامجك أولاً باستيراد النتيجة ثم تصديرها. سيكون التوقع ، أن جميع الاتصالات في الإخراج هي أيضا في المدخلات والعكس صحيح.

تسمى الحالة التي يظل فيها العقار كما هو ثابت. في هذه الحالة ، الثابت هو مجموعة من "العلاقات الرومانسية" بين الأفراد في السكان المحاكية. حاول العثور على أكبر قدر ممكن من الثوابت واختبرها ببيانات تم إنشاؤها عشوائيًا. يمكن أن يكون السلوكيات غير فعالة ، على سبيل المثال:

  • يظل عمه عمًا ، حتى عندما تضيف المزيد من "العلاقات الرومانسية"
  • كل طفل لديه أحد الوالدين
  • السكان الذين لديهم جيلين لديه واحد على الأقل

أو يمكن أن تكون تقنية:

  • لن ينهار برنامجك على رسم بياني يصل إلى 10 مليار عضو (بغض النظر عن عدد الترابطات)
  • مقياس البرامج الخاص بك مع O (رقم العقد) و O (عدد الحواف ^ 2)
  • يمكن لبرنامجك حفظ وإعادة تحميل كل رسم بياني عائلي يصل إلى 10 مليار عضو

من خلال تشغيل اختبارات المحاكاة ، ستجد الكثير من حالات الزوايا الغريبة. إصلاحها سيستغرق الكثير من الوقت. أيضا سوف تفقد الكثير من التحسينات ، سيتم تشغيل البرنامج أبطأ بكثير. عليك أن تقرر ، إذا كان الأمر يستحق ذلك وإذا كان هذا في نطاق برنامجك.

أنا المطور لبعض برامج شجرة العائلة (مكتوبة في C ++ وكيو تي). لم يكن لدي أي مشاكل حتى أرسل لي أحد زبائني تقريرًا عن الأخطاء. المشكلة هي أن العميل لديه طفلين مع ابنتهما ، ونتيجة لذلك ، لا يمكنه استخدام برنامجي بسبب الأخطاء.

هذه الأخطاء هي نتيجة لتأكيداتي ومحاولاتي المختلفة حول الرسم البياني للعائلة التي يتم معالجتها (على سبيل المثال ، بعد السير في دورة ، ينص البرنامج على أن X لا يمكن أن يكون الأب أو الجد من Y).

كيف يمكنني حل هذه الأخطاء دون إزالة جميع تأكيدات البيانات؟


آخر جواب وهمية وهمية لسؤال سخيف:

الجواب الحقيقي هو ، استخدام بنية بيانات مناسبة. لا يمكن التعبير عن علم الأنساب البشرية بشكل كامل باستخدام شجرة نقية بدون دورات. يجب عليك استخدام نوع من الرسم البياني. أيضا ، تحدث إلى عالم أنثروبولوجيا قبل الذهاب إلى أبعد من ذلك ، لأن هناك الكثير من الأماكن الأخرى يمكن أن تحدث أخطاء مماثلة في محاولة لعلم الأنساب ، حتى في أبسط حالات "الزواج الأحادي البطريركي الأبوي".

حتى إذا أردنا تجاهل العلاقات المحرمة محليًا كما نوقش هنا ، فهناك الكثير من الطرق القانونية تمامًا وغير المتوقعة لإدخال الدورات في شجرة العائلة.

على سبيل المثال: http://en.wikipedia.org/wiki/Cousin_marriage

في الأساس ، فإن زواج ابن عم ليس شائعًا ومتوقعًا فقط ، بل هو السبب في انتقال البشر من آلاف المجموعات العائلية الصغيرة إلى 6 مليارات نسمة في جميع أنحاء العالم. لا يمكن أن تعمل بأي طريقة أخرى.

هناك حقا عدد قليل جدا من العالم عندما يتعلق الأمر بعلم الأنساب والأسرة والنسب. تقريبا أي فرضية صارمة حول المعايير التي تشير إلى من يمكن أن تكون عمة ، أو من يستطيع أن يتزوج من ، أو كيف يتم إضفاء الشرعية على الأطفال لغرض الإرث ، يمكن أن يزعجها بعض الاستثناء في مكان ما في العالم أو التاريخ.


أنا أكره التعليق على مثل هذا الموقف المشدود ، لكن أسهل طريقة لعدم إعادة تجزئ جميع الثوابت الخاصة بك هو إنشاء رأس فانتوم في الرسم البياني الخاص بك يعمل بمثابة وكيل إلى أبي المحارب.


أهم شيء هو avoid creating a problem ، لذلك أعتقد أنه يجب عليك استخدام علاقة مباشرة لتجنب وجود دورة.

كما قالmarkmywords ، # تشمل "fritzl.h".

أخيرا يجب أن أقول recheck your data structure . ربما يحدث خطأ ما هناك (ربما تكون قائمة مرتبطة ثنائية الاتجاه تحل مشكلتك).


استرخاء تأكيداتك.

ليس عن طريق تغيير القواعد ، والتي من المرجح أن تكون مفيدة جدًا ل 99.9٪ من عملائك في اكتشاف الأخطاء في إدخال بياناتهم.

بدلاً من ذلك ، يمكنك تغييره من خطأ "لا يمكن إضافة علاقة" إلى تحذير مع "إضافة على أي حال".


الآثار الجانبية المحتملة جانبا ، يبدو من المؤكد أنك تحتاج إلى علاج "عقدة" على شجرة عائلة كشخص سلف بدلا من افتراض أن العقدة يمكن أن يكون الشخص واحد فقط.

اجعل عقدة الشجرة تتضمن شخصًا بالإضافة إلى الخلفاء - وبعد ذلك يمكن أن يكون لديك عقدة أخرى أعمق أسفل الشجرة التي تتضمن نفس الشخص مع خلفاء مختلفين.


تكرار الأب (أو استخدام الارتباط / مرجع).

على سبيل المثال ، إذا كنت تستخدم قاعدة بيانات ذات تسلسل هرمي:

$ #each person node has two nodes representing its parents.
$ mkdir Family
$ mkdir Family/Son
$ mkdir Family/Son/Daughter
$ mkdir Family/Son/Father
$ mkdir Family/Son/Daughter/Father
$ ln -s Family/Son/Daughter/Father Family/Son/Father
$ mkdir Family/Son/Daughter/Wife
$ tree Family
Family
└── Son
    ├── Daughter
    │   ├── Father
    │   └── Wife
    └── Father -> Family/Son/Daughter/Father

4 directories, 1 file

تكون بيانات الأنساب دورية ولا تتناسب مع رسم بياني دوري ، لذلك إذا كان لديك تأكيدات ضد الدورات ، فيجب عليك إزالتها.

الطريقة لمعالجة هذا في طريقة عرض دون إنشاء طريقة عرض مخصصة هي معاملة الأصل دوري كـ الأصل "ghost". بعبارة أخرى ، عندما يكون الشخص أبًا وجدًا لنفس الشخص ، يتم عرض عقدة الجد بشكل طبيعي ، ولكن يتم عرض العقدة الأب كعقدة "شبح" لها تسمية بسيطة مثل ("انظر الجد") ) ويشير إلى الجد.

للقيام بعمليات حسابية قد تحتاج إلى تحسين المنطق الخاص بك للتعامل مع الرسوم البيانية الدورية بحيث لا تتم زيارة العقدة أكثر من مرة إذا كانت هناك دورة.


هذا هو أحد الأسباب التي تجعل اللغات مثل "Go" لا تملك تأكيدات. فهم معتادون على التعامل مع الحالات التي ربما لم تفكر فيها ، في أغلب الأحيان. يجب عليك فقط تأكيد المستحيل ، وليس فقط المستبعد . فعل هذا الأخير هو ما يعطي التأكيدات سمعة سيئة. في كل مرة تكتب فيها assert( ، ابتعد لمدة عشر دقائق وفكر بالفعل في ذلك.

في حالتك المزعجة بشكل خاص ، من الممكن أن يكون هذا التأكيد مزعجًا ومروعًا في ظل ظروف نادرة ولكن محتملة. ومن ثم ، تعامل معها في تطبيقك ، إذا أردت فقط أن تقول "لم يتم تصميم هذا البرنامج للتعامل مع السيناريو الذي قدمته".

التأكيد على أن جدك العظيم ، العظيم ، والدك مستحيل هو شيء معقول للقيام به.

إذا كنت أعمل في شركة اختبار تم تعيينها لاختبار البرنامج الخاص بك ، بالطبع كنت قد قدمت هذا السيناريو. لماذا ا؟ كل "ذكاء" حدث ذكي بعد ذاهب سوف يفعل نفس الشيء بالضبط ويستمتع في "تقرير الأخطاء" الناتج.


وقد أظهرت بعض الإجابات طرق للحفاظ على التأكيدات / الثوابت ، ولكن هذا يبدو وكأنه سوء استخدام التأكيدات / ثابتة. التأكيدات هي التأكد من أن ما يجب أن يكون صحيحًا صحيح ، ويجب على الثوابت التأكد من أن شيئًا لا يجب تغييره لا يتغير.

ما تؤكده هنا هو أن علاقات المحارم غير موجودة. من الواضح أنها موجودة بالفعل ، لذا فإن تأكيدك غير صحيح. يمكنك التغلب على هذا التأكيد ، ولكن الخطأ الحقيقي في التأكيد نفسه. يجب إزالة التأكيد.


يجب أن تستخدم شجرة عائلتك علاقات موجهة. بهذه الطريقة لن يكون لديك دورة.


يجب أن تكون قد أعددت عائلة Atreides (إما الحديث أو Atreides أو القديم Oedipus Rex ) كحالة اختبار. لا يمكنك العثور على أخطاء باستخدام البيانات المطهرة كحالة اختبار.







family-tree