Last chance! 50% off DataCamp Premium
Sale ends in
कोडिंग किसी कंप्यूटर को एक विशेष कार्य करने के लिए दिए जाने वाले निर्देश – जिन्हें एल्गोरिदम भी कहा जाता है – लिखने की कला है। कंप्यूटर से संचार करने के लिए डेवलपर प्रोग्रामिंग भाषाओं का उपयोग करते हैं।
अंग्रेज़ी, रूसी या केचुआ जैसी प्राकृतिक भाषाओं की तरह, प्रोग्रामिंग भाषाएँ भी संप्रेषण के लिए आवश्यक विशिष्ट वाक्यविन्यास और अर्थगत नियमों के सेट से बनी होती हैं। यद्यपि प्राकृतिक भाषाएँ अधिक जटिल, लचीली और गतिशील होती हैं, ये विशेषताएँ सीमित हद तक प्रोग्रामिंग भाषाओं पर भी लागू होती हैं।
सबसे सरल एल्गोरिदम भी आप कई तरीकों से लिख सकते हैं। कोड विकसित करते समय कुछ लचीलापन अच्छा होता है, लेकिन यह दक्षता और प्रभावी संप्रेषण से समझौता कर सकता है, खासकर जब उस पर कई लोग काम कर रहे हों।
इसी कारण, पठनीयता कोड लेखन का एक महत्वपूर्ण पहलू है। यह सुनिश्चित करने के लिए कि डेवलपर एक ही पृष्ठ पर हों, अधिकांश प्रोग्रामिंग भाषाओं ने कोडिंग मानक विकसित किए हैं। ये दस्तावेज़ पढ़ने योग्य, अनुरक्षित और स्केलेबल कोड बनाने के लिए दिशानिर्देश और सर्वोत्तम प्रथाएँ प्रदान करते हैं।
इस लेख में, हम Python में कोडिंग की सर्वोत्तम प्रथाएँ देखेंगे, जो सबसे लोकप्रिय डेटा साइंस भाषाओं में से एक है। निम्नलिखित अनुभागों में प्रस्तुत प्रथाएँ मुख्यतः आधारित हैं PEP 8 पर, जो Python में कोड लिखने के लिए मानक गाइड है।
Python का उपयोग किन कार्यों में होता है, यह जानने के लिए हमारा लेख या हमारा Introduction to Python कोर्स देखें।
“कोड को जितनी बार लिखा जाता है, उससे कहीं अधिक बार पढ़ा जाता है। कोड हमेशा इस तरह लिखा जाना चाहिए कि वह पढ़ने में आसान हो” – Guido van Rossum, Python के जनक
PEP 8 Python कोड के लिए एक स्टाइल गाइड है। 2001 में Guido van Rossum, Barry Warsaw और Nick Coghlan द्वारा लिखी गई, यह अधिक पठनीय और सुसंगत कोड लिखने के लिए सिफारिशों का एक सेट प्रदान करती है। यह वेरिएबल्स का नाम कैसे रखना है से लेकर एक पंक्ति में अधिकतम कितने अक्षर होने चाहिए, सब कुछ कवर करती है।
PEP का अर्थ है Python Enhancement Proposal। एक PEP वह दस्तावेज़ होता है जो Python के लिए प्रस्तावित नई विशेषताओं का वर्णन करता है और Python के पहलुओं, जैसे डिज़ाइन और शैली, का दस्तावेजीकरण करता है।
यद्यपि अनिवार्य नहीं है, Python समुदाय का एक बड़ा हिस्सा PEP 8 का उपयोग करता है। इसलिए दिशानिर्देशों का पालन करना अत्यधिक सलाहनीय है। ऐसा करने से, आप एक पेशेवर प्रोग्रामर के रूप में अपनी विश्वसनीयता बढ़ाएँगे।
PEP 8 की व्यापक स्वीकृति के बावजूद, ये दिशानिर्देश हर परिदृश्य में फिट नहीं बैठ सकते। ऐसे मामलों में, कंपनियाँ अक्सर अपनी स्वयं की परंपराएँ तय करती हैं।
पढ़ने योग्य और सुव्यवस्थित कोड लिखना वास्तविक फर्क ला सकता है और आपके करियर के अवसरों को बढ़ा सकता है। शुरुआती लोगों को भले ही कोडिंग यांत्रिक और जटिल प्रक्रिया लगे, सच्चाई यह है कि कोडिंग एक कला है।
Python में कोड गुणवत्ता बढ़ाने के लिए आप कई सुझावों का पालन कर सकते हैं। यहाँ कुछ सबसे प्रासंगिक सुझावों की सूची दी गई है।
इंडेंटेशन का मतलब कोड की पंक्ति की शुरुआत में स्पेस से है। जहाँ अन्य प्रोग्रामिंग भाषाओं में इंडेंटेशन केवल पठनीयता के लिए संसाधन है, वहीं Python में इंडेंटेशन अनिवार्य है। Python इंडेंटेशन का उपयोग कोड ब्लॉक खोलने के लिए करता है। अधिक सटीक रूप से, प्रति इंडेंटेशन स्तर 4 लगातार स्पेस, जैसा कि निम्न कोड में दिखाया गया है:
for number in [1,2,3,4]:
if number % 2 == 0:
print(number)
else:
continue
PEP 8 सिफारिश करता है कि कोई भी पंक्ति 79 अक्षरों से लंबी नहीं होनी चाहिए। यह तर्कसंगत है, क्योंकि छोटी पंक्तियाँ पढ़ने में आसान होती हैं। साथ ही, इस लंबाई से आप कई फ़ाइलें साथ-साथ खोल सकते हैं।
टॉप-लेवल फ़ंक्शन और क्लास परिभाषाओं को दो रिक्त पंक्तियों से घेरें। किसी क्लास के अंदर मेथड परिभाषाओं के आसपास एक रिक्त पंक्ति रखें। संबंधित फ़ंक्शनों के समूहों को अलग करने के लिए अतिरिक्त रिक्त पंक्तियाँ (संयम से) उपयोग की जा सकती हैं। अंत में, फ़ंक्शनों के भीतर तार्किक अनुभागों को दर्शाने के लिए (संयम से) रिक्त पंक्तियाँ उपयोग करें।
कोड में महारत समय लेती है। कोडिंग के दौरान सभी विवरणों पर ध्यान देना चुनौतीपूर्ण और समय लेने वाला हो सकता है। सौभाग्य से, मशीनें, खासकर लिंटर्स और फ़ॉर्मैटर्स, कोड गुणवत्ता सुनिश्चित करने में हमारी मदद कर सकती हैं।
लिंटर्स सोर्स कोड का स्थैतिक विश्लेषण करते हैं और अर्थगत विसंगतियों की जाँच करते हैं। फ़ॉर्मैटर्स समान टूल हैं जो आपके कोड के स्पेसिंग, पंक्ति लंबाई, आर्गुमेंट पोजिशनिंग आदि को पुनर्संरचित करने की कोशिश करते हैं ताकि अलग-अलग फ़ाइलों या प्रोजेक्ट्स में आपका कोड सुसंगत दिखे। Python आपको चुनने के लिए लिंटर्स और फ़ॉर्मैटर्स की एक बड़ी श्रृंखला देता है।
ऊपर बताए गए कुछ नियम सीधे-सादे हैं, लेकिन कोडिंग अक्सर अच्छे स्वाद और सहज ज्ञान का विषय होती है। कोडिंग में माहिर बनने के लिए, आपको Python की कुछ बुनियादी मान्यताओं के बारे में पता होना चाहिए। ऐसे सिद्धांतों का एक शानदार उदाहरण है Zen of Python, जिसे एक अलग लेख में कवर किया गया है।
लॉगिंग वह तरीका है जिससे सॉफ़्टवेयर चलने पर होने वाली घटनाओं को ट्रैक किया जाता है। खासकर जब एप्लिकेशन आकार और जटिलता में बढ़ते हैं, तो विकास, डिबगिंग, रनिंग और प्रदर्शन ट्रैकिंग के लिए लॉगिंग एक महत्वपूर्ण तकनीक बन जाती है।
logging मॉड्यूल लॉगिंग प्रथाओं को संबोधित करने के लिए संस्करण 2.3 से Python की स्टैंडर्ड लाइब्रेरी का हिस्सा रहा है। लॉगिंग के संदर्भ में यह अधिकांश Python डेवलपर्स के लिए पहला विकल्प है और PEP 282 में विस्तृत रूप से वर्णित है।
लॉगिंग भावना में Print फ़ंक्शन के समान है। हालाँकि, प्रिंट फ़ंक्शन में वह बहुत-सी जानकारी नहीं होती जो डेवलपर के लिए उपयोगी हो सकती है। लॉगिंग, इसके विपरीत, त्रुटि के होने का टाइमस्टैम्प और पंक्ति संख्या लॉग कर सकती है। यह त्रुटियों या किसी भी जानकारी को फाइलों, सॉकेट्स आदि में भी लॉग कर सकती है।
मॉड्यूल को इम्पोर्ट करने के लिए, आपको बस यह कोड चलाना होगा:
import logging
हर लॉग संदेश समान नहीं होता। वास्तव में, मॉड्यूल संदेश की गंभीरता के अनुसार लॉगिंग स्तरों की श्रेणी प्रदान करता है। श्रेणी इस प्रकार है:
import logging
logging.info('This message is just informative')
logging.debug('My missions is to provide information about debugging.')
logging.critical("A Critical Logging Message")
यह कहते हुए, नीचे Python में लॉगिंग को संभालने के छह सर्वोत्तम अभ्यासों की सूची दी गई है।
हमने पहले कहा था कि लॉग्स प्रिंट फ़ंक्शनों के समान जानकारी प्रदान करते हैं। हालाँकि, लॉग्स कहीं अधिक शक्तिशाली हैं और अधिक सूक्ष्म जानकारी दे सकते हैं।
यदि आप लॉगिंग रूटीन से परिचित नहीं हैं, तो Print फ़ंक्शन की ओर जाना आकर्षक लग सकता है, लेकिन लॉग्स हमेशा अधिक सुरक्षित विकल्प होंगे। वे स्केल करने और जटिल एप्लिकेशन संभालने के लिए बेहतर उपयुक्त हैं।
वेब गाइड और डॉक्यूमेंटेशन से भरा है। उदाहरण के लिए, यह DataCamp लॉगिंग ट्यूटोरियल शुरुआत करने के लिए उपयुक्त हो सकता है।
यह मॉड्यूल अधिकांश Python डेवलपर्स के लिए प्रमुख विकल्प है। इसका अर्थ है कि मॉड्यूल अच्छी तरह मेंटेन किया गया है और एक बड़े समुदाय का समर्थन प्राप्त है जो आपके सवालों के जवाब देगा।
logging मॉड्यूल में संदेशों के छह अलग-अलग स्तर आते हैं। प्रत्येक का एक विशिष्ट उद्देश्य होता है। जितना अधिक आप उनके अनुरूप रहेंगे, आपके और उपयोगकर्ताओं के लिए आपके कोड में क्या हो रहा है, यह समझना उतना आसान होगा।
यह लॉग्स की एक महत्वपूर्ण विशेषता है जो प्रिंट फ़ंक्शनों में नहीं होती। जहाँ समस्या आई, यह जानने के अलावा, यह जानना भी ज़रूरी है कि वह कब हुई। ऐसे में टाइमस्टैम्प्स आपके सबसे बड़े सहायक होते हैं। सुनिश्चित करें कि टाइमस्टैम्प लिखने के लिए मानक प्रारूप, यानी ISO-8601 प्रारूप, का उपयोग करें।
FileHandler के बजाय RotatingFileHandler क्लासेस, जैसे TimedRotatingFileHandler, का उपयोग करें ताकि पुराने लॉग फ़ाइलों को संग्रहित, संपीड़ित या हटाकर मेमोरी स्पेस की समस्याओं से बचा जा सके। ये क्लासेस आकार सीमा या समय शर्त ट्रिगर होने पर जगह साफ करेंगी।
कमेंट्स हमारे कोड के भविष्य के पाठकों के लिए टिप्पणी करने में बहुत महत्वपूर्ण होते हैं। यद्यपि यह परिभाषित करना कठिन है कि कोड पर कमेंट कैसे किया जाना चाहिए, कुछ दिशानिर्देश हैं जिन्हें हम अपना सकते हैं:
दो प्रकार के कमेंट्स होते हैं: ब्लॉक कमेंट्स और इनलाइन कमेंट्स।
ब्लॉक कमेंट उसके बाद आने वाले कोड की व्याख्या करता है। आमतौर पर, आप ब्लॉक कमेंट को कोड ब्लॉक के समान स्तर पर इंडेंट करते हैं। ब्लॉक कमेंट की प्रत्येक पंक्ति # और एक सिंगल स्पेस से शुरू होती है, जैसे:
# This is a block comment
print('Welcome to DataCamp!")
दूसरी ओर, इनलाइन कमेंट्स कोड के समान स्तर पर दिखाई देते हैं। इनलाइन कमेंट्स स्टेटमेंट से कम से कम दो स्पेस से अलग होने चाहिए। ब्लॉक कमेंट की तरह, इनलाइन कमेंट एक सिंगल हैश साइन (#) से शुरू होता है और उसके बाद एक स्पेस और टेक्स्ट स्ट्रिंग आती है।
print ("Have you ever tried Python?") # This is an inline comment
डॉकस्ट्रिंग वह स्ट्रिंग लिटरल है जो किसी मॉड्यूल, फ़ंक्शन, क्लास या मेथड परिभाषा में पहले स्टेटमेंट के रूप में आती है। आमतौर पर, आप डॉक्यूमेंटेशन स्ट्रिंग का उपयोग स्वचालित रूप से कोड डॉक्यूमेंटेशन जनरेट करने के लिए करते हैं। इस प्रकार, किसी ऑब्जेक्ट की डॉकस्ट्रिंग को रन-टाइम पर उस ऑब्जेक्ट के विशेष एट्रिब्यूट obj.__doc__ से एक्सेस किया जा सकता है।
संगति के लिए, डॉकस्ट्रिंग्स को हमेशा ट्रिपल डबल कोट्स (""") में बंद किया जाता है।
डॉकस्ट्रिंग्स के दो रूप होते हैं: वन-लाइनर और मल्टीलाइन डॉकस्ट्रिंग्स। वन-लाइनर वास्तव में स्पष्ट मामलों के लिए होते हैं। वे वास्तव में एक ही पंक्ति में फिट होने चाहिए। निम्न उदाहरण multiply() फ़ंक्शन में एक लाइन की डॉकस्ट्रिंग दर्शाता है:
def multiply(x, y):
""" Return the product of two numbers """
result = x * y
return result
दूसरी ओर, मल्टीलाइन डॉकस्ट्रिंग कई पंक्तियों में हो सकती है। ऐसी डॉकस्ट्रिंग में स्क्रिप्ट के फ़ंक्शन, कमांड लाइन सिंटैक्स, एनवायरनमेंट वेरिएबल्स और फाइलों का दस्तावेज होना चाहिए। उपयोग संदेश पर्याप्त रूप से विस्तृत हो सकते हैं और नए उपयोगकर्ता के लिए कमांड को सही ढंग से उपयोग करने के लिए पर्याप्त होने चाहिए।
def calculate_salary(hours, price=20):
""" Return the salary according to the hours worked
Arguments:
hours: total hours investe
price: price of each hours worked. Minimum price is 20 dollars
"""
salary = hours * price
return salary
डॉकस्ट्रिंग्स का अधिक विस्तृत विवरण PEP257 में पाया जा सकता है।
जहाँ कमेंट्स उन अन्य डेवलपर्स के लिए महत्वपूर्ण हैं जिनके साथ आप काम कर रहे हैं ताकि वे आपके कोड को समझ सकें, वहीं डॉक्यूमेंटेशन संभावित उपयोगकर्ताओं के समुदाय को आपका सॉफ़्टवेयर उपयोग करना सिखाने के लिए होता है। यह एक महत्वपूर्ण चरण है: आपका सॉफ़्टवेयर चाहे कितना भी अच्छा हो, यदि डॉक्यूमेंटेशन पर्याप्त अच्छा नहीं है, या और भी बुरा, अनुपस्थित है, तो लोग इसका उपयोग नहीं करेंगे।
एक README फ़ाइल शामिल करना हमेशा एक अच्छा अभ्यास है, खासकर यदि आप किसी नए प्रोजेक्ट पर काम कर रहे हैं। ये फाइलें आमतौर पर आपके कोड के पाठकों के लिए मुख्य प्रवेश बिंदु होती हैं और प्रोजेक्ट के उपयोगकर्ताओं और मेंटेनर्स दोनों के लिए सामान्य जानकारी शामिल करती हैं।
संक्षिप्त होते हुए भी, README फ़ाइल में प्रोजेक्ट का उद्देश्य, सॉफ़्टवेयर के मुख्य स्रोत का URL और श्रेय संबंधी जानकारी समझाई जानी चाहिए।
इसी तरह, आपको हमेशा setup.py फ़ाइल शामिल करनी चाहिए, यह सुनिश्चित करने के लिए कि सॉफ़्टवेयर या लाइब्रेरी को Distutils के साथ पैकेज और वितरित किया गया है, जो Python मॉड्यूल वितरित करने का मानक है।
इसके अलावा, यदि आपका सॉफ़्टवेयर चलाने के लिए अन्य निर्भरताएँ या पैकेज आवश्यक हैं, तो आपको एक requirements.txt फ़ाइल शामिल करनी चाहिए जो आवश्यक निर्भरताओं और उनके संस्करणों का वर्णन करे।
अंत में, आप किसी भी अन्य जानकारी को जोड़ने के लिए स्वतंत्र हैं जिसे आप संभावित उपयोगकर्ताओं के लिए प्रासंगिक मानते हैं। उदाहरण के लिए, यह एक अच्छी प्रथा है कि आप यह दिखाएँ कि आपका पैकेज या फ़ंक्शंस कैसे काम करते हैं।
अपने डेटा प्रोजेक्ट्स में क्रम और सुसंगति सुनिश्चित करने के लिए, हर नए प्रोजेक्ट के लिए एक वर्चुअल एनवायरनमेंट बनाना एक अच्छी प्रथा है।
वर्चुअल एनवायरनमेंट, जिन्हें virtualenvs भी कहा जाता है, आपके प्रोजेक्ट के लिए आवश्यक Python और लाइब्रेरी वर्ज़न तथा संबंधित pip वर्ज़न को अलग-थलग रखने में मदद करते हैं। इससे एंड-यूज़र सिस्टम द्वारा प्रदत्त सॉफ़्टवेयर और संस्करणों से स्वतंत्र, अपने स्वयं के सॉफ़्टवेयर और संस्करणों का सेट इंस्टॉल और प्रबंधित कर सकते हैं।
virtualenvs बनाने के लिए, हमें पहले आवश्यक पैकेज इंस्टॉल करना होगा, अपने टर्मिनल में निम्न पंक्ति लिखकर:
pip install virtualenv
नया virtualenv बनाने के लिए, निम्न कोड काम कर देगा। हम नए virtualenv को “new_venv” कह रहे हैं
python3 -m venv /path/to/new/virtual/environment/new_venv
शुरुआती Python डेवलपर्स के बीच सबसे आम गलतियों में से एक है वेरिएबल्स, क्लासेस, फ़ंक्शंस आदि का अनुचित नामकरण। नामकरण परंपराएँ कोड की पठनीयता सुनिश्चित करने के लिए महत्वपूर्ण तत्व हैं।
PEP 8 Python में ऑब्जेक्ट्स के नामकरण का मानक तरीका समझाता है। दिशानिर्देशों के अनुसार, नए मॉड्यूल और पैकेज (तृतीय-पक्ष फ़्रेमवर्क सहित) इन्हीं मानकों के अनुसार लिखे जाने चाहिए, लेकिन जहाँ किसी मौजूदा लाइब्रेरी की शैली अलग है, वहाँ आंतरिक सुसंगति को प्राथमिकता दी जाती है।
बहुत सामान्य या बहुत दुनियावी नामों का उपयोग करने से बचें। साथ ही, स्टैंडर्ड लाइब्रेरी में उपयोग किए गए पहचानकर्ता PEP 3131 में वर्णित अनुसार ASCII संगत होने चाहिए।
# Bad naming:
data_structure, ríos_españa, dictionary_with_countries_and_capitals
# Good naming:
user_profile, stop_words, global_emissions_df
नीचे Python में सबसे सामान्य ऑब्जेक्ट्स के लिए नामकरण परंपराओं की सूची है।
|
पहचानकर्ता |
परंपरा |
|
मॉड्यूल |
lowercase |
|
क्लास |
CapWords |
|
फ़ंक्शंस |
lowercase |
|
मेथड्स |
lowercase |
|
टाइप वेरिएबल्स |
CapWords |
|
कॉनस्टेंट्स |
UPPERCASE |
|
पैकेज |
lowercase |
Python की सर्वोत्तम प्रथाओं में महारत साफ-सुथरा, कुशल और अनुरक्षित कोड लिखने के लिए अनिवार्य है। कोड गुणवत्ता, लॉगिंग, कमेंटिंग और डॉक्यूमेंटेशन पर दिशानिर्देशों का पालन करके, और वर्चुअल एनवायरनमेंट जैसे टूल का उपयोग करके, आप सुनिश्चित कर सकते हैं कि आपके प्रोजेक्ट्स को प्रबंधित करना, सहयोग करना और स्केल करना आसान हो।
जैसे-जैसे आप अपनी Python कौशल में सुधार करते हैं, Python और इसके व्यापक अनुप्रयोगों को गहराई से समझने के लिए अधिक गहन शिक्षण संसाधनों को एक्सप्लोर करने पर विचार करें। यदि आप संरचित मार्गदर्शन ढूँढ रहे हैं, तो ये संसाधन देखें:
सॉफ़्टवेयर विकास के दौरान पठनीयता, गुणवत्तापूर्ण कोड और स्केलेबिलिटी सुनिश्चित करने के लिए।
वर्चुअल एनवायरनमेंट एक ऐसा टूल है जो प्रत्येक प्रोजेक्ट के लिए एक अलग, आइसोलेटेड एनवायरनमेंट बनाकर अलग-अलग प्रोजेक्ट्स की निर्भरताओं को अलग करता है।
यह एक दस्तावेज़ है जो Python कोड कैसे लिखें, इस पर मानक दिशानिर्देश और सर्वोत्तम प्रथाएँ प्रदान करता है।
इंडेंटेशन कोड की पंक्ति की शुरुआत में स्पेस को संदर्भित करता है। Python कोड ब्लॉक इंगित करने के लिए इंडेंटेशन का उपयोग करता है।
Zen of Python 19 "मार्गदर्शक सिद्धांतों" का संग्रह है जो कंप्यूटर प्रोग्राम लिखने के लिए हैं और जो Python प्रोग्रामिंग भाषा के डिज़ाइन को प्रभावित करते हैं।
Python डॉकस्ट्रिंग वह स्ट्रिंग है जिसका उपयोग किसी Python मॉड्यूल, क्लास, फ़ंक्शन या मेथड का दस्तावेजीकरण करने के लिए किया जाता है, ताकि प्रोग्रामर इम्प्लिमेंटेशन के विवरण पढ़े बिना समझ सकें कि यह क्या करता है।
दो प्रकार के कमेंट्स होते हैं: ब्लॉक कमेंट्स और इनलाइन कमेंट्स।
मैं एक स्वतंत्र डेटा विश्लेषक हूँ और दुनिया भर की कंपनियों व संगठनों के साथ डेटा साइंस परियोजनाओं पर सहयोग करता/करती हूँ। मैं 2+ वर्षों के अनुभव वाला/वाली डेटा साइंस प्रशिक्षक भी हूँ। मैं नियमित रूप से अंग्रेज़ी और स्पेनिश में डेटा साइंस से संबंधित लेख लिखता/लिखती हूँ, जिनमें से कुछ DataCamp, Towards Data Science और Analytics Vidhya जैसी स्थापित वेबसाइटों पर प्रकाशित हुए हैं। राजनीतिक विज्ञान और क़ानून की पृष्ठभूमि वाले/वाली डेटा वैज्ञानिक के रूप में, मेरा लक्ष्य लोक नीति, क़ानून और प्रौद्योगिकी के संगम पर काम करना है—विचारों की शक्ति का उपयोग करके ऐसे अभिनव समाधान और कथाएँ विकसित करना जो हमें तात्कालिक चुनौतियों, विशेषकर जलवायु संकट, से निपटने में मदद कर सकें। मैं स्वयं-अध्येता, सतत सीखने वाला/वाली और बहुविषयक दृष्टिकोण का प्रबल समर्थक/समर्थक हूँ। नई चीज़ें सीखने में कभी देर नहीं होती।
इन कोर्सेज़ के साथ Python के बारे में और जानें!
{count, plural, one {कोर्स} other {कोर्स}}
{count, plural, one {कोर्स} other {कोर्स}}
{count, plural, one {कोर्स} other {कोर्स}}