Search

1.10a — आपका पहला program कैसे design किया जाये

अब आप programs के basics को समझ चुके हैं, आइये अब ज़रा करीब से देखें की program को design कैसे किया जाये । जब आप program लिखने वाले होगे, आपके पास ज़रूर कोई ना कोई problem होगा जिसे आप उस program के ज़रिये solve करना चाहते हैं । नए programmers अकसर इस बात का सही अंदाज़ा नहीं लगा पाते हैं की उनके ideas को codes में कैसे तब्दील किया जाये । लेकिन देखा जाये, तो आप दैनिक जीवन से ही कई सारे problem solving skills सीख चुके हो ।

जिस चीज़ को याद रखना सबसे ज्यादा ज़रूरी है (और जो सबसे ज्यादा मुश्किल काम है), वो है coding शुरू करने से पहले program को design करना । कई मामलों में, programming बिलकुल architecture (भवन निर्माण की विद्या) की तरह है । क्या होगा यदि आप बिना किसी plan के घर बनाना शुरू कर दोगे । आप एक ऐसा घर बना लोगे, जिसमे कई खामियां होंगी: दीवारें सीधी नहीं बनी होंगी, छत से पानी टपकता होगा, आदि… बिलकुल इसी तरह, यदि आप बिना किसी plan के program लिखने बैठ जाओगे, तो बाद में आपको पता चलेगा की आपके program में कई खराबियाँ है, और इन खराबियों को सुधारने में आपका बहुत सारा समय बर्बाद हो रहा है, जबकि आप पहले से थोड़ा सोच-समझकर काम करते, तो इन सारी दिक्कतों से खुद को बचा सकते थे ।

Programs लिखने की लंबी दौड़ में आप पहले से थोड़ी planning कर अपना बहुत सारा समय बचा सकते हो, और बाद में खुद निराश होने से भी बच सकते हो ।

Step 1: Problem को पहले define करें

सबसे पहले आपको ये निश्चित करने की ज़रूरत है की आखिर आपका program किस तरह के problem को solve करने वाला है । बेहतर होगा, की आप इसे एक या दो lines में समझा सकें । उदाहरण के लिए:

  • मैं एक phonebook application लिखना चाहता/चाहती हूँ, जो मेरे friends के phone numbers को सुरक्षित रखेगा ।
  • मैं एक random dungeon generator बनाना चाहता/चाहती हूँ, जो हर बार अलग-अलग दिखने वाली गुफ़ाएँ generate करेगा ।
  • मैं एक ऐसा program लिखना चाहता/चाहती हूँ जो internet से stocks की जानकारी इकट्ठा कर ये अनुमान लगाने में सक्षम होगा, की किसे खरीदना सही है ।

ये step अभी तक आसान लग रहा होगा, यही सबसे ज्यादा ज़रूरी भी है । यहाँ पे आपसे सबसे बड़ी गलती ये हो सकती है, की आपका program आपको या आपके boss को जो चाहिए था, वो दे पाने में असफल हो जाय ।

Step 2: आपके tools, targets और backup plan को define करें

जब आप एक experienced programmer बन जाते हो, तब भी यहाँ से आपके पास कई ऐसे steps होंगे जिनके बारे में सोचना ज़रूरी है, जैसे:

  • आपके program को कौन use करने वाले हैं और वे क्या चाहते हैं, इस बात को अच्छी तरह से समझना ।
  • ये सुनिश्चित करना की आपके program का target architecture क्या होगा अर्थात आप किस तरह के computers या OS के लिए program design करने वाले हो ।
  • सुनिश्चित करना की आप program बनाते वक़्त किन tools का इस्तेमाल करने वाले हो ।
  • सुनिश्चित करना की आप अपना program कैसे बनाने वाले हो, अकेले या किसी team के साथ ।
  • कुछ चीजों को collect करना, जैसे एक ऐसा document, जहाँ आपका program क्या-क्या कर पायेगा, इसका एक list मौजूद हो ।
  • आपके program के लिए testing/feedback/release की रणनीति तैयार करना ।
  • सुनिश्चित करना की आप अपने code का backup कैसे बनाओगे ।

