कार मेंटेनेंस सर्विस शेड्यूल प्लानर
Wikiprompt से, मुफ्त प्रॉम्प्ट विश्वकोश
कार मेंटेनेंस सर्विस शेड्यूल प्लानर क्लॉड-शैली का एक संपूर्ण कौशल जिसमें संरचित प्रॉम्प्ट, संदर्भ दस्तावेज़, टेम्पलेट, उदाहरण और एक पायथन स्टैडलिब स्क्रिप्ट शामिल है जो सेवा अंतराल और इतिहास को ट्रैक करके, कार्य यात्राओं को बंडल करके और लागतों का पूर्वानुमान लगाकर कार रखरखाव की योजना बनाता है।
प्रॉम्प्ट सामग्रीसहेजें
🌐
---
name: car-maintenance-service-schedule-planner
description: अपनी सर्विस शेड्यूल और सर्विस हिस्ट्री से कार मेंटेनेंस की योजना बनाता है - ओडोमीटर रीडिंग से अनुमान लगाता है कि आप कितनी दूर ड्राइव करते हैं, पता लगाता है कि क्या ओवरड्यू है, जल्द ड्यू है या अगली बार दूरी या समय (जो भी पहले आए) के हिसाब से कब ड्यू है, कम वर्कशॉप विज़िट में आइटम्स को बंडल करता है और मासिक राशि के साथ लागत का पूर्वानुमान लगाता है। ओवरड्यू सुरक्षा और कानूनी आइटम, गायब रिकॉर्ड और ओडोमीटर टाइपो को फ्लैग करता है। एक ऑफलाइन stdlib Python प्लानर शामिल है।
---
# कार मेंटेनेंस सर्विस शेड्यूल प्लानर
आप कार मालिकों को बिना ज़्यादा पैसे खर्च किए मेंटेनेंस के साथ बने रहने में मदद करते हैं। लोग ट्रैक खो देते हैं क्योंकि हर आइटम अपनी घड़ी पर चलता है: तेल हर 15,000 किमी या 12 महीने में, ब्रेक फ्लुइड हर 2 साल में चाहे दूरी कुछ भी हो, रोडवर्थिनेस टेस्ट हर साल, टाइमिंग बेल्ट 120,000 किमी या 8 साल में। कुछ न कुछ हमेशा ड्यू होने वाला होता है, रसीदें बिखरी होती हैं और महंगे आइटम अचानक सामने आ जाते हैं। आप मालिक के शेड्यूल और उनकी सर्विस हिस्ट्री को स्पष्ट सूची में बदल देते हैं कि क्या ड्यू है, एक छोटी विज़िट योजना जो आइटम्स को कम से कम वर्कशॉप ट्रिप्स में बांटती है, और एक लागत पूर्वानुमान जिसके लिए वे बजट बना सकते हैं।
आप मालिक द्वारा दिए गए इंटरवल्स से योजना बनाते हैं (मालिक के मैनुअल, सर्विस बुकलेट या डीलर से)। आप खराबी का निदान नहीं करते या यह तय नहीं करते कि कोई पार्ट घिस गया है; उपयोगकर्ता को बताएं कि वे वर्कशॉप के निष्कर्षों और निर्माता के शेड्यूल का पालन करें, और चेतावनी लाइट, आवाज़, ब्रेक या स्टीयरिंग की समस्याओं की तुरंत जांच कराएं।
## इस स्किल में फ़ाइलें
- `scripts/car_service_plan.py` - एक कार JSON (वाहन, वर्तमान ओडोमीटर, किमी और/या महीने के इंटरवल वाले शेड्यूल आइटम, गंभीर-सेवा इंटरवल, पहले-परीक्षण में देरी, लागत, सुरक्षा/कानूनी फ्लैग, नाम उपनाम) और एक सर्विस लॉग CSV (तारीख, ओडोमीटर, ";" से अलग किए गए आइटम, लागत, दुकान) पढ़ता है; रीडिंग से वार्षिक दूरी का अनुमान लगाता है, प्रत्येक आइटम के अंतिम बार किए जाने का समय पाता है, समय और अनुमानित दूरी दोनों से अगली ड्यू तिथि की गणना करता है, स्थिति OVERDUE / DUE SOON / OK, क्षितिज पर बंडल की गई वर्कशॉप विज़िट और प्रति तिमाही लागत; रिपोर्ट निष्कर्ष CS01-CS09 (Python 3.8+ मानक पुस्तकालय केवल)
- `references/intervals-and-severe-service.md` - निर्माता के शेड्यूल को कैसे पढ़ें, समय बनाम दूरी, गंभीर-सेवा की स्थितियाँ, विशिष्ट आइटम नोट और क्या कभी टालना नहीं चाहिए
- `references/checks-and-codes.md` - हर निष्कर्ष कोड, उसकी गंभीरता और क्या करना है, साथ ही इनपुट फ़ील्ड
- `templates/service-plan.md` - एक-पेज की योजना और वर्कशॉप में ले जाने के लिए चेकलिस्ट
- `examples/car.json` - 83,400 किमी पर 2019 पेट्रोल एस्टेट कार जिसमें 11 शेड्यूल आइटम हैं (उदाहरणात्मक इंटरवल और कीमतें - अपने मैनुअल से बदलें)
- `examples/service-log.csv` - संयुक्त विज़िट के साथ सात साल की सर्विस हिस्ट्री, एक उपनाम ("Oil change"), शेड्यूल में नहीं एक आइटम और एक ओडोमीटर टाइपो
- `examples/service-plan.md` - उदाहरण पर वास्तविक प्लानर आउटपुट
## कार्यप्रवाह
### 1. शेड्यूल और हिस्ट्री इकट्ठा करें
मेक, मॉडल, इंजन और पहली पंजीकरण तिथि, आज की ओडोमीटर रीडिंग, और मालिक के मैनुअल या सर्विस बुकलेट से मेंटेनेंस शेड्यूल (आइटम, दूरी इंटरवल, समय इंटरवल, गंभीर-सेवा इंटरवल यदि वे ज़्यादातर छोटी यात्राएं करते हैं, टो करते हैं, या धूल या अत्यधिक गर्मी या ठंड में ड्राइव करते हैं) के लिए पूछें। सर्विस हिस्ट्री के लिए पूछें: इनवॉइस, सर्विस बुक में स्टैम्प या डीलर का प्रिंटआउट, तारीख, ओडोमीटर और क्या किया गया था। उनकी वर्कशॉप के पिछले इनवॉइस से मोटी कीमतें जोड़ें। उन्हें `examples/car.json` जैसे कार JSON और `examples/service-log.csv` जैसे लॉग में लिखें।
### 2. प्लानर चलाएं
```
python3 scripts/car_service_plan.py examples/car.json examples/service-log.csv
python3 scripts/car_service_plan.py car.json log.csv --odometer 84100 --today 2026-11-20
python3 scripts/car_service_plan.py car.json log.csv --severe --horizon 36
python3 scripts/car_service_plan.py car.json log.csv --json
python3 scripts/car_service_plan.py --self-test
```
एग्ज़िट 0 = कोई ओवरड्यू सुरक्षा या कानूनी आइटम नहीं, 1 = एक सुरक्षा/कानूनी आइटम ओवरड्यू है (या लॉग में उच्च निष्कर्ष है), 2 = खराब इनपुट। शेल के बिना, प्रत्येक आइटम के लिए अंतिम तारीख और ओडोमीटर लें, दोनों इंटरवल जोड़ें, वार्षिक दूरी के साथ दूरी को तारीख में बदलें, और पहले वाला लें।
### 3. परिणाम पढ़ें
- पहले उच्च: CS01 उच्च (ओवरड्यू ब्रेक, ब्रेक फ्लुइड, टायर, कानूनी परीक्षण) - सावधानी से ड्राइव करें और अभी बुक करें; CS04 उच्च (भविष्य में तारीखें, आज के ओडोमीटर से ऊपर रीडिंग) - लॉग ठीक करें।
- मध्यम: अन्य ओवरड्यू आइटम, जल्द ड्यू आइटम, बिना रिकॉर्ड वाले आइटम (CS03 - नई से गिना जाता है, इसलिए भुगतान करने से पहले सर्विस बुक जांचें) और ओडोमीटर रीडिंग जो पीछे जाती हैं।
- निम्न/जानकारी: योजना के भीतर बड़े-टिकट आइटम (CS08), अपने इंटरवल से काफी पहले किए गए आइटम (CS05), शेड्यूल में नहीं लॉग प्रविष्टियाँ, उपयोग में गंभीर इंटरवल।
- यदि वार्षिक दूरी गलत लगती है, तो रीडिंग जांचें; आज की रीडिंग के साथ `--odometer` का उपयोग करें।
### 4. विज़िट की योजना बनाएं
विज़िट तालिका का उपयोग करें: विज़िट 1 को ओवरड्यू सब कुछ और बंडल विंडो के भीतर ड्यू सब कुछ के लिए बुक करें, और वर्कशॉप से एक बार में पूरी सूची के लिए कोटेशन मांगें। एक सस्ते आइटम को कुछ हफ्ते आगे बढ़ाएं यदि यह एक यात्रा बचाता है, लेकिन सुरक्षा या कानूनी आइटम को कभी बाद में न धकेलें। विज़िट, वर्कशॉप के लिए चेकलिस्ट और मासिक राशि के साथ `templates/service-plan.md` भरें।
### 5. डिलीवर करें
ओवरड्यू और जल्द ड्यू सूची सादे शब्दों में लौटाएं, तारीखों और अनुमानित लागतों के साथ विज़िट योजना, 12- और 24-महीने की लागत पूर्वानुमान और अलग रखने के लिए मासिक राशि, साथ ही जांचने के लिए प्रश्न (बिना हिस्ट्री वाले आइटम के रिकॉर्ड, उनके इंजन के लिए सटीक इंटरवल, वारंटी शर्तें जिनके लिए डीलर सर्विसिंग की आवश्यकता होती है)।
## उदाहरण परिणाम
83,400 किमी पर 2019 ऑक्टेविया के लिए (लगभग 11,000 किमी प्रति वर्ष) चार आइटम ओवरड्यू हैं: ब्रेक फ्लुइड (126 दिन, सुरक्षा), निरीक्षण सेवा और एयर फिल्टर (समय से) और टायर रोटेशन (3,300 किमी), और रोडवर्थिनेस टेस्ट 20 नवंबर 2026 को ड्यू है - एक विज़िट अब सभी पांचों को लगभग 410 EUR में कवर करती है। टाइमिंग बेल्ट का कोई रिकॉर्ड नहीं है, इसलिए इसे नई से गिना जाता है और नवंबर 2027 में उम्र के अनुसार ड्यू है (लगभग 680 EUR), और नए टायर जून 2027 के लिए अनुमानित हैं (लगभग 560 EUR)। अगले 24 महीनों में मेंटेनेंस लगभग 2,445 EUR आता है, इसलिए लगभग 102 EUR प्रति माह अलग रखें। सितंबर 2023 में 4,790 किमी की रीडिंग एक टाइपो है और इसे अनदेखा किया जाता है।
## नियम
- सटीक इंजन के लिए निर्माता के इंटरवल का उपयोग करें; उदाहरण मान केवल उदाहरणात्मक हैं।
- जो भी पहले आए: एक आइटम उसकी दूरी और समय सीमा में से जो पहले हो उस पर ड्यू है, यहां तक कि उस कार के लिए भी जो शायद ही चलाई जाती है।
- पैसे या यात्रा बचाने के लिए ब्रेक, टायर, स्टीयरिंग, चेतावनी लाइट या कानूनी परीक्षण को स्थगित करने का सुझाव कभी न दें।
- बिना रिकॉर्ड वाला आइटम अज्ञात है, किया हुआ नहीं: ऐसा कहें और सर्विस बुक जांचने या वर्कशॉप से पूछने का सुझाव दें।
- लागत अनुमान हैं; उपयोगकर्ता को कोटेशन लेने के लिए कहें, और स्वतंत्र गैरेज का सुझाव देने से पहले वारंटी शर्तों का उल्लेख करें।
## इंटरवल और गंभीर सेवा
## इंटरवल कहां से आते हैं
- आपके सटीक मॉडल, इंजन और मॉडल वर्ष के लिए मालिक का मैनुअल या सर्विस बुकलेट। एक ही मॉडल में पेट्रोल, डीजल और हाइब्रिड इंजन के लिए, और "फिक्स्ड" बनाम "फ्लेक्सिबल/लॉन्ग-लाइफ" सर्विस रेजिम के लिए अलग-अलग शेड्यूल हो सकते हैं।
- कई कारें डैशबोर्ड पर अगली तेल सेवा दिखाती हैं (सेवा संकेतक)। यदि यह बुकलेट से असहमत है, तो डीलर से पूछें कि कार किस रेजिम पर सेट है।
- वारंटी शर्तों को ध्यान में रखें: कुछ निर्माताओं को उनके शेड्यूल के अनुसार असली-विनिर्देश भागों के साथ सर्विसिंग की आवश्यकता होती है; स्वतंत्र गैरेज आमतौर पर ठीक हैं यदि वे शेड्यूल का पालन करते हैं और इनवॉइस रखते हैं।
## जो भी पहले आए
दूरी और समय दोनों इंटरवल वाला हर आइटम दोनों में से पहले वाले पर ड्यू है। कम-माइलेज वाली कारें समय सीमा से टकराती हैं (तेल पुराना होता है, ब्रेक फ्लुइड पानी सोखता है, रबर बेल्ट और टायर पुराने होते हैं); उच्च-माइलेज वाली कारें दूरी सीमा से टकराती हैं। प्लानर आपकी वार्षिक दूरी के साथ दूरी सीमा को तारीख में बदल देता है।
## गंभीर सेवा
अधिकांश मैनुअल छोटे इंटरवल सूचीबद्ध करते हैं जब कार ज़्यादातर इसके लिए उपयोग की जाती है:
- छोटी यात्राएं (लगभग 10 किमी से कम, इंजन शायद ही पूरी तरह गर्म होता है), विशेष रूप से ठंडे मौसम में;
- स्टॉप-एंड-गो शहर यातायात, टैक्सी या डिलीवरी उपयोग, लंबी आइडलिंग;
- ट्रेलर या कारवां टोइंग, छत भार, पहाड़ी ड्राइविंग;
- धूल भरी या रेतीली सड़कें, बहुत गर्म या बहुत ठंडी जलवायु।
यदि इनमें से कोई भी आपकी अधिकांश ड्राइविंग का वर्णन करता है, तो `--severe` (या `"severe": true`) का उपयोग करें ताकि `severe_km` / `severe_months` वाले आइटम छोटे इंटरवल का उपयोग करें।
## आइटम नोट (विशिष्ट, अपना मैनुअल जांचें)
| आइटम | विशिष्ट आधार | नोट |
|---|---|---|
| इंजन तेल और फिल्टर | दूरी और समय | सबसे महत्वपूर्ण नियमित आइटम; मैनुअल में तेल विनिर्देश का उपयोग करें |
| निरीक्षण सेवा | दूरी और समय | बड़ी सेवा; आमतौर पर कई जांच शामिल हैं |
| ब्रेक फ्लुइड | केवल समय (अक्सर 2 साल) | पानी सोखता है; कभी स्थगित न करें |
| ब्रेक निरीक्षण / पैड / डिस्क | दूरी और समय | घिसाव पर बदलें, निश्चित इंटरवल पर नहीं |
| कूलेंट | समय या "लाइफटाइम" | हर सर्दियों में स्तर और फ्रीज सुरक्षा जांचें |
| एयर फिल्टर, केबिन फिल्टर | दूरी और समय | धूल भरे या प्रदूषित क्षेत्रों में छोटा |
| स्पार्क प्लग (पेट्रोल) | दूरी और समय | आधुनिक इंजनों पर लंबे इंटरवल |
| टाइमिंग बेल्ट (यदि लगा है) | दूरी और समय | विफलता इंजन को नष्ट कर सकती है; अक्सर वाटर पंप के साथ बदला जाता है; चेन में आमतौर पर कोई इंटरवल नहीं होता |
| टायर | घिसाव और उम्र | मासिक ट्रेड गहराई जांचें; कई निर्माता ट्रेड की परवाह किए बिना 6-10 साल में बदलने का सुझाव देते हैं |
| टायर रोटेशन | दूरी | यदि आपका मैनुअल इसकी सिफारिश करता है (अलग-अलग आकार के आगे/पीछे टायरों के लिए नहीं) |
| रोडवर्थिनेस टेस्ट | समय (कानूनी) | पहला परीक्षण कुछ वर्षों के बाद (जैसे 3 या 4), फिर देश के आधार पर हर 1-2 साल |
| 12 वी बैटरी | स्थिति | 4-5 साल पुरानी होने पर सर्दियों से पहले परीक्षण करें |
## कानूनी परीक्षण
नियम देश के अनुसार भिन्न होते हैं (यूके में MOT, जर्मनी में TUV/HU, फ्रांस में CT, तुर्की में TUVTURK, अमेरिका में राज्य निरीक्षण)। अपने देश की पहली-परीक्षण देरी को `first_months` के रूप में और दोहराव इंटरवल को `months` के रूप में दर्ज करें, और आइटम को `"legal": true` चिह्नित करें। कई योजनाएं आपको तारीख खोए बिना थोड़ा जल्दी परीक्षण करने देती हैं; इसे पहले की विज़िट में बंडल करने से पहले अपनी जांचें।
## क्या कभी स्थगित न करें
ब्रेक और ब्रेक फ्लुइड, टायर (ट्रेड, क्षति, उम्र), स्टीयरिंग और सस्पेंशन दोष, चेतावनी लाइट (तेल दबाव, ब्रेक, इंजन तापमान), और कानूनी परीक्षण। प्लानर इन्हें `safety` / `legal` के साथ चिह्नित करता है और ओवरड्यू होने पर उच्च मानता है।
## इनपुट प्राप्त करना
- हर विज़िट का ओडोमीटर और तारीख: इनवॉइस, सर्विस बुक स्टैम्प, डीलर का डिजिटल सर्विस रिकॉर्ड, कानूनी परीक्षण प्रमाण पत्र (वे ओडोमीटर रिकॉर्ड करते हैं)।
- कीमतें: आपके पिछले इनवॉइस या एक कोटेशन; उन भागों के लिए 10-20% जोड़ें जो अक्सर एक ही समय में बदले जाते हैं (वाइपर, बल्ब, ब्रेक पैड)।
## जांच और निष्कर्ष कोड
| कोड | गंभीरता | जांच | क्या करें |
|---|---|---|---|
| CS01 | उच्च: सुरक्षा या कानूनी आइटम ओवरड्यू; मध्यम: अन्य आइटम ओवरड्यू | ड्यू तिथि या ड्यू दूरी बीत गई | इसे बुक करें; सुरक्षा आइटम के लिए पूरा होने तक सावधानी से ड्राइव करें |
| CS02 | मध्यम | `due_soon.days` या `due_soon.km` के भीतर ड्यू | इसे अगली विज़िट के साथ बुक करें |
| CS03 | मध्यम | लॉग में आइटम का कोई रिकॉर्ड नहीं: पहले पंजीकरण से गिना गया | इसके लिए भुगतान करने से पहले सर्विस बुक / रसीदें / डीलर रिकॉर्ड जांचें |
| CS04 | उच्च: भविष्य में तारीख, वर्तमान ओडोमीटर से ऊपर रीडिंग; मध्यम: पहले की तुलना में कम रीडिंग, अपठनीय ओडोमीटर | लॉग स्थिरता | टाइपो ठीक करें; दूरी और ड्यू गणना के लिए रीडिंग को अनदेखा किया जाता है |
| CS05 | जानकारी | दोनों इंटरवल के 60% से कम पर अंतिम बार किया गया | ठीक है यदि इरादा था (गंभीर उपयोग, वारंटी); अन्यथा पैसा जल्दी खर्च हुआ |
| CS06 | जानकारी | गंभीर-सेवा इंटरवल उपयोग में | जांचें कि स्थितियां अभी भी लागू हैं |
| CS07 | जानकारी | लॉग आइटम आपके शेड्यूल में नहीं (मरम्मत, अतिरिक्त) | इतिहास के लिए रखा गया; यदि यह किसी अन्य नाम से शेड्यूल आइटम है तो उपनाम जोड़ें |
| CS08 | निम्न | 400 या अधिक की लागत वाला आइटम योजना क्षितिज के भीतर आता है | इसके लिए बजट बनाएं; जल्दी कोटेशन लें |
| CS09 | मध्यम | पर्याप्त ओडोमीटर रीडिंग नहीं (कम से कम 60 दिन पहले की रीडिंग): डिफ़ॉल्ट वार्षिक दूरी उपयोग की गई | रीडिंग जोड़ें (परीक्षण प्रमाण पत्र, ईंधन ऐप, डैशबोर्ड की तस्वीरें) |
## निर्णय
- **सुरक्षा/कानूनी सहित ओवरड्यू**: अभी बुक करें।
- **ओवरड्यू**: जल्द बुक करें।
- **जल्द ड्यू** / **अप टू डेट**।
## संख्याएं कैसे निकाली जाती हैं
- वार्षिक दूरी: आज से कम से कम एक साल पहले की नवीनतम लॉग रीडिंग से आज की रीडिंग तक (यदि कोई इतनी पुरानी नहीं है तो सबसे पहली रीडिंग)।
- अगली ड्यू: अंतिम किए जाने की तारीख + महीने, और अंतिम किए जाने का ओडोमीटर + किमी, आपकी दैनिक दूरी के साथ तारीख में बदला गया; पहले वाला जीतता है। बिना रिकॉर्ड वाला आइटम पहले पंजीकरण से 0 किमी पर गिना जाता है (`first_months` पहली बार `months` की जगह लेता है, जैसे 36 महीने के बाद पहला कानूनी परीक्षण)।
- क्षितिज: प्रत्येक आइटम उस तारीख से दोहराता है जिसे किया गया माना जाता है (इसकी ड्यू तिथि, या ओवरड्यू होने पर आज)।
- विज़िट: किसी विज़िट के पहले आइटम के `bundle.days` और `bundle.km` के भीतर ड्यू आइटम उस विज़िट में शामिल होते हैं (आगे खींचे गए, कभी बाद में नहीं धकेले गए)।
- लागत: प्रत्येक घटना की `cost` उसकी तिमाही में जोड़ी गई; मासिक राशि = क्षितिज कुल / क्षितिज महीने।
## कार JSON कुंजियाँ
`vehicle{name, first_registered, unit}, odometer{reading, date}, driving{default_per_year, severe, severe_reasons}, currency, horizon_months, due_soon{km, days}, bundle{km, days}, schedule[{item, km, months, severe_km, severe_months, first_months, cost, safety, legal, aliases[]}]`।
## सर्विस लॉग CSV
`date, odometer, item, cost, shop, notes` - एक विज़िट में कई आइटम `;` से अलग किए गए। नाम शेड्यूल आइटम और उपनामों से केस-असंवेदनशील रूप से मेल खाते हैं। लागत कॉलम आपके रिकॉर्ड के लिए है; पूर्वानुमान शेड्यूल कीमतों का उपयोग करता है।
## टेम्पलेट
# कार सर्विस प्लान: <कार, पंजीकरण>
**तारीख:** <YYYY-MM-DD> **ओडोमीटर:** <83,400 किमी> **वार्षिक दूरी:** <लगभग 11,000 किमी> **शेड्यूल:** <मालिक का मैनुअल, सामान्य / गंभीर सेवा>
## अभी करें
| आइटम | क्यों | अनुमानित लागत |
|---|---|---|
| <ब्रेक फ्लुइड> | <4 महीने ओवरड्यू (2-वर्ष इंटरवल) - सुरक्षा> | <85> |
| <रोडवर्थिनेस टेस्ट> | <2026-11-20 को ड्यू - कानूनी> | <60> |
## अगली विज़िट
| कब (बुक करें) | लगभग | आइटम | अनुमानित लागत |
|---|---|---|---|
| <2027-02-14> | <86,500 किमी> | <तेल और फिल्टर, ब्रेक निरीक्षण> | <180> |
## बजट
- अगले 12 महीने: <1,220> <EUR>
- अगले 24 महीने: <2,445> <EUR> -> <102> प्रति माह अलग रखें
- आगे बड़े आइटम: <टाइमिंग बेल्ट किट और वाटर पंप, नवंबर 2027, लगभग 680>
## जांचने के लिए
- [ ] <टाइमिंग बेल्ट का कोई रिकॉर्ड नहीं - सर्विस बुक / डीलर से पूछें>
- [ ] <इस इंजन के लिए सटीक ब्रेक फ्लुइड इंटरवल>
- [ ] <वारंटी: क्या इसके लिए डीलर सर्विसिंग की आवश्यकता है?>
## वर्कशॉप के लिए चेकलिस्ट
- कार: <मेक, मॉडल, इंजन, VIN यदि पूछा जाए>, ओडोमीटर <...>
- कृपया करें: <"अभी करें" से सूची>
- कृपया बदलने से पहले जांचें और कोटेशन दें: <ब्रेक पैड/डिस्क, टायर, वाइपर, बैटरी>
- कृपया सर्विस बुक स्टैम्प करें / डिजिटल रिकॉर्ड भेजें और इनवॉइस पर ओडोमीटर नोट करें।
*इंटरवल <स्रोत> से; लागत अनुमान हैं। कुछ भी असामान्य (चेतावनी लाइट, आवाज़, खिंचाव, कंपन) तुरंत जांचवाएं।*
## उदाहरण: car.json
{
"vehicle": {"name": "2019 स्कोडा ऑक्टेविया एस्टेट 1.5 TSI (पेट्रोल)", "first_registered": "2019-11-14", "unit": "km"},
"odometer": {"reading": 83400, "date": "2026-11-04"},
"driving": {"default_per_year": 12000, "severe": false, "severe_reasons": ["सर्दियों में ज़्यादातर छोटी यात्राएं", "कभी-कभी कारवां टोइंग"]},
"currency": "EUR",
"horizon_months": 24,
"due_soon": {"km": 1500, "days": 45},
"bundle": {"km": 2500, "days": 60},
"schedule": [
{"item": "इंजन तेल और फिल्टर", "km": 15000, "months": 12, "severe_km": 7500, "severe_months": 6, "cost": 140, "aliases": ["oil service", "oil change"]},
{"item": "निरीक्षण सेवा", "km": 30000, "months": 24, "severe_km": 20000, "cost": 190, "aliases": ["inspection"]},
{"item": "ब्रेक निरीक्षण", "km": 20000, "months": 12, "cost": 40, "safety": true},
{"item": "ब्रेक फ्लुइड", "months": 24, "cost": 85, "safety": true},
{"item": "एयर फिल्टर", "km": 60000, "months": 48, "severe_km": 30000, "cost": 45},
{"item": "केबिन फिल्टर", "km": 30000, "months": 24, "cost": 40, "aliases": ["pollen filter"]},
{"item": "स्पार्क प्लग", "km": 60000, "months": 72, "cost": 160},
{"item": "टायर रोटेशन", "km": 10000, "cost": 30},
{"item": "टायर (4 का सेट)", "km": 45000, "months": 72, "cost": 560, "safety": true},
{"item": "टाइमिंग बेल्ट किट और वाटर पंप", "km": 120000, "months": 96, "cost": 680},
{"item": "रोडवर्थिनेस टेस्ट", "months": 12, "first_months": 36, "cost": 60, "legal": true, "aliases": ["mot", "periodic inspection"]}
]
}
## उदाहरण: service-log.csv
date,odometer,item,cost,shop,notes
2020-11-20,11500,तेल सेवा; ब्रेक निरीक्षण,165,मुख्य डीलर,पहली सेवा
2021-11-05,22800,तेल सेवा; ब्रेक निरीक्षण; केबिन फिल्टर,210,मुख्य डीलर,
2022-05-28,33900,तेल सेवा; निरीक्षण सेवा; ब्रेक फ्लुइड; एयर फिल्टर,395,मुख्य डीलर,
2022-11-08,38000,रोडवर्थिनेस टेस्ट,55,परीक्षण केंद्र,पास
2023-06-15,45150,तेल सेवा; ब्रेक निरीक्षण; टायर रोटेशन; टायर (4 का सेट),735,क्विकफिट,नए टायर 205/55 R16
2023-09-02,4790,विंडस्क्रीन चिप मरम्मत,60,ग्लासफिक्स,
2023-11-13,49000,रोडवर्थिनेस टेस्ट,55,परीक्षण केंद्र,पास
2024-07-01,56900,तेल सेवा; निरीक्षण सेवा; ब्रेक फ्लुइड; स्पार्क प्लग; ब्रेक निरीक्षण,520,मुख्य डीलर,
2024-11-12,59800,रोडवर्थिनेस टेस्ट,58,परीक्षण केंद्र,सलाह: पीछे वाइपर
2025-08-20,70100,तेल सेवा; ब्रेक निरीक्षण; केबिन फिल्टर; टायर रोटेशन,240,कोने गैरेज,
2025-11-20,73000,रोडवर्थिनेस टेस्ट,60,परीक्षण केंद्र,पास
2026-02-14,75300,तेल बदलें; ब्रेक निरीक्षण,150,कोने गैरेज,डैश लाइट आई
## उदाहरण: service-plan.md
# सर्विस प्लान: 2019 स्कोडा ऑक्टेविया एस्टेट 1.5 TSI (पेट्रोल)
आज 2026-11-04, ओडोमीटर 83,400 किमी। आप लगभग 11,008 किमी/वर्ष ड्राइव करते हैं (2025-08-20 70,100 -> 2026-11-04 83,400)। सामान्य-सेवा इंटरवल, योजना क्षितिज 24 महीने। स्रोत: examples/service-log.csv।
**निर्णय: 4 आइटम ओवरड्यू, सुरक्षा/कानूनी आइटम सहित - अभी विज़िट बुक करें**
अगले 12 महीने: लगभग 1,220.00 EUR; अगले 24 महीने: 2,445.00 EUR (लगभग 101.88 EUR प्रति माह अलग रखें)। निष्कर्ष: 1 उच्च, 6 मध्यम, 2 निम्न, 3 जानकारी।
## आइटम
| आइटम | इंटरवल | अंतिम बार किया गया | ड्यू तिथि तक | ड्यू किमी पर | अगला (अनुमानित) | ट्रिगर | स्थिति | अनुमानित लागत |
|---|---|---|---|---|---|---|---|---|
| निरीक्षण सेवा | 30,000 किमी / 24 महीने | 2024-07-01 56,900 पर | 2026-07-01 | 86,900 | 2026-11-04 | समय | **ओवरड्यू** | 190.00 |
| ब्रेक फ्लुइड [सुरक्षा] | 24 महीने | 2024-07-01 56,900 पर | 2026-07-01 | - | 2026-11-04 | समय | **ओवरड्यू** | 85.00 |
| एयर फिल्टर | 60,000 किमी / 48 महीने | 2022-05-28 33,900 पर | 2026-05-28 | 93,900 | 2026-11-04 | समय | **ओवरड्यू** | 45.00 |
| टायर रोटेशन | 10,000 किमी | 2025-08-20 70,100 पर | - | 80,100 | 2026-11-04 | दूरी | **ओवरड्यू** | 30.00 |
| रोडवर्थिनेस टेस्ट [कानूनी] | 12 महीने | 2025-11-20 73,000 पर | 2026-11-20 | - | 2026-11-20 | समय | **जल्द ड्यू** | 60.00 |
| इंजन तेल और फिल्टर | 15,000 किमी / 12 महीने | 2026-02-14 75,300 पर | 2027-02-14 | 90,300 | 2027-02-14 | समय | ठीक | 140.00 |
| ब्रेक निरीक्षण [सुरक्षा] | 20,000 किमी / 12 महीने | 2026-02-14 75,300 पर | 2027-02-14 | 95,300 | 2027-02-14 | समय | ठीक | 40.00 |
| टायर (4 का सेट) [सुरक्षा] | 45,000 किमी / 72 महीने | 2023-06-15 45,150 पर | 2029-06-15 | 90,150 | 2027-06-15 | दूरी | ठीक | 560.00 |
| केबिन फिल्टर | 30,000 किमी / 24 महीने | 2025-08-20 70,100 पर | 2027-08-20 | 100,100 | 2027-08-20 | समय | ठीक | 40.00 |
| टाइमिंग बेल्ट किट और वाटर पंप | 120,000 किमी / 96 महीने | कोई रिकॉर्ड नहीं (नई से गिना गया, 2019-11-14) | 2027-11-14 | 120,000 | 2027-11-14 | समय | ठीक | 680.00 |
| स्पार्क प्लग | 60,000 किमी / 72 महीने | 2024-07-01 56,900 पर | 2030-07-01 | 116,900 | 2029-11-18 | दूरी | ठीक | 160.00 |
## वर्कशॉप विज़िट (60 दिनों / 2,500 किमी के भीतर आइटम बंडल किए गए हैं)
| # | बुक करें | लगभग | आइटम | अनुमानित लागत |
|---|---|---|---|---|
| 1 | 2026-11-04 (अभी) | 83,400 किमी | एयर फिल्टर (ओवरड्यू), ब्रेक फ्लुइड (ओवरड्यू), निरीक्षण सेवा (ओवरड्यू), टायर रोटेशन (ओवरड्यू), रोडवर्थिनेस टेस्ट | 410.00 |
| 2 | 2027-02-14 | 86,476 किमी | ब्रेक निरीक्षण, इंजन तेल और फिल्टर | 180.00 |
| 3 | 2027-06-15 | 90,125 किमी | टायर (4 का सेट) | 560.00 |
| 4 | 2027-08-20 | 92,116 किमी | केबिन फिल्टर, टायर रोटेशन | 70.00 |
| 5 | 2027-11-14 | 94,710 किमी | टाइमिंग बेल्ट किट और वाटर पंप, रोडवर्थिनेस टेस्ट | 740.00 |
| 6 | 2028-02-14 | 97,484 किमी | ब्रेक निरीक्षण, इंजन तेल और फिल्टर | 180.00 |
| 7 | 2028-08-27 | 103,365 किमी | टायर रोटेशन | 30.00 |
| 8 | 2028-11-04 | 105,446 किमी | ब्रेक फ्लुइड, निरीक्षण सेवा | 275.00 |
## तिमाही के अनुसार लागत पूर्वानुमान
| तिमाही | अनुमानित लागत |
|---|---|
| 2026-Q4 | 410.00 |
| 2027-Q1 | 180.00 |
| 2027-Q2 | 560.00 |
| 2027-Q3 | 40.00 |
| 2027-Q4 | 770.00 |
| 2028-Q1 | 180.00 |
| 2028-Q3 | 30.00 |
| 2028-Q4 | 275.00 |
| **कुल 24 महीने** | **2,445.00** |
## निष्कर्ष
- **उच्च CS01** ब्रेक फ्लुइड 126 दिनों से ओवरड्यू है (सुरक्षा आइटम) - इसे अभी बुक करें
- **मध्यम CS01** एयर फिल्टर 160 दिनों से ओवरड्यू है - इसे अभी बुक करें
- **मध्यम CS01** निरीक्षण सेवा 126 दिनों से ओवरड्यू है - इसे अभी बुक करें
- **मध्यम CS01** टायर रोटेशन 3,300 किमी से ओवरड्यू है - इसे अभी बुक करें
- **मध्यम CS02** रोडवर्थिनेस टेस्ट जल्द ड्यू है: 2026-11-20
- **मध्यम CS03** टाइमिंग बेल्ट किट और वाटर पंप: आपके लॉग में कोई रिकॉर्ड नहीं - नई से गिना गया; सर्विस बुक या रसीदें जांचें
- **मध्यम CS04** पंक्ति 7: 2023-09-02 पर ओडोमीटर 4,790, 2023-06-15 पर 45,150 से कम है - टाइपो या गलत कार? रीडिंग अनदेखा की गई
- **निम्न CS08** टाइमिंग बेल्ट किट और वाटर पंप (लगभग 680.00) 2027-11-14 को योजना में आता है - अभी इसके लिए बजट बनाएं
- **निम्न CS08** टायर (4 का सेट) (लगभग 560.00) 2027-06-15 को योजना में आता है - अभी इसके लिए बजट बनाएं
- **जानकारी CS05** ब्रेक निरीक्षण अंतिम बार 5,200 किमी / 6 महीने के बाद किया गया था (इंटरवल के 60% से कम) - गंभीर उपयोग के लिए ठीक है, अन्यथा पैसा जल्दी खर्च हुआ
- **जानकारी CS05** इंजन तेल और फिल्टर अंतिम बार 5,200 किमी / 6 महीने के बाद किया गया था (इंटरवल के 60% से कम) - गंभीर उपयोग के लिए ठीक है, अन्यथा पैसा जल्दी खर्च हुआ
- **जानकारी CS07** पंक्ति 7: 'विंडस्क्रीन चिप मरम्मत' आपके शेड्यूल में नहीं है - केवल इतिहास में रखा गया
इंटरवल और कीमतें आपकी कार फ़ाइल से आती हैं: उन्हें अपने सटीक इंजन के लिए मालिक के मैनुअल या सर्विस बुकलेट के खिलाफ जांचें, और यदि आपकी वर्कशॉप पहले घिसाव पाती है तो उसका पालन करें। लागत अनुमान हैं; टायर और ब्रेक भी घिसाव पर निर्भर करते हैं, न कि केवल दूरी पर।
## पायथन स्क्रिप्ट (car_service_plan.py)
```python
#!/usr/bin/env python3
"""कार मेंटेनेंस सर्विस शेड्यूल प्लानर (केवल stdlib, Python 3.8+)।
आपकी कार के मेंटेनेंस शेड्यूल (दूरी और/या समय इंटरवल वाले आइटम, मालिक के
मैनुअल या सर्विस बुकलेट से) और आपकी सर्विस हिस्ट्री (CSV) पढ़ता है, लॉग में
ओडोमीटर रीडिंग से अनुमान लगाता है कि आप कितनी दूर ड्राइव करते हैं, और हर आइटम
के लिए पता लगाता है कि वह अंतिम बार कब किया गया था, अगली बार कब ड्यू है (दूरी
या समय, जो भी पहले आए), क्या ओवरड्यू या जल्द ड्यू है, कौन से आइटम एक वर्कशॉप
विज़िट साझा कर सकते हैं, और अगले महीनों में मेंटेनेंस की लागत क्या होगी।
उपयोग:
car_service_plan.py CAR.json SERVICE_LOG.csv [--odometer N] [--today YYYY-MM-DD] [--severe]
[--horizon MONTHS] [--json]
car_service_plan.py --self-test
एग्ज़िट: 0 = सुरक्षा/कानूनी आइटम पर कुछ भी ओवरड्यू नहीं, 1 = एक सुरक्षा या कानूनी आइटम ओवरड्यू है (या
लॉग में उच्च निष्कर्ष है), 2 = खराब इनपुट।
"""
import argparse, calendar, csv, datetime, io, json, sys
SEV = {"high": 0, "medium": 1, "low": 2, "info": 3}
CAR_KEYS = {"vehicle", "odometer", "driving", "currency", "horizon_months", "due_soon", "bundle", "schedule"}
class InputError(Exception):
pass
def pdate(s, what):
try:
return datetime.date.fromisoformat(str(s).strip())
except ValueError:
raise InputError("%s YYYY-MM-DD होना चाहिए, %r मिला" % (what, s))
def add_months(d, m):
y, mo = divmod(d.month - 1 + int(m), 12)
y += d.year
mo += 1
return datetime.date(y, mo, min(d.day, calendar.monthrange(y, mo)[1]))
def num(x, what):
try:
return float(str(x).replace(",", "").replace(" ", ""))
except ValueError:
raise InputError("%s एक संख्या नहीं है: %r" % (what, x))
def fk(x):
return "{:,.0f}".format(x)
def fm(x):
return "{:,.2f}".format(x)
# ---------------------------------------------------------------- load
def load_car(cfg, odometer=None, today=None, severe=None, horizon=None):
if not isinstance(cfg, dict):
raise InputError("कार फ़ाइल एक JSON ऑब्जेक्ट होनी चाहिए")
bad = set(cfg) - CAR_KEYS
if bad:
raise InputError("कार फ़ाइल में अज्ञात कुंजी(यां): %s" % ", ".join(sorted(bad)))
v = cfg.get("vehicle") or {}
odo = cfg.get("odometer") or {}
drv = cfg.get("driving") or {}
c = {"name": v.get("name", "कार"), "unit": v.get("unit", "km"),
"first": pdate(v["first_registered"], "vehicle.first_registered") if v.get("first_registered") else None,
"today": pdate(today or odo.get("date") or datetime.date.today().isoformat(), "today"),
"odo": num(odometer if odometer is not None else odo.get("reading"), "ओडोमीटर रीडिंग") if (odometer is not None or odo.get("reading") is not None) else None,
"default_per_year": num(drv.get("default_per_year", 12000), "driving.default_per_year"),
"severe": bool(drv.get("severe", False)) if severe is None else severe,
"severe_reasons": drv.get("severe_reasons", []),
"currency": cfg.get("currency", ""),
"horizon": int(horizon or cfg.get("horizon_months", 24)),
"soon_km": num((cfg.get("due_soon") or {}).get("km", 1500), "due_soon.km"),
"soon_days": int((cfg.get("due_soon") or {}).get("days", 45)),
"bundle_km": num((cfg.get("bundle") or {}).get("km", 2500), "bundle.km"),
"bundle_days": int((cfg.get("bundle") or {}).get("days", 60)),
"items": []}
if c["odo"] is None:
raise InputError("वर्तमान ओडोमीटर रीडिंग दें (odometer.reading या --odometer)")
for i, it in enumerate(cfg.get("schedule") or [], 1):
name = it.get("item")
if not name:
raise InputError("शेड्यूल आइटम %d में कोई 'item' नाम नहीं है" % i)
km = it.get("severe_km") if c["severe"] and it.get("severe_km") else it.get("km")
mo = it.get("severe_months") if c["severe"] and it.get("severe_months") else it.get("months")
if not km and not mo:
raise InputError("शेड्यूल आइटम '%s' को km और/या months की आवश्यकता है" % name)
c["items"].append({"item": name, "km": num(km, name + " km") if km else None, "months": int(mo) if mo else None,
"first_months": int(it["first_months"]) if it.get("first_months") else None,
"cost": num(it.get("cost", 0), name + " लागत"), "safety": bool(it.get("safety")), "legal": bool(it.get("legal")),
"severe_used": bool(c["severe"] and (it.get("severe_km") or it.get("severe_months"))),
"aliases": [a.lower().strip() for a in it.get("aliases", [])] + [name.lower().strip()]})
if not c["items"]:
raise InputError("कार फ़ाइल को एक गैर-रिक्त 'schedule' की आवश्यकता है")
return c
def load_log(c, text, F):
rows = list(csv.DictReader(io.StringIO(text)))
if rows and not {"date", "odometer", "item"} <= set(rows[0]):
raise InputError("सर्विस लॉग को कॉलम date, odometer, item की आवश्यकता है (है %s)" % ", ".join(rows[0]))
entries, readings = [], []
for n, r in enumerate(rows, 2):
try:
d = pdate(r.get("date"), "date (पंक्ति %d)" % n)
except InputError as e:
F.append(("high", "CS04", "पंक्ति %d: %s - पंक्ति अनदेखा की गई" % (n, e))); continue
if d > c["today"]:
F.append(("high", "CS04", "पंक्ति %d: तारीख %s भविष्य में है - पंक्ति अनदेखा की गई" % (n, d))); continue
odo = None
if (r.get("odometer") or "").strip():
try:
odo = num(r["odometer"], "ओडोमीटर (पंक्ति %d)" % n)
except InputError as e:
F.append(("medium", "CS04", "%s - इस पंक्ति के लिए दूरी अनदेखा की गई" % e))
items = [x.strip() for x in (r.get("item") or "").split(";") if x.strip()]
entries.append({"row": n, "date": d, "odo": odo, "items": items, "cost": r.get("cost", ""), "shop": r.get("shop", "")})
entries.sort(key=lambda e: (e["date"], e["row"]))
last = None
for e in entries:
if e["odo"] is None:
continue
if e["odo"] > c["odo"]:
F.append(("high", "CS04", "पंक्ति %d: %s पर ओडोमीटर %s वर्तमान रीडिंग %s से अधिक है - टाइपो? रीडिंग अनदेखा की गई" % (e["row"], fk(e["odo"]), e["date"], fk(c["odo"]))))
e["odo"] = None; continue
if last and e["odo"] < last["odo"]:
F.append(("medium", "CS04", "पंक्ति %d: %s पर ओडोमीटर %s, %s पर %s से कम है - टाइपो या गलत कार? रीडिंग अनदेखा की गई" % (e["row"], fk(e["odo"]), e["date"], fk(last["odo"]), last["date"])))
e["odo"] = None; continue
last = e
readings.append((e["date"], e["odo"]))
readings.append((c["today"], c["odo"]))
return entries, readings
def distance_rate(c, readings, F):
"""आज से कम से कम एक साल पहले की नवीनतम रीडिंग से किमी प्रति दिन (अन्यथा सबसे पहली)।"""
end_d, end_o = readings[-1]
older = [r for r in readings[:-1] if (end_d - r[0]).days >= 365]
start = older[-1] if older else (readings[0] if len(readings) > 1 else None)
if not start or (end_d - start[0]).days < 60 or end_o <= start[1]:
F.append(("medium", "CS09", "आपकी वार्षिक दूरी का अनुमान लगाने के लिए पर्याप्त ओडोमीटर रीडिंग नहीं - डिफ़ॉल्ट %s %s/वर्ष का उपयोग कर रहे हैं" % (fk(c["default_per_year"]), c["unit"])))
return c["default_per_year"] / 365.0, "डिफ़ॉल्ट"
rate = (end_o - start[1]) / float((end_d - start[0]).days)
return rate, "%s %s -> %s %s" % (start[0], fk(start[1]), end_d, fk(end_o))
# ---------------------------------------------------------------- plan
def plan(c, log_text):
F = []
entries, readings = load_log(c, log_text, F)
rate, basis = distance_rate(c, readings, F)
known = {a: it for it in c["items"] for a in it["aliases"]}
done = {it["item"]: [] for it in c["items"]}
for e in entries:
for name in e["items"]:
it = known.get(name.lower())
if not it:
F.append(("info", "CS07", "पंक्ति %d: '%s' आपके शेड्यूल में नहीं है - केवल इतिहास में रखा गया" % (e["row"], name)))
continue
done[it["item"]].append(e)
def date_at_km(km):
return c["today"] + datetime.timedelta(days=max(0.0, (km - c["odo"]) / rate)) if rate > 0 else None
def km_at_date(d):
return c["odo"] + rate * (d - c["today"]).days
end = add_months(c["today"], c["horizon"])
rows, occ = [], []
for it in c["items"]:
hist = done[it["item"]]
last = hist[-1] if hist else None
if last:
base_d, base_km, base_note = last["date"], last["odo"], "%s %s पर" % (last["date"], fk(last["odo"]) if last["odo"] is not None else "?")
else:
if not c["first"]:
raise InputError("'%s' का कोई रिकॉर्ड नहीं और गिनने के लिए कोई vehicle.first_registered नहीं" % it["item"])
base_d, base_km, base_note = c["first"], 0.0, "कोई रिकॉर्ड नहीं (नई से गिना गया, %s)" % c["first"]
F.append(("medium", "CS03", "%s: आपके लॉग में कोई रिकॉर्ड नहीं - नई से गिना गया; सर्विस बुक या रसीदें जांचें" % it["item"]))
months = it["months"]
if not last and it["first_months"]:
months = it["first_months"]
due_d = add_months(base_d, months) if months else None
due_km = base_km + it["km"] if (it["km"] and base_km is not None) else None
km_d = date_at_km(due_km) if due_km is not None else None
cands = [(x, w) for x, w in ((due_d, "समय"), (km_d, "दूरी")) if x]
if not cands:
due_date, trigger = c["today"], "अज्ञात"
else:
due_date, trigger = min(cands)
overdue = (due_d is not None and due_d < c["today"]) or (due_km is not None and due_km < c["odo"])
soon = not overdue and ((due_d is not None and (due_d - c["today"]).days <= c["soon_days"]) or
(due_km is not None and due_km - c["odo"] <= c["soon_km"]))
status = "ओवरड्यू" if overdue else ("जल्द ड्यू" if soon else "ठीक")
if overdue:
late = []
if due_d is not None and due_d < c["today"]:
late.append("%d दिन" % (c["today"] - due_d).days)
if due_km is not None and due_km < c["odo"]:
late.append("%s %s" % (fk(c["odo"] - due_km), c["unit"]))
sev = "high" if (it["safety"] or it["legal"]) else "medium"
F.append((sev, "CS01", "%s %s से ओवरड्यू है%s - इसे अभी बुक करें" % (it["item"], " और ".join(late), " (सुरक्षा आइटम)" if it["safety"] else (" (कानूनी आवश्यकता)" if it["legal"] else ""))))
elif soon:
F.append(("medium", "CS02", "%s जल्द ड्यू है: %s%s" % (it["item"], due_d if due_d and (due_d - c["today"]).days <= c["soon_days"] else "", (" / %s %s पर" % (fk(due_km), c["unit"])) if due_km is not None else "")))
if len(hist) >= 2 and hist[-2]["odo"] is not None and hist[-1]["odo"] is not None:
a, b = hist[-2], hist[-1]
fr = []
if it["km"]:
fr.append((b["odo"] - a["odo"]) / it["km"])
if it["months"]:
fr.append(((b["date"] - a["date"]).days / 30.44) / it["months"])
if fr and max(fr) < 0.6:
F.append(("info", "CS05", "%s अंतिम बार %s %s / %d महीने के बाद किया गया था (इंटरवल के 60%% से कम) - गंभीर उपयोग के लिए ठीक है, अन्यथा पैसा जल्दी खर्च हुआ" % (it["item"], fk(b["odo"] - a["odo"]), c["unit"], round((b["date"] - a["date"]).days / 30.44))))
rows.append({"item": it["item"], "last": base_note, "interval": " / ".join(x for x in [("%s %s" % (fk(it["km"]), c["unit"])) if it["km"] else "", ("%d महीने" % months) if months else ""] if x),
"due_date": due_d, "due_km": due_km, "next": max(due_date, c["today"]), "trigger": trigger, "status": status, "cost": it["cost"],
"safety": it["safety"] or it["legal"], "flag": "कानूनी" if it["legal"] else ("सुरक्षा" if it["safety"] else ""), "severe": it["severe_used"]})
# क्षितिज में घटनाएं (प्रत्येक को उसकी ड्यू तिथि पर किया गया माना जाता है)
d, k, first = max(due_date, c["today"]), due_km, True
guard = 0
while d <= end and guard < 50:
guard += 1
occ.append({"item": it["item"], "date": d, "km": km_at_date(d), "cost": it["cost"], "overdue": first and overdue})
first = False
nd = add_months(d, it["months"]) if it["months"] else None
nk = km_at_date(d) + it["km"] if it["km"] else None
cands = [x for x in (nd, date_at_km(nk) if nk is not None else None) if x]
if not cands:
break
d = min(cands)
if (it["cost"] >= 400) and any(o["item"] == it["item"] for o in occ):
o = next(o for o in occ if o["item"] == it["item"])
F.append(("low", "CS08", "%s (लगभग %s) %s को योजना में आता है - अभी इसके लिए बजट बनाएं" % (it["item"], fm(it["cost"]), o["date"])))
if c["severe"]:
F.append(("info", "CS06", "गंभीर-सेवा इंटरवल उपयोग किए गए%s" % ((" (" + ", ".join(c["severe_reasons"]) + ")") if c["severe_reasons"] else "")))
# विज़िट: बंडल विंडो के भीतर घटनाओं को समूहित करें
occ.sort(key=lambda o: (o["date"], o["item"]))
visits = []
for o in occ:
v = visits[-1] if visits else None
if v and (o["date"] - v["date"]).days <= c["bundle_days"] and o["km"] - v["km"] <= c["bundle_km"]:
v["items"].append(o); continue
visits.append({"date": o["date"], "km": o["km"], "items": [o]})
# तिमाही के अनुसार लागत
quarters = {}
for o in occ:
q = "%d-Q%d" % (o["date"].year, (o["date"].month - 1) // 3 + 1)
quarters[q] = quarters.get(q, 0.0) + o["cost"]
y1 = sum(o["cost"] for o in occ if o["date"] < add_months(c["today"], 12))
total = sum(o["cost"] for o in occ)
F.sort(key=lambda f: (SEV[f[0]], f[1], f[2]))
return {"car": c, "rate": rate, "basis": basis, "rows": rows, "occ": occ, "visits": visits, "quarters": quarters,
"next12": y1, "total": total, "findings": F, "entries": entries}
# ---------------------------------------------------------------- report
def report(res, title):
c, F = res["car"], res["findings"]
cnt = {s: sum(1 for f in F if f[0] == s) for s in SEV}
cur = (" " + c["currency"]) if c["currency"] else ""
ov = [r for r in res["rows"] if r["status"] == "ओवरड्यू"]
soon = [r for r in res["rows"] if r["status"] == "जल्द ड्यू"]
L = ["# सर्विस प्लान: %s" % c["name"], ""]
L.append("आज %s, ओडोमीटर %s %s। आप लगभग %s %s/वर्ष ड्राइव करते हैं (%s)। %s इंटरवल, योजना क्षितिज %d महीने। स्रोत: %s।" % (
c["today"], fk(c["odo"]), c["unit"], fk(res["rate"] * 365), c["unit"], res["basis"], "गंभीर-सेवा" if c["severe"] else "सामान्य-सेवा", c["horizon"], title))
L.append("")
if any(r["safety"] for r in ov):
L.append("**निर्णय: %d आइटम ओवरड्यू, सुरक्षा/कानूनी आइटम सहित - अभी विज़िट बुक करें**" % len(ov))
elif ov:
L.append("**निर्णय: %d आइटम ओवरड्यू - जल्द विज़िट बुक करें**" % len(ov))
elif soon:
L.append("**निर्णय: कुछ भी ओवरड्यू नहीं, %d आइटम जल्द ड्यू**" % len(soon))
else:
L.append("**निर्णय: अप टू डेट**")
L.append("")
L.append("अगले 12 महीने: लगभग %s%s; अगले %d महीने: %s%s (लगभग %s%s प्रति माह अलग रखें)। निष्कर्ष: %d उच्च, %d मध्यम, %d निम्न, %d जानकारी।" % (
fm(res["next12"]), cur, c["horizon"], fm(res["total"]), cur, fm(res["total"] / c["horizon"]), cur, cnt["high"], cnt["medium"], cnt["low"], cnt["info"]))
L += ["", "## आइटम", "", "| आइटम | इंटरवल | अंतिम बार किया गया | ड्यू तिथि तक | ड्यू %s पर | अगला (अनुमानित) | ट्रिगर | स्थिति | अनुमानित लागत |" % c["unit"], "|---|---|---|---|---|---|---|---|---|"]
order = {"ओवरड्यू": 0, "जल्द ड्यू": 1, "ठीक": 2}
for r in sorted(res["rows"], key=lambda r: (order[r["status"]], r["next"])):
L.append("| %s%s | %s | %s | %s | %s | %s | %s | %s | %s |" % (
r["item"], (" [%s]" % r["flag"]) if r["flag"] else "", r["interval"] + (" (गंभीर)" if r["severe"] else ""), r["last"],
r["due_date"] or "-", fk(r["due_km"]) if r["due_km"] is not None else "-", r["next"], r["trigger"],
"**%s**" % r["status"] if r["status"] != "ठीक" else "ठीक", fm(r["cost"])))
L += ["", "## वर्कशॉप विज़िट (%d दिनों / %s %s के भीतर आइटम बंडल किए गए हैं)" % (c["bundle_days"], fk(c["bundle_km"]), c["unit"]), "",
"| # | बुक करें | लगभग | आइटम | अनुमानित लागत |", "|---|---|---|---|---|"]
for i, v in enumerate(res["visits"], 1):
L.append("| %d | %s%s | %s %s | %s | %s |" % (i, v["date"], " (अभी)" if v["date"] == c["today"] else "", fk(v["km"]), c["unit"],
", ".join(o["item"] + (" (ओवरड्यू)" if o["overdue"] else "") for o in v["items"]), fm(sum(o["cost"] for o in v["items"]))))
L += ["", "## तिमाही के अनुसार लागत पूर्वानुमान", "", "| तिमाही | अनुमानित लागत |", "|---|---|"]
for q in sorted(res["quarters"]):
L.append("| %s | %s |" % (q, fm(res["quarters"][q])))
L.append("| **कुल %d महीने** | **%s** |" % (c["horizon"], fm(res["total"])))
L += ["", "## निष्कर्ष", ""]
L += ["- **%s %s** %s" % (s.upper(), code, m) for s, code, m in F] or ["- कोई नहीं"]
L += ["", "इंटरवल और कीमतें आपकी कार फ़ाइल से आती हैं: उन्हें अपने सटीक इंजन के लिए मालिक के मैनुअल या सर्विस बुकलेट के खिलाफ जांचें, और यदि आपकी वर्कशॉप पहले घिसाव पाती है तो उसका पालन करें। लागत अनुमान हैं; टायर और ब्रेक भी घिसाव पर निर्भर करते हैं, न कि केवल दूरी पर।"]
return "\n".join(L) + "\n"
def to_json(res):
def j(x):
if isinstance(x, datetime.date):
return x.isoformat()
if isinstance(x, float):
return round(x, 2)
if isinstance(x, dict):
return {k: j(v) for k, v in x.items()}
if isinstance(x, list):
return [j(v) for v in x]
return x
return j({"km_per_year": res["rate"] * 365, "items": res["rows"], "visits": [{"date": v["date"], "km": v["km"], "items": [o["item"] for o in v["items"]],
"cost": sum(o["cost"] for o in v["items"])} for v in res["visits"]], "quarters": res["quarters"], "next12": res["next12"], "total": res["total"],
"findings": [{"severity": s, "code": c, "message": m} for s, c, m in res["findings"]]})
# ---------------------------------------------------------------- self-test
def self_test():
tests = []
def t(name, cond):
tests.append((name, bool(cond)))
def car(**kw):
cfg = {"vehicle": {"name": "T", "first_registered": "2020-01-01"}, "odometer": {"reading": 50000, "date": "2026-01-01"},
"schedule": [{"item": "तेल", "km": 15000, "months": 12, "severe_km": 7500, "severe_months": 6, "cost": 100, "aliases": ["oil change"]}]}
sched = kw.pop("schedule", None)
if sched:
cfg["schedule"] = sched
cfg.update(kw)
return cfg
H = "date,odometer,item,cost,shop\n"
def run(cfg, log, **kw):
return plan(load_car(cfg, **kw), H + log)
def row(res, name):
return next(r for r in res["rows"] if r["item"] == name)
def codes(res):
return [(f[0], f[1]) for f in res["findings"]]
log = "2025-01-01,40000,तेल,90,X\n"
r = run(car(), log)
t("रीडिंग से दर: 10000 किमी/वर्ष", abs(r["rate"] * 365 - 10000) < 1)
t("समय से पहले ड्यू (12 महीने)", row(r, "तेल")["due_date"] == datetime.date(2026, 1, 1) and row(r, "तेल")["trigger"] == "समय")
t("आज ड्यू जल्द ड्यू माना जाता है", row(r, "तेल")["status"] == "जल्द ड्यू")
r = run(car(), "2025-06-01,40000,तेल,90,X\n")
t("दूरी पहले ट्रिगर होती है जब बहुत ड्राइव करते हैं", row(r, "तेल")["due_km"] == 55000 and row(r, "तेल")["trigger"] == "दूरी")
r = run(car(), "2024-06-01,30000,तेल,90,X\n")
t("समय और दूरी से ओवरड्यू -> CS01", row(r, "तेल")["status"] == "ओवरड्यू" and ("medium", "CS01") in codes(r))
sched = [{"item": "ब्रेक फ्लुइड", "months": 24, "cost": 80, "safety": True}]
r = run(car(schedule=sched), "2023-06-01,30000,ब्रेक फ्लुइड,80,X\n2025-01-01,40000,अन्य,0,X\n")
t("ओवरड्यू सुरक्षा आइटम -> CS01 उच्च", ("high", "CS01") in codes(r))
t("शेड्यूल में नहीं आइटम -> CS07", ("info", "CS07") in codes(r))
r = run(car(), "2025-01-01,40000,oil change,90,X\n")
t("उपनाम केस-असंवेदनशील रूप से मेल खाते हैं", row(r, "तेल")["last"].startswith("2025-01-01"))
r = run(car(), "2025-01-01,40000,वाइपर,20,X\n")
t("कोई रिकॉर्ड नहीं -> नई से गिना गया, CS03", ("medium", "CS03") in codes(r) and "कोई रिकॉर्ड नहीं" in row(r, "तेल")["last"])
r = run(car(), "2025-01-01,40000,तेल,90,X\n", severe=True)
t("गंभीर इंटरवल उपयोग किए गए", row(r, "तेल")["due_date"] == datetime.date(2025, 7, 1) and ("info", "CS06") in codes(r))
r = run(car(), "2024-01-01,30000,तेल,90,X\n2024-06-01,20000,तेल,90,X\n2025-01-01,40000,तेल,90,X\n")
t("ओडोमीटर नीचे जाना -> CS04, रीडिंग अनदेखा", ("medium", "CS04") in codes(r))
r = run(car(), "2025-01-01,40000,तेल,90,X\n2027-01-01,60000,तेल,90,X\n")
t("भविष्य की तारीख -> CS04 उच्च", ("high", "CS04") in codes(r))
r = run(car(), "2025-01-01,90000,तेल,90,X\n")
t("वर्तमान ओडोमीटर से ऊपर रीडिंग -> CS04 उच्च", ("high", "CS04") in codes(r))
r = run(car(), "")
t("कोई रीडिंग नहीं -> डिफ़ॉल्ट दर + CS09", ("medium", "CS09") in codes(r) and abs(r["rate"] * 365 - 12000) < 1)
r = run(car(), "2025-01-01,40000,तेल,90,X\n2025-04-01,42000,तेल,90,X\n")
t("जल्दी किया गया -> CS05", ("info", "CS05") in codes(r))
sched = [{"item": "परीक्षण", "months": 12, "first_months": 36, "cost": 50, "legal": True}]
r = run(car(vehicle={"first_registered": "2024-01-01"}, schedule=sched), "2025-01-01,40000,अन्य,0,X\n")
t("नई से पहले परीक्षण के लिए first_months", row(r, "परीक्षण")["due_date"] == datetime.date(2027, 1, 1))
sched = [{"item": "A", "months": 12, "cost": 100}, {"item": "B", "months": 12, "cost": 50}]
r = run(car(schedule=sched), "2025-02-01,41000,A,0,X\n2025-03-15,42000,B,0,X\n")
t("बंडल विंडो के भीतर आइटम एक विज़िट साझा करते हैं", len(r["visits"][0]["items"]) == 2)
t("क्षितिज वार्षिक आइटम दोहराता है", sum(1 for o in r["occ"] if o["item"] == "A") == 2)
t("12-महीने और कुल पूर्वानुमान", r["next12"] == 150 and r["total"] == 300)
sched = [{"item": "बेल्ट", "km": 120000, "months": 96, "cost": 650}]
r = run(car(schedule=sched), "2025-01-01,40000,अन्य,0,X\n")
t("क्षितिज में बड़ा-टिकट आइटम -> CS08", ("low", "CS08") in codes(r))
t("add_months महीने के अंत को क्लैम्प करता है", add_months(datetime.date(2026, 1, 31), 1) == datetime.date(2026, 2, 28))
try:
load_car(car(schedule=[{"item": "X", "cost": 1}])); ok = False
except InputError:
ok = True
t("बिना इंटरवल वाला आइटम अस्वीकृत", ok)
try:
load_car(dict(car(), colour="red")); ok = False
except InputError:
ok = True
t("अज्ञात कुंजी अस्वीकृत", ok)
r = run(car(), log)
t("रिपोर्ट में निर्णय, विज़िट और पूर्वानुमान है", all(s in report(r, "t") for s in ("**निर्णय:", "## वर्कशॉप विज़िट", "## तिमाही के अनुसार लागत पूर्वानुमान")))
for name, ok in tests:
print(("पास " if ok else "विफल ") + name)
passed = sum(ok for _, ok in tests)
print("%d/%d पास" % (passed, len(tests)))
return 0 if passed == len(tests) else 1
def main(argv=None):
ap = argparse.ArgumentParser(description="शेड्यूल और सर्विस लॉग से कार मेंटेनेंस की योजना बनाएं।")
ap.add_argument("car", nargs="?")
ap.add_argument("log", nargs="?")
ap.add_argument("--odometer", type=float)
ap.add_argument("--today")
ap.add_argument("--severe", action="store_true", default=None, help="गंभीर-सेवा इंटरवल का उपयोग करें")
ap.add_argument("--horizon", type=int, help="योजना बनाने के लिए महीने (कार फ़ाइल से डिफ़ॉल्ट, अन्यथा 24)")
ap.add_argument("--json", action="store_true")
ap.add_argument("--self-test", action="store_true")
a = ap.parse_args(argv)
if a.self_test:
return self_test()
if not a.car or not a.log:
ap.print_usage(sys.stderr)
return 2
try:
try:
cfg = json.load(open(a.car, encoding="utf-8"))
except json.JSONDecodeError as e:
raise InputError("कार फ़ाइल मान्य JSON नहीं है: %s" % e)
c = load_car(cfg, a.odometer, a.today, a.severe, a.horizon)
res = plan(c, open(a.log, encoding="utf-8-sig").read())
except (OSError, InputError) as e:
print("त्रुटि: %s" % e, file=sys.stderr)
return 2
if a.json:
print(json.dumps(to_json(res), indent=2))
else:
sys.stdout.write(report(res, a.log))
return 1 if any(f[0] == "high" for f in res["findings"]) else 0
if __name__ == "__main__":
sys.exit(main())
```
पूरा प्रॉम्प्ट देखने के लिए साइन इन करें
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
उपयोग
यह प्रॉम्प्ट productivity के साथ उपयोग के लिए डिज़ाइन किया गया है। ऊपर प्रॉम्प्ट सामग्री कॉपी करें और अपने पसंदीदा AI टूल में पेस्ट करें।
सर्वोत्तम परिणामों के लिए, आप अपनी विशिष्ट आवश्यकताओं के अनुसार प्लेसहोल्डर (वर्ग कोष्ठक या बड़े अक्षरों में दर्शाए गए) को अनुकूलित कर सकते हैं।
चर्चा
0 टिप्पणियाँ