2009-05-14 9 views
9

MATLAB में, आप कैसे बताते हैं कि एक चर को कोड में आउटपुट कहां मिल रहा है?MATLAB में कोई संख्या कहां से प्रिंट कर रही है यह निर्धारित करने के लिए?

मेरे पास MATLAB कोड की लगभग 10K लाइनें हैं जिनके बारे में 4 लोग काम कर रहे हैं। कहीं न कहीं, किसी विशिष्ट तरीका में एक MATLAB स्क्रिप्ट में एक चर फेंक दिया गया है:

foo 

दुर्भाग्य से, मैं नहीं जानता कि क्या चर उत्पादन हो रहा है। और आउटपुट अन्य महत्वपूर्ण आउटपुट को छेड़छाड़ कर रहा है।

कोई विचार?

पेज। किसी ने कभी भी standard.out ओवरराइट करने का प्रयास किया? चूंकि MATLAB और जावा एकीकरण इतना तंग है, क्या यह काम करेगा? इस समस्या का सामना करते समय जावा में एक चाल का उपयोग किया गया है जो मेरे अपने संस्करण के साथ standard.out को प्रतिस्थापित करना है।

+0

ओह, मुझे इससे नफरत है। मेरी इच्छा है कि जब भी इसे अर्धविराम के बिना बयानों का सामना करना पड़ता है तो त्रुटि को फेंकने के लिए MATLAB में वैश्विक सेटिंग होना संभव था। –

+0

यह disp (str2num (FOO)) होने के समाप्त हो गया; कोड में गहरी गड़बड़ी हुई। चाल यह महसूस कर रही थी कि आउटपुट एक ही समय था, सभी 200 गीगा डेटा फ़ाइलों के माध्यम से खोज रहा था, और उस मूल्य को ढूंढ रहा था। यह पता लगाने के लिए कि आंतरिक चर में वह मान था, और फिर उस मान के साथ कोड में प्रत्येक संदर्भ को ट्रैक करना। प्रस्तावित दृष्टिकोणों का उपयोग करने के लिए बहुत सी लिंट त्रुटियों के साथ कोड की बहुत सारी पंक्तियां। धन्यवाद!!!! – John

+0

हां, लेकिन ओवरलोडिंग डिस्प्ले की मेरी चाल जल्दी से काम करेगी। –

उत्तर

7

ओह, मुझे यह भी नफरत है। मेरी इच्छा है कि मैटलैब को "डिस्प्ले अगर डिस्प्ले" था तो बिल्कुल इस पर रुकने के लिए।

Weiyin से mlint traversal एक अच्छा विचार है। Mlint गतिशील कोड नहीं देख सकता है, हालांकि, जैसे eval() या स्ट्रिंग-मूल्यवान आकृति हैंडल कॉलबैक के तर्क। मैंने इस तरह के कॉलबैक में इस तरह के आउटपुट में भाग लिया है, जहां update_table() कुछ स्थितियों में कुछ देता है।

uicontrol('Style','pushbutton', 'Callback','update_table') 

आप कर सकते हैं "बतख-पंच" करने के लिए एक विधि में निर्मित प्रकार आप dbstop के लिए एक हुक देने के लिए। अपने Matlab पथ पर एक निर्देशिका में, "@double" नाम की एक नई निर्देशिका बनाएं, और इस तरह @ डबल/display.m फ़ाइल बनाएं।

function display(varargin) 
builtin('display', varargin{:}); 

तो फिर तुम

dbstop in double/display at 2 

करते हैं और अपने कोड चला सकते हैं। अब जब भी डिस्प्ले को डायनामिक कोड से छोड़ा जाता है, तो डिस्प्ले को पूरी तरह से छोड़ा जाता है, जिसमें डायनामिक कोड भी शामिल होता है। इसे @ डबल के लिए करने से चार और कोशिकाओं को भी शामिल किया जाता है। यदि यह एक अलग प्रकार प्रदर्शित किया जा रहा है, तो आपको प्रयोग करना पड़ सकता है।