एक नए programmer के लिए इन सवालों का जवाब देना आसान होगा: आप अपने इस्तेमाल के लिए कोई program लिख रहे हो, वो भी अकेले आपके खुद के system में, एक IDE का प्रयोग करते हुए जिसे आपने download या purchase (खरीद) किया है । और साथ ही आपके program को आपके सिवा और कोई इस्तेमाल भी नहीं करने वाला है । ये सभी चीजें program से सम्बंधित ज़रूरतों को समझने में आसान बना देती है ।

लेकिन फिर भी, यदि आप कुछ बड़ा design करने जा रहे हो (जो काफी complex है), आपके पास code का backup रखने की एक strategy होनी चाहिए । इसे केवल zip करना या आपके machine के किसी दूसरे directory में copy कर लेना काफी नहीं है (फिर भी, ये कुछ नहीं से तो बेहतर है ) । इस परिस्थिति में यदि आपका system कभी crash कर गया, तो आपके अभी तक के मेहनत पर पानी फिर जायेगा । एक अच्छे backup strategy का मतलब है, आपके system और system के बाहर, आपके code की एक copy सुरक्षित रखना । इसे करने के कई तरीके हैं: जैसे code को अपने Email ID में खुद ही email करके store कर लेना, इसे Dropbox या किसी दूसरे cloud service में copy कर लेना, FTP की सहायता से इसे किसी दूसरे machine (आपके system से अलग) में store कर लेना या फिर इसे local network से connected किसी दूसरे machine में copy कर लेना ।

Step 3: मुश्किल problems को छोटे-छोटे आसान problems में तोड़ दें

वास्तविक जीवन में, हमें अकसर किसी काम को पूरा करना पड़ता है जो हमारे लिए काफी मुश्किल होता है । इन्हें कैसे पूरा करना है, इसे decide करना काफी चुनौतीपूर्ण हो सकता है । इन मामलों में, हम अकसर problem solving के लिए top down method का उपयोग करते हैं । इसका मतलब है, एक बहुत मुश्किल काम को पूरा करने के बजाय, इसे पहले tasks के कई टुकड़ों में बाँट देना, जिन्हें solve करना वाकई में आसान हो । यदि task के ये टुकड़े अब भी solve करने में आसान नहीं हैं, तो उन्हें और भी छोटे-छोटे भागों में बाँटा जा सकता है । मुश्किल tasks को लगातार छोटे और आसान tasks में बाँटने से, एक समय आप अपने code के साथ एक ऐसे जगह पे पहुंच जाओगे, जहाँ हर एक task बहुत आसान नहीं, तो कम से कम manage करने लायक ज़रूर बन जायेगा ।

आइये इसका एक उदाहरण देखते हैं । चलिए मान लेते हैं की हमे गाजर के ऊपर एक report तैयार करना है । हमारे task का structure शुरुआत में कुछ ऐसा होगा:

  • गाजर पर एक report तैयार करो

गाजर पर एक ही बार में एक report लिखकर तैयार करना सच में एक बड़ा task है, इसलिए चलिए हम इसे छोटे subtasks में बाँटते हैं:

  • गाजर पर एक report तैयार करो
    • गाजरों पर research (शोध) करो
    • outline (रूपरेखा) तैयार करो
    • इन outlines को अब गाजरों की विस्तृत जानकारियों से पूरा करो
    • अब इसमें एक विषय-सूची (table of contents) जोड़ो

