कस्टम ब्लॉक: स्टाइल गाइड

पिछले कुछ सालों में, ब्लॉकली और ब्लॉकली गेम टीम ने बहुत से सबक सीखे हैं. ये सबक नए ब्लॉक बनाने वालों पर लागू होते हैं. नीचे हमारी गलतियों या आम तौर पर दूसरों से की गई गलतियों का कलेक्शन है.

ये सामान्य सबक हैं जिन्हें हमने Blockly की विज़ुअल स्टाइल का इस्तेमाल करके सीखा है. ऐसा हो सकता है कि ये सभी डिज़ाइन या इस्तेमाल के उदाहरणों पर लागू न हों. अन्य समाधान मौजूद हैं. यह उपयोगकर्ताओं को होने वाली समस्याओं और उनसे बचने के तरीकों की पूरी सूची नहीं है. हर मामला थोड़ा अलग होता है और उसके अपने-आप में उतार-चढ़ाव होते हैं.

1. कंडीशनल बनाम लूप

नए उपयोगकर्ताओं के लिए सबसे मुश्किल ब्लॉक, कंडिशनल और लूप हैं. कई ब्लॉक-आधारित एनवायरमेंट, इन दोनों ब्लॉक को एक ही 'कंट्रोल' कैटगरी में ग्रुप करते हैं, जहां दोनों ब्लॉक का आकार और एक ही रंग होता है. इससे अक्सर उन्हें निराशा होती है, क्योंकि नए उपयोगकर्ता इन दोनों ब्लॉक के बीच भ्रम की स्थिति पैदा करते हैं. ब्लॉक रूप से, कंडिशनल और लूप को अलग-अलग 'तर्क' और 'लूप' कैटगरी में ले जाने का सुझाव दिया जाता है. इन हर कैटगरी का रंग अलग होना चाहिए. इससे यह साफ़ हो जाता है कि ये ऐसे अलग-अलग आइडिया हैं जो एक जैसे आकार होने के बावजूद, अलग तरह से व्यवहार करते हैं.

सुझाव: कंडिशनल और लूप को अलग-अलग रखें.

2. एक-आधारित सूचियां

नौसिखिए प्रोग्रामर को पहली बार शून्य-आधारित सूचियों का सामना करना पड़ता है, लेकिन उनकी प्रतिक्रिया बहुत खराब होती है. नतीजतन, ब्लॉकली एक के हिसाब से सूची और स्ट्रिंग इंडेक्स करके लुआ और लंबा मू के लीडर का पीछा करता है.

Blockly के बेहतर इस्तेमाल के लिए, शून्य पर आधारित सूचियों की मदद से, टेक्स्ट में ट्रांज़िशन करना आसान हो जाता है. कम उम्र या ज़्यादा नई ऑडियंस को, एक-आधारित इंडेक्स करने का सुझाव अब भी दिया जाता है.

सुझाव: एक पहला नंबर है.

3. उपयोगकर्ता के इनपुट

उपयोगकर्ता से पैरामीटर पाने के तीन तरीके हैं. ड्रॉपडाउन सबसे ज़्यादा पाबंदी वाला होता है. यह आसान ट्यूटोरियल और प्रैक्टिस के लिए अच्छा होता है. इनपुट फ़ील्ड से ज़्यादा आज़ादी मिलती है और यह ज़्यादा क्रिएटिव गतिविधियों के लिए भी अच्छा है. वैल्यू ब्लॉक इनपुट (आम तौर पर शैडो ब्लॉक के साथ) सिर्फ़ एक स्टैटिक वैल्यू होने के बजाय वैल्यू (जैसे, रैंडम जनरेटर) का आकलन कर सकता है.

सुझाव: इनपुट का ऐसा तरीका चुनें जो आपके उपयोगकर्ताओं के हिसाब से सही हो.

4. लाइव ब्लॉक इमेज

ब्लॉक से जुड़े दस्तावेज़ में उन ब्लॉक की इमेज होनी चाहिए जिनके बारे में बताया जा रहा है. स्क्रीनशॉट लेना आसान है. हालांकि, अगर ऐसी 50 इमेज हैं और ऐप्लिकेशन का 50 भाषाओं में अनुवाद किया जाता है, तो अचानक एक इमेज में 2,500 स्टैटिक इमेज दिखने लगती हैं. फिर कलर स्कीम बदल जाती है और 2,500 इमेज को अपडेट करना होगा -- फिर से.

रखरखाव के इस बुरे सपने से खुद को जानने के लिए, Blockly Games ने सभी स्क्रीनशॉट की जगह ब्लॉकली को रीड-ओनली मोड में चलने वाले मोड से कर दिया. नतीजा किसी तस्वीर की तरह दिखता है, लेकिन इसके अप-टू-डेट होने की गारंटी होती है. रीड-ओनली मोड ने अंतरराष्ट्रीयकरण को संभव बना दिया है.