आप शायद अंतर्निहित डिस्प() को उसी तरह ओवरराइड कर सकते हैं। मुझे लगता है कि यह Java की System.out स्ट्रीम के लिए कस्टम प्रतिस्थापन के समान होगा।

कहने की जरूरत नहीं है, अंतर्निहित प्रकारों के तरीकों को जोड़ना गैर मानक, असमर्थित, बहुत त्रुटि-प्रवण है, और कुछ डीबगिंग सत्र के बाहर बहुत सावधान रहना है।

3

आप इस तरह के रूप में एक लाइन है, तो:

foo = 2 

और कोई "," अंत पर है, तो उत्पादन चर नाम सबसे पहले प्रकट होता के साथ स्क्रीन को फेंक दिया हो जाएगा:

foo = 

    2 

इस मामले में, आप स्ट्रिंग के लिए फ़ाइल खोज करनी चाहिए "foo =" और लाइन याद आ रही खोजने के लिए एक " , "।

यदि आप कोई परिवर्तनीय नाम दिखाई देने वाले आउटपुट को देख रहे हैं, तो आउटपुट शायद DISP या FPRINTF फ़ंक्शन का उपयोग कर स्क्रीन पर डाला जा रहा है। "Disp" या "fprintf" के लिए फ़ाइल को खोजना आपको यह पता लगाने में मदद करेगा कि डेटा कहां प्रदर्शित किया जा रहा है।

यदि आप परिवर्तनीय नाम "ans" के साथ आउटपुट देख रहे हैं, तो यह एक ऐसा मामला है जब एक गणना की जा रही है, एक चर में नहीं रखा जा रहा है, और एक ';' गायब है पंक्ति के अंत में, इस तरह के रूप में:

size(foo) 

सामान्य तौर पर, यह है कि क्या जहां इन खोजने के लिए कोड में हो रहा है, के बाद से (के रूप में आप बाहर पाया है) यह कठिन हो सकता है प्रदर्शित करने के लिए एक बुरी बात है कोड के एक बड़े टुकड़े में रखा गया है। इस मामले में, अपमानजनक रेखा को ढूंढने का सबसे आसान तरीका MLINT का उपयोग करना है, जैसा कि अन्य उत्तरों ने सुझाव दिया है।

5

यह एक विशिष्ट पैटर्न mLint में मदद मिलेगी आप पाते है:

alt text

तो, नारंगी लाइनों के लिए संपादक के दाहिने हाथ की ओर देखो। यह आपको न केवल इस अनुकूलन को खोजने में मदद करेगा, लेकिन कई और भी बहुत कुछ। ध्यान दें कि आपका परिवर्तनीय नाम हाइलाइट किया गया है।

+0

+1: एमआईएलटीटी लापता ';' के लिए अच्छी तरह से काम करता है, लेकिन मुझे लगता है कि अगर कोई गलती डीआईएसपी समस्या थी तो इससे मदद नहीं मिलेगी। – gnovice

0

आपको अपनी सभी एम-फाइलों को पार करने की आवश्यकता होगी (शायद एक रिकर्सिव फ़ंक्शन या यूनिक्स ('find -type f -iname * .m') का उपयोग करना होगा)। प्रत्येक फ़ाइल नाम पर कॉल mlint:

r = mlint(filename); 

आर संदेश क्षेत्र के साथ एक (संभावित रूप से खाली) संरचना होगी। संदेश को ढूंढें जो "आउटपुट दबाने के लिए सेमीकॉलन के साथ टर्मिनेट स्टेटमेंट" से शुरू होता है।

1

आप एक समारोह के रूप में mlint चला सकते हैं और परिणामों की व्याख्या कर सकते हैं।