हाँ, अब ये ज्यादा manageable है क्यूँकि हमारे पास main task को पूरा करने के लिए अब subtasks मौजूद हैं, जिनपर हम एक-एक कर के पूरा ध्यान लगा सकते हैं । लेकिंन अभी भी “गाजरों पर research (शोध) करो”, थोड़ा मुश्किल प्रतीत हो रहा है, इसलिए इसे भी subtasks में तोड़ा जा सकता है:

  • गाजर पर एक report तैयार करो
    • गाजरों पर research (शोध) करो
      • Library में जाकर गाजरों के बारे में लिखी गयी किताबें पढ़ो
      • Internet से गाजरों पर जानकारी इकट्ठा करो
      • जो सबसे ज्यादा ज़रूरी लगता है, उनपर notes तैयार कर लो
    • outline (रूपरेखा) तैयार करो
      • फसल के बढ़ने की जानकारी
      • आगे की प्रक्रियाओं की जानकारी
      • पोषण की जानकारी
    • इन outlines को अब गाजरों की विस्तृत जानकारियों से पूरा करो
    • अब इसमें एक विषय-सूची (table of contents) जोड़ो

अब हमारे पास tasks का एक structure है, जिनमे से कोई भी बहुत ज्यादा मुश्किल नहीं है । अब इनमे से एक-एक subtasks को पूरा कर हम गाजर पर report तैयार करने जैसा मुश्किल task भी पूरा कर सकते हैं ।

Hierarchy या task का अनुक्रम तैयार करने का एक और तरीका bottom up method है । इस method में, हम आसान कामों को सामूहिक रूप में पूरा करते हुए पूरे task की hierarchy तैयार कर लेते हैं ।

उदाहरण के लिए, साप्ताहिक दिनों में बहुत कोई school या किसी दूसरे काम के लिए कहीं-न-कहीं ज़रूर जाते हैं, इसलिए चलिए मान लेते हैं की हमें “बिस्तर से काम तक जाने के लिए तैयार हो जाओ” जैसे किसी problem को solve करना है । यदि आपसे ऐसे किसी problem को solve करने को कहा जाये, तो आप शायद कुछ ऐसा list तैयार करोगे:

  • कपडे चुनो
  • कपडे पहनो
  • नाश्ता करो
  • अब काम पर निकल जाओ
  • Brush करो
  • बिस्तर से उठो
  • नाश्ता तैयार करो
  • Car में बैठो
  • नहा लो

Bottom up method का प्रयोग कर, हम इन सभी tasks में से एक तरह के कामों की grouping कर इन्हें एक अनुक्रम में सजा सकते हैं:

  • बिस्तर से काम तक जाने के लिए तैयार हो जाओ
    • Bedroom से सम्बंधित काम
      • बिस्तर से उठ जाओ
      • कपडे चुन लो
    • Bathroom से सम्बंधित काम
      • नहा लो
      • Brush कर लो
    • नाश्ते से सम्बंधित काम
      • नाश्ता तैयार करो
      • नाश्ता कर लो
    • Transportation से सम्बंधित काम
      • Car में बैठो
      • अब काम पर निकल जाओ

ये task hierarchies (task के अनुक्रम) programming में काफी उपयोगी साबित हो सकते हैं । वो इसलिए क्यूँकि यदि एक बार आपने hierarchy तैयार कर लिया तो समझ लें की आपने लगभग पूरे program का structure define कर लिया । Top level task (जो की यहाँ पे, “गाजर पर एक report तैयार करो” या “बिस्तर से काम तक जाने के लिए तैयार हो जाओ” है), program का main() function बनेगा (क्यूँकि हमें mainly इसी task को पूरा करना है) । इसके अलावा, subtasks program के अन्य functions के रूप में define किये जाएँगे ।

यदि कहीं पे ऐसा लगता है की कोई sub-item (functions) अब भी बहुत ज्यादा complex (जटिल) है, तो आसानी से इसके और टुकड़े किये जा सकते हैं, अर्थात् इस program में और अधिक functions जोड़े जा सकते हैं। ऐसा करते हुए जल्द ही हम ऐसे जगह पे पहुँच जायेंगे जहाँ हमारे program के functions बहुत ही आसानी से लिखे जा सकते हैं ।