सुझाव: अगर एक से ज़्यादा भाषाओं में ऐप्लिकेशन उपलब्ध है, तो रीड ओनली मोड का इस्तेमाल करें.

5. बाईं ओर मौजूद

अमेरिका में बच्चों के फ़ीडबैक (हालांकि दिलचस्प दूसरे देशों के सुझाव नहीं) से, बाएँ और दाएँ के बीच का भ्रम साफ़ तौर पर पता चला. ऐरो जोड़कर इस समस्या को हल कर दिया गया. अगर दिशा मिलती-जुलती है (उदाहरण के लिए, अवतार के लिए), तो ऐरो की स्टाइल अहम है. A → स्ट्रेट ऐरो या ↱ तीर के निशान से भ्रम की स्थिति बन जाती है जब अवतार का चेहरा बिलकुल उलटा होता है. ⟳ गोलाकार ऐरो है, भले ही कोण का ऐंगल, ऐरो के संकेत से छोटा हो.

सुझाव: जहां तक हो सके, टेक्स्ट के साथ यूनिकोड आइकॉन का इस्तेमाल करें.

6. हाई-लेवल ब्लॉक

जहां भी संभव हो, उच्च-स्तरीय तरीका अपनाया जाना चाहिए, भले ही इससे एक्ज़िक्यूशन परफ़ॉर्मेंस या सुविधा में कमी आती हो. इस 'Apps स्क्रिप्ट एक्सप्रेशन' पर विचार करें:

SpreadsheetApp.getActiveSheet().getDataRange().getValues()

सभी संभावित क्षमताओं को बनाए रखने वाली 1:1 मैपिंग के तहत, ऊपर दिए गए एक्सप्रेशन को चार ब्लॉक का इस्तेमाल करके बनाया जाएगा. हालांकि, ब्लॉकली का मकसद हाई-लेवल वाला एक ब्लॉक देना है. यह ब्लॉक पूरे एक्सप्रेशन को शामिल करता है. लक्ष्य 95% मामले के लिए ऑप्टिमाइज़ करना है, भले ही, बाकी 5% मामलों को इससे ज़्यादा मुश्किल हो. ब्लॉकली को टेक्स्ट पर आधारित भाषाओं की जगह इस्तेमाल करने के लिए नहीं बनाया गया है. इसका मकसद उपयोगकर्ताओं को शुरुआत में सीखने की प्रक्रिया से गुज़रना है, ताकि वे टेक्स्ट पर आधारित भाषाओं का इस्तेमाल कर सकें.

सुझाव: अपने पूरे एपीआई को आंखों की रोशनी से ब्लॉक में न बदलें.

7. प्रॉडक्ट लौटाने के लिए वैकल्पिक वैल्यू

टेक्स्ट आधारित प्रोग्रामिंग में कई फ़ंक्शन, कोई कार्रवाई करते हैं, फिर कोई वैल्यू देते हैं. इस रिटर्न वैल्यू का इस्तेमाल किया जा सकता है या नहीं भी किया जा सकता. उदाहरण के लिए, स्टैक का pop() फ़ंक्शन. आखिरी एलिमेंट को पाने या हटाने के लिए पॉप का इस्तेमाल किया जा सकता है या सिर्फ़ रिटर्न वैल्यू वाले आखिरी एलिमेंट को हटाने के लिए भी पॉप का इस्तेमाल किया जा सकता है.

var last = stack.pop();  // Get and remove last element.
stack.pop();  // Just remove last element.

ब्लॉक आधारित भाषाएं, आम तौर पर रिटर्न वैल्यू को अनदेखा करने में अच्छी नहीं होतीं. वैल्यू ब्लॉक में कोई ऐसी चीज़ प्लग इन की जानी चाहिए जो वैल्यू को स्वीकार करती हो. इस समस्या से निपटने के लिए कई रणनीतियां हैं.

a) समस्या पर ध्यान दें. ऐसे मामलों से बचने के लिए ज़्यादातर ब्लॉक-आधारित भाषाएं ऐसी भाषा डिज़ाइन करती हैं. उदाहरण के लिए, स्क्रैच में ऐसा कोई ब्लॉक नहीं होता है जिस पर खराब असर और रिटर्न वैल्यू, दोनों हों.