>> I = mlint('filename','-struct'); 
>> isErrorMessage = arrayfun(@(S)strcmp(S.message,... 
     'Terminate statement with semicolon to suppress output (in functions).'),I); 
>>I(isErrorMessage).line 

यह केवल कि एकल फाइल में लापता अर्धविराम मिल जाएगा। तो इसे फ़ाइलों (कार्यों) की एक सूची पर चलाना होगा जिन्हें कुछ मुख्य कार्यों से बुलाया जाता है।

यदि आप disp() या fprintf() पर कॉल ढूंढना चाहते हैं तो आपको फ़ाइल के पाठ में पढ़ना होगा और कॉल खोजने के लिए नियमित रूप से एक्सप्रेशन का उपयोग करना होगा।

नोट: यदि आप किसी फ़ंक्शन के बजाय स्क्रिप्ट का उपयोग कर रहे हैं तो आपको उपरोक्त संदेश को पढ़ने के लिए बदलने की आवश्यकता होगी: 'आउटपुट को दबाएं (स्क्रिप्ट में) को अर्धविराम के साथ समाप्त करें।'

3

मुझे "डीबीस्टॉप अगर डिस्प्ले" का विचार पसंद है, हालांकि यह एक डीबीस्टॉप विकल्प नहीं है जिसे मैं जानता हूं।

यदि अन्य सभी विफल हो जाते हैं, तो अभी भी उम्मीद है। मलिंट एक अच्छा विचार है, लेकिन यदि हजारों लाइनें और कई कार्य हैं, तो आप अपराधी को कभी नहीं ढूंढ सकते हैं। इससे भी बदतर, यदि यह कोड ढीला लिखा गया है, तो दिखाई देने वाले ज़िल्ट झंडे के ज़िलियन होंगे। आप इसे कैसे सीमित करेंगे?

एक समाधान वहां अपना रास्ता प्रदर्शित करना है। मैं प्रदर्शन समारोह अधिभारित होगा। केवल अस्थायी रूप से, लेकिन यह काम करेगा। उत्पादन

ans = 
     stuff 

के रूप में या

foo = 
     stuff 

तब के रूप में कमांड लाइन करने के लिए छोड़ दिया जा रहा है तो यह प्रदर्शन के साथ बाहर लिखा गया है। यदि यह

stuff 

के बाद बाहर आ रहा है तो disp अपराधी है। इससे क्या फर्क पड़ता है? अपराधी को अधिभारित करें।अपने MATLAB खोज पथ के शीर्ष पर स्थित कुछ निर्देशिका में एक नई निर्देशिका बनाएं, जिसे @double कहा जाता है (यह मानते हुए कि आउटपुट एक डबल चर है। यदि यह चरित्र है, तो आपको एक @char निर्देशिका की आवश्यकता होगी।) @ MATLAB खोज पथ पर स्वयं डबल निर्देशिका, बस इसे अपने पथ पर कुछ निर्देशिका में डालें।

इस निर्देशिका के अंदर, कमांड लाइन आउटपुट करने के आपके निर्धारण के आधार पर, disp.m या display.m नामक एक नई एम-फाइल डालें। एम-फाइल की सामग्री बिल्टिन फ़ंक्शन पर कॉल होगी, जो आपको इनपुट पर डिस्प या डिस्प्ले के बिल्टिन संस्करण को कॉल करने की अनुमति देगी।

अब, नए फ़ंक्शन के अंदर एक डिबगिंग बिंदु सेट करें। स्क्रीन पर हर बार आउटपुट उत्पन्न होता है, यह फ़ंक्शन कॉल किया जाएगा। यदि कई घटनाएं हैं, तो आपको डीबगर का उपयोग करने की आवश्यकता हो सकती है ताकि प्रजनन को फंसे होने तक प्रसंस्करण की अनुमति दी जा सके। आखिरकार, यह प्रक्रिया आक्रामक रेखा को फंस जाएगी। याद रखें, आप डीबगर में हैं! यह निर्धारित करने के लिए डीबगर का प्रयोग करें कि कौन सा फ़ंक्शन डिस्प और कहां कहलाता है। आप विवाद या प्रदर्शन से बाहर निकल सकते हैं, या यह देखने के लिए कि क्या हुआ है, बस डीबीस्टैक की सामग्री देखें।

जब सब कुछ किया जाता है और समस्या की मरम्मत की जाती है, तो इस अतिरिक्त निर्देशिका को हटाएं, और आपके द्वारा डाले गए डिस्प/डिस्प्ले फ़ंक्शन को हटा दें।

1

एंड्रयू Janke के अधिक भार एक बहुत ही उपयोगी टिप है केवल दूसरी बात यह बजाय dbstop का उपयोग कर मैं निम्नलिखित बेहतर काम करता है, सरल कारण यह है कि display.m में रोक लगाने को रोकने के लिए निष्पादन का कारण होगा, हर बार प्रदर्शन के लिए लगता है की है एमएम कहा जाता है, भले ही कुछ भी लिखा न हो।

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

function display(varargin) 
builtin('display', varargin{:}); 
if isempty(varargin{1})==0 
keyboard 
end 
1

एक ऐसी चीजों का पता लगाने का मूर्ख तरीका आउटपुट को देखते हुए डीबगर में कोड के माध्यम से क्रमशः कदम उठाना है। यह निम्नानुसार आगे बढ़ेगा:

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

हालांकि दर्द होने पर, आपको लाइन को अपेक्षाकृत तेज़ी से तब तक मिल जाएगा जब तक आपके पास बड़े कार्य/स्क्रिप्ट नहीं होते हैं, जो कि वैसे भी खराब अभ्यास है। यदि स्क्रिप्ट इस तरह हैं तो आप फ़ंक्शन में लाइन को उसी तरह से ढूंढने के लिए विभाजन प्रकार का उपयोग कर सकते हैं। इसमें शुरुआत में एक ब्रेक प्वाइंट डालने में शामिल होगा, फिर एक आधे रास्ते और ध्यान दें कि फ़ंक्शन का कौन सा आधा उत्पादन उत्पन्न करता है, फिर लाइन को तब तक घुमाता है जब तक कि लाइन स्थित न हो जाए।

1

मुझे यह समस्या बहुत छोटी कोड के साथ थी और यह एक बगजर है, भले ही ओपी को अपना समाधान मिला, मैं एक छोटी सी धोखा पोस्ट करूंगा जिसे मैंने सीखा।

1) Matlab कमांड प्रॉम्प्ट में, 'अधिक' चालू करें।

more on 

2) खिड़की के प्रॉम्प्ट-वाई/टर्मिनल-वाई भाग को ऊंचाई में टेक्स्ट की केवल पंक्ति में बदलें।

3) कोड चलाएं। इसे मुद्रित करने के लिए जहां भी इसे मुद्रित करने की आवश्यकता होगी, क्योंकि इसे प्रिंट करने की जगह नहीं है (अधिक [स्पेस] या [डाउन] प्रेस पर अवरुद्ध हो रहा है)।

4) अपने प्रोग्राम को उस स्थान पर मारने के लिए [ctrl] - [सी] दबाएं जहां यह प्रिंट नहीं कर सका।

5) अपने प्रॉम्प्ट-वाई क्षेत्र को सामान्य आकार में वापस करें। ट्रेस के शीर्ष से शुरू करना, लाल टेक्स्ट में क्लिक करने योग्य बिट्स पर क्लिक करें। ये आपके संभावित अपराधी हैं। (बेशक, आपको उन हिस्सों को पार करने के लिए [डाउन] इत्यादि दबाए जाने की आवश्यकता हो सकती है जहां कोड वास्तव में चीजों को मुद्रित करने का इरादा था।)

संबंधित मुद्दे