Step 4: Tasks को एक sequence में सजाएँ

अब जब आपके program का structure तैयार हो गया है, ये पता करने की ज़रूरत है की इन tasks को आपस में जोड़ा कैसे जाये । इसमें सबसे पहले subtasks के पूरे होने के sequence को पहचानना ज़रूरी है । अर्थात, ये जानना ज़रूरी है की किस क्रम में program problems को solve करेगा । उदाहरण के लिए, जब आप सुबह उठते हो, आप ऊपर दिए गए कामों को किस क्रम में करते हो ? इसका list कुछ ऐसा दिखेगा:

  • बिस्तर से उठो
  • कपड़े चुनो
  • नहा लो
  • कपड़े पहन लो
  • नाश्ता तैयार करो
  • नाश्ता कर लो
  • Brush करो
  • Car में बैठो
  • अब काम पर निकल जाओ

इसी तरह, यदि हमे calculator लिखना होता तो हम चीजों को कुछ इस तरह सजाते:

  • User से first number लो
  • User से mathematical operation (जोड़, घटाव, गुणा या भाग) पता करो
  • User से second number लो
  • Result calculate करो
  • Result print करो

यही list आगे चलकर ये बताएगा की आपके main() में क्या code लिखा जाना चाहिए:

या फिर calculator वाले case में:

Note कीजिये की यदि आप program को construct करने (बनाने) के लिए ऐसे किसी “outline (रूपरेखा) ” का प्रयोग करते हैं, तो codes लिखने तक के लिए code के जगहों पर comment out कर के रखना एक अच्छा उपाय है । और जब outline पूरा हो जाये, तो एक-एक कर के उनपर (tasks/functions पर) काम शुरू कीजिये । इस तरह से, compiler भी उनके define ना होने को लेकर कोई complain नहीं करेगा ।

Step 5: हर task के लिए data input और output को समझें

जब आपके पास एक hierarchy और tasks का sequence उपलब्ध है, अगला काम जो आप करने वाले हो, वो है ये पता करना की आपका हर एक task पूरा होने के लिए किन inputs की मांग करेगा और इनपर calculation कर क्या output प्रदान करेगा (यदि कोई output देना हो तो) । यदि पिछले step से आपके पास input data मौजूद है, तो अब ये input data इस task (function) के लिए parameter के रूप में काम करेगा । यदि आप किसी दूसरे function में इस्तेमाल करने के लिए मौजूदा task से data calculate कर रहे हैं, तो सामान्यतः वो इस task (function) का return value बनेगा ।

जब हमारा काम ख़त्म हो जाये, तो हमारे पास हर function का prototype होना चाहिए । यदि आप भूल गए हो, तो फिर से बताया जा रहा है: function prototype, किसी function का ऐसा declaration है जिसमे function का नाम, इसका return type और parameters तो होता है, पर इसमें function का definition नहीं लिखा जाता ।

आइये अब कुछ examples पर नज़र डालते हैं । getUserInput() बहुत ही आसान सा function है । हमलोग user से एक number लेने वाले हैं और इसे caller को return करने वाले हैं । इसलिए, function का prototype कुछ ऐसा दिखेगा:

Calculator वाले example में, function calculateResult() को 3 inputs लेने की ज़रूरत पड़ेगी: दो numbers और एक mathematical operator । हमारे पास इस function के call होने से पहले ही ये तीनों inputs मौजूद होने चाहिए, ताकि ये calculateResult() के parameters बन सके । calculateResult() function, result value तो ज़रूर calculate करेगा, पर इसे print नहीं करेगा । इसलिए, हमे इस value को return करना होगा ताकि कोई और function इसका इस्तेमाल कर सके ।

हम इसका function prototype कुछ इस प्रकार से लिख सकते हैं:

Step 6: Task के details को लिखें