b) दो ब्लॉक दें. अगर टूलबॉक्स में स्पेस देना ज़रूरी नहीं है, तो हर तरह के ब्लॉक में से दो ब्लॉक देना एक आसान तरीका है. पहला, बिना रिटर्न वैल्यू के और दूसरा ब्लॉक के साथ. समस्या यह है कि इससे भ्रम की स्थिति पैदा करने वाला ऐसा टूलबॉक्स हो सकता है जिसमें करीब एक जैसे ब्लॉक होते हैं.

c) एक ब्लॉक को बदलें. ड्रॉपडाउन, चेकबॉक्स या दूसरे कंट्रोल का इस्तेमाल करें, ताकि उपयोगकर्ता यह चुन सकें कि रिटर्न वैल्यू दी जाए या नहीं. ब्लॉक फिर अपने विकल्पों के आधार पर अपना आकार बदलता है. इसका एक उदाहरण, Blockly की लिस्ट ऐक्सेस ब्लॉक में देखा जा सकता है.

d) मूल्य का लाभ उठाएं. App Inventor के पहले वर्शन ने एक विशेष पाइप ब्लॉक बनाया जो कनेक्ट किए गए सभी मान का इस्तेमाल करता था. उपयोगकर्ताओं को यह सिद्धांत समझ नहीं आया. इस वजह से, App Inventor के दूसरे वर्शन ने पाइप ब्लॉक को हटा दिया. इसके बजाय, उपयोगकर्ताओं को सिर्फ़ थ्रोअवे वैरिएबल को वैल्यू असाइन करने का सुझाव दिया गया.

सुझाव: हर रणनीति के अपने फ़ायदे और नुकसान हैं. चुनें कि आपके उपयोगकर्ताओं के लिए क्या सही है.

8. ग्रोइंग ब्लॉक

कुछ ब्लॉक के लिए, इनपुट की अलग-अलग संख्या की ज़रूरत हो सकती है. उदाहरण के लिए, एक ऐसा अतिरिक्त ब्लॉक है जो संख्याओं के आर्बिट्रेरी सेट का योग करता है या if/elseif/else ऐसे ब्लॉक का इस्तेमाल करता है जिसमें एल्सीरीफ़ क्लॉज़ का कोई आर्बिट्रेरी सेट है या ऐसा सूची कंस्ट्रक्टर है जिसमें शुरुआत करने वाले एलिमेंट की आर्बिट्रेरी संख्या है. ऐसी कई रणनीतियां हैं जिनके अपने अपने फ़ायदे और नुकसान हैं.

a) सबसे आसान तरीका यह है कि उपयोगकर्ता छोटे-छोटे ब्लॉक में से ब्लॉक को भी बनाए. इसका एक उदाहरण, दो संख्याओं को जोड़ने वाले दो ब्लॉक को नेस्ट करके तीन संख्याएं जोड़ना है. दूसरा उदाहरण सिर्फ़ if/else ब्लॉक की जानकारी देना और उपयोगकर्ता को दूसरा तरीका बनाने के लिए उन्हें नेस्ट करना होगा.

इस तरीके का फ़ायदा यह है कि इसे आसानी से इस्तेमाल किया जा सकता है (उपयोगकर्ता और डेवलपर, दोनों के लिए). इसका नुकसान यह है कि बड़ी संख्या में नेस्टिंग होने पर, कोड बहुत जटिल हो जाता है. साथ ही, उपयोगकर्ता के लिए इसे पढ़ना और उसका रखरखाव करना मुश्किल हो जाता है.

b) एक विकल्प यह है कि ब्लॉक को डाइनैमिक तरीके से बड़ा किया जाए, ताकि आखिर में एक फ़्री इनपुट रहे. इसी तरह, अगर आखिरी इनपुट में दो फ़्री इनपुट हैं, तो ब्लॉक आखिरी इनपुट को मिटा देता है. ऐप्लिकेशन इन्वेंटर के पहले वर्शन ने इस तरीके का इस्तेमाल किया.

ऐप्लिकेशन इन्वेंटर के उपयोगकर्ताओं ने अपने-आप बढ़ने वाले ब्लॉक को कुछ वजहों से नापसंद किया. पहला, इनपुट हमेशा मुफ़्त था और प्रोग्राम कभी भी 'पूरा नहीं हुआ' था. दूसरा, स्टैक के बीच में कोई एलिमेंट शामिल करना निराशाजनक था, क्योंकि इसमें बदलाव के नीचे मौजूद सभी एलिमेंट को डिसकनेक्ट करना और उन्हें फिर से कनेक्ट करना शामिल था. हालांकि, अगर क्रम ज़रूरी नहीं है और उपयोगकर्ताओं को उनके प्रोग्राम में मौजूद कमियों के साथ सहज बनाया जा सकता है, तो यह एक बहुत ही सुविधाजनक विकल्प है.

c) इस छेद की समस्या को हल करने के लिए, कुछ डेवलपर +/- बटन जोड़ देते हैं, ताकि वे मैन्युअल रूप से इनपुट जोड़ या हटा सकें. ओपन रॉबर्टा नीचे से इनपुट जोड़ने या निकालने के लिए ऐसे दो बटनों का उपयोग करती है. दूसरे डेवलपर हर पंक्ति में दो बटन जोड़ते हैं, ताकि स्टैक के बीच से शामिल करने और मिटाने की सुविधा मिल सके. दूसरे लोग हर पंक्ति पर दो अप/डाउन बटन जोड़ते हैं, ताकि स्टैक को फिर से क्रम में लगाया जा सके.

यह रणनीति, विकल्पों का एक रेंज है. इसमें हर ब्लॉक के लिए सिर्फ़ दो बटन से लेकर, हर पंक्ति में चार बटन शामिल होते हैं. एक तरफ़ यह खतरा है कि उपयोगकर्ता अपनी ज़रूरी कार्रवाइयां नहीं कर पा रहे हैं, जबकि दूसरी तरफ़ यूज़र इंटरफ़ेस (यूआई) इतने बटन से भरा हुआ है कि यह स्टारशिप एंटरप्राइज़ के ब्रिज की तरह लगता है.

d) सबसे सुविधाजनक तरीका है ब्लॉक में म्यूटेटर बबल जोड़ना. इसे एक बटन के रूप में दिखाया जाता है, जो उस ब्लॉक का कॉन्फ़िगरेशन डायलॉग खोलता है. अपनी मर्ज़ी से एलिमेंट जोड़े, मिटाए या फिर से व्यवस्थित किए जा सकते हैं.

इस तरीके का नुकसान यह है कि इसमें म्यूटेटर, नए उपयोगकर्ताओं के लिए सहज नहीं हैं. पेश है म्यूटेटर को शुरू करने के लिए किसी तरह के निर्देश की ज़रूरत होती है. छोटे बच्चों को टारगेट करने वाले, ब्लॉक किए गए ऐप्लिकेशन में म्यूटेटर का इस्तेमाल नहीं किया जाना चाहिए. हालांकि, एक बार सीख लेने के बाद, जानकार उपयोगकर्ताओं के लिए ये अनमोल हैं.

सुझाव: हर रणनीति के अपने फ़ायदे और नुकसान हैं. चुनें कि आपके उपयोगकर्ताओं के लिए क्या सही है.

9. कोड जनरेट करना हटाएं

Advanced Blockly उपयोगकर्ता, जनरेट किए गए कोड (JavaScript, Python, PHP, Lua, Dart वगैरह) को देख सकें और उनके लिखे प्रोग्राम को तुरंत पहचान सकें. इसका मतलब है कि मशीन से जनरेट किए गए कोड को पढ़ने लायक बनाए रखने के लिए ज़्यादा कोशिश करनी होगी. शानदार ब्रैकेट, न्यूमेरिक वैरिएबल, क्रश्ड व्हाइटस्पेस, और वर्बोस कोड टेंप्लेट की मदद से शानदार कोड बनाए जा सकते हैं. जनरेट किए गए कोड में टिप्पणियां शामिल होनी चाहिए. साथ ही, वह Google की स्टाइल गाइड के मुताबिक होना चाहिए.

सुझाव: जनरेट किए गए कोड पर गर्व करें. इसे उपयोगकर्ता को दिखाएं.

10. भाषा की निर्भरता

क्लीन कोड की ज़रूरत का एक खराब असर यह होता है कि ब्लॉकली के व्यवहार को काफ़ी हद तक इस बात से समझा जा सकता है कि क्रॉस-कंपाइल की गई भाषा कैसे काम करती है. सबसे ज़्यादा इस्तेमाल होने वाली आउटपुट भाषा JavaScript है, लेकिन अगर Blockly को किसी दूसरी भाषा में क्रॉस-कंपाइल किया जाता है, तो दोनों भाषाओं के लिए सटीक व्यवहार को बनाए रखने की ग़ैर-ज़रूरी कोशिश नहीं करनी चाहिए. उदाहरण के लिए, JavaScript में एक खाली स्ट्रिंग 'गलत' है, जबकि लुआ में यह सही है. ब्लॉकली के कोड के लिए व्यवहार का एक ही पैटर्न तय करने से, टारगेट भाषा पर ध्यान दिए बिना पूरा नहीं होने वाला कोड मिल सकता है. ऐसा लगता है कि यह GWT कंपाइलर से मिला है.

सुझाव: ब्लॉकली कोई भाषा नहीं है, मौजूदा भाषा को अपने व्यवहार पर असर डालने दें.