इस step में, हर एक task के लिए आप इसका वास्तविक implementation (definition) लिखोगे । यदि आपने task को छोटे-छोटे भागों में अच्छी तरह से बाँटा है, तो यहाँ सबकुछ बहुत ही आसान लगने वाला है । यदि कोई task अब भी काफी complex लग रहा है, तो शायद इसे और छोटे भागों में (subtasks में) बाँटने की ज़रूरत है जिन्हें आसानी से implement किया जा सके ।

उदाहरण के लिए:

Step 7: Data inputs और outputs को आपस में connect करें

अब आख़री step में आप हर एक task के inputs और outputs को सही तरीके से आपस में connect करोगे । उदाहरण के लिए, आप calculateResult() के output (return value) को printResult() के input के रूप में इस्तेमाल करोगे (parameters के द्वारा), ताकि ये calculated answer को print कर सके । ऐसा करने के लिए आपको अकसर “intermediary variables” की ज़रूरत पड़ेगी जो अस्थाई रूप से results को store करके रखेगा ताकि ये एक से दूसरे function में pass किये जा सके । उदाहरण के लिए:

Code का ये version, temporary variables का इस्तेमाल न करने वाले version से काफी अच्छा और पढने लायक प्रतीत होता है:

ये step नए programmers के लिए सबसे मुश्किल step साबित हो सकता है ।

ऊपर दिया गया calculator program इसके सम्पूर्ण रूप में कुछ इस तरह से लिखा जायेगा । ध्यान दे की नीचे दिया गया example हमारे अभी तक देखे गये concepts से कुछ नया use कर रहा है, इसलिए इसका संक्षिप्त विवरण नीचे दिया गया है:

  • if statements आपको code की एक line execute करने की अनुमति देता है, यदि दिया गया condition true है तो
  • Operator == दिए गए दो items को compare कर ये पता लगाता है की क्या ये दोनों बराबर हैं

हमे मालूम है की आप अभी इन दोनों को ठीक से नहीं समझ पाओगे (हम इनके बारे में आगे के chapters में विस्तार से जानेंगे)। अभी के लिए, बस program के flow को जानने की कोशिश कीजिये, और ये समझने का प्रयास कीजिये की data, functions के बीच move कैसे करता है अर्थात् एक से दुसरे function तक कैसे पहुँचता है ।

Programs लिखने पर कुछ advice

अपने programs को शुरुआत में बिलकुल simple रखें । । अकसर, नये programmers एक ही बार में अपने program से बहुत कुछ करवाने की अपेक्षा रखते हैं । “मुझे graphics और sounds के साथ एक role-playing game बनाना है जिसमे randomly (यादृच्छिक रूप से) monsters (राक्षस/दैत्य) और dungeons (गुफाएँ) generate होंगे, जिसमे एक शहर भी होगा जहाँ आप (player) dungeons में मिलने वाले रत्नों को ले जाकर बेच सकेंगे” यदि आप शुरुआत से ही चीजों को इतना complex बना दोगे, तो आप कुछ ही समय बाद project को आगे ना बढ़ा पाने की वजह से निराश महसूस करने लगोगे । इसलिए, अपना पहला लक्ष्य जितना हो सके आसान रखिये, कुछ ऐसा जो आप वास्तव में कर सकते हो । उदाहरण के लिए, “मुझे screen पर केवल एक 2D field दिखाना है” ।

समय के साथ-साथ नए features जोड़ें । यदि आपका simple सा program ठीक से काम कर रहा है, तो अब आप इसमें नए features जोड़ सकते हो । उदाहरण के लिए, यदि आप screen पर program के द्वारा 2D field दिखाने में सफल हो गए, तो अब game में एक character add कीजिये जो field पर घूम सके । यदि आप ये कर पाए, तो अब field में कुछ दीवारें जोड़ दें जो आपके character के लिए बाधा उत्पन्न करे । यदि दीवारें बन गयीं हैं, तो इनका उपयोग कर एक साधारण सा शहर बनाये । यदि शहर बन गया है, तो अब इसमें कुछ व्यापारियों को जोड़े । यदि आप इसी तरह चीजों को थोड़ा- थोड़ा कर के जोड़ते जायेंगे, तो आपका program complex होता जायेगा और आपको इसका पता भी नहीं चलेगा ।

एक समय में केवल एक ही जगह पर ध्यान दे । सब कुछ एक ही बार में code कर लेने की कोशिश ना करें, और एक समय में एक से अधिक चीजों पर ध्यान देने की भी कोशिश ना करें । एक समय में केवल और केवल एक ही task पर ध्यान दें, और जितना हो सके इसी को समाप्त करने के बारे में सोंचे । एक task जिसका एक भाग पूरी तरह से काम करता हो पर 5 भागों में काम अभी भी शुरू ना हुआ हो, उस task से बेहतर है, जिसके सभी 6 भागों पर आधा-अधुरा काम किया गया हो । यदि आप अपना मन एक से अधिक कामों को पूरा करने में लगाओगे, तो जल्द ही गलतियाँ कर बैठोगे और साथ ही किसी task के ज़रूरी पहलुओं पर काम करना भूल जाओगे ।

आप जैसे-जैसे आगे बढ़ते हैं, लिखे गए code के हर एक हिस्से को test भी करते जाइये । नए programmers अकसर एक ही बार में पूरा program लिख कर बैठ जाते हैं । और ऐसा करने के बाद जब वे पूरे program को compile करते हैं, compiler उन्हें सैकड़ो errors देता है । ये न केवल डरावना है, बल्कि यदि आपका code काम नही कर पाया, तो इसके काम ना करने की वजह पता करना भी इस तरह की coding के कारण मुश्किल हो सकता है । इसलिए, सबसे पहले code का बस थोडा सा भाग लिखे और इसके तुरंत बाद इसे compile और test कर ले । यदि ये काम नहीं कर रहा, तो आपको जल्द ही पता चल जायेगा की आपने कहाँ गलती की है, और इस तरह से आप इसे आसानी से fix कर सकोगे । जब आप sure हो जाये की code अच्छी तरह से काम कर रहा है, code का थोड़ा और हिस्सा लिखना प्रारंभ करें और दोबारा इसी प्रक्रिया को दोहराएँ । इस तरह, हो सकता है की आपके code को पूरा लिखने में ज्यादा समय लग जाये, पर जब आप इसे पूरा कर लोगे, हर चीज़ अच्छी तरह से काम करेगी और आपको, program क्यों काम नहीं कर रहा है, इसका पता लगाने में लगभग इसका दोगुना समय खर्च नहीं करना पड़ेगा 🙂 ।

बहुत सारे नए programmers इन सभी suggestions और steps को छोटा करने की कोशिश करेंगे (क्यूंकि देखकर लगता है की इन सब के लिए तो बहुत ज्यादा काम करना पड़ जायेगा, या फिर शायद इसलिए क्यूंकि ये steps code लिखने जितना मजेदार नहीं हैं ) । लेकिन किसी बड़े project में, दिए गये steps को follow करना आपका बहुत सारा समय और श्रम बचा सकता है । पहले से थोडा plan कर के चलने से, आप बहुत जगहों पर code को debug करने के झंझट से बच सकते हो ।

अच्छी खबर ये है, की एक बार यदि आपको इन concepts के साथ code करना अच्छा लगने लगा, तो ये आपके nature का हिस्सा बन जायेंगे और कुछ ही समय बाद आप बिना इनके बारे में सोचे इन सभी rules को follow कर रहे होगे । और तो और, थोड़े इंतज़ार के बाद आप इतने काबिल हो जाओगे की आपको पूरे के पूरे functions लिखने के लिए भी पहले से किसी planning की ज़रूरत नहीं पड़ेगी ।

1.11 -- आपके program को Debug करना (stepping और breakpoints)
Index
1.10 -- Preprocessor और header guards पर एक नज़र

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter