एक लाइन के कार्यों से बनी डेटा मूंगिंग पाइपलाइन के लिए यूनिट परीक्षण


10

मैरी रोज कुक की व्यावहारिक क्रियाशीलता का व्यावहारिक परिचय पढ़ना , वह एक विरोधी पैटर्न का एक उदाहरण देता है

def format_bands(bands):
    for band in bands:
        band['country'] = 'Canada'
        band['name'] = band['name'].replace('.', '')
        band['name'] = band['name'].title()

जबसे

  • फ़ंक्शन एक से अधिक कार्य करता है
  • नाम वर्णनात्मक नहीं है
  • इसके दुष्प्रभाव हैं

एक प्रस्तावित समाधान के रूप में, वह अनाम कार्यों को पाइपलाइन करने का सुझाव देती है

pipeline_each(bands, [call(lambda x: 'Canada', 'country'),
                      call(lambda x: x.replace('.', ''), 'name'),
                      call(str.title, 'name')])

हालांकि यह मुझे कम परीक्षण योग्य होने का नकारात्मक पक्ष लगता है; कम से कम format_bands में यह जांचने के लिए एक इकाई परीक्षण हो सकता है कि यह क्या करता है, लेकिन पाइपलाइन का परीक्षण कैसे किया जाता है? या यह विचार है कि अनाम कार्य इतने आत्म-व्याख्यात्मक हैं कि उन्हें परीक्षण करने की आवश्यकता नहीं है?

इसके लिए मेरा वास्तविक विश्व अनुप्रयोग मेरे pandasकोड को अधिक कार्यात्मक बनाने की कोशिश में है। मैं अक्सर "मुंगिंग" फंक्शन के अंदर किसी न किसी तरह की पाइपलाइन लगाता हूँ

def munge_data(df)
     df['name'] = df['name'].str.lower()
     df = df.drop_duplicates()
     return df

या पाइपलाइन शैली में पुनर्लेखन:

def munge_data(df)
    munged = (df.assign(lambda x: x['name'].str.lower()
                .drop_duplicates())
    return munged

इस तरह की स्थिति में सर्वोत्तम प्रथाओं के लिए कोई सुझाव?


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

जवाबों:


1

मुझे लगता है कि आपने पुस्तक के सही उदाहरण का शायद अधिक महत्वपूर्ण हिस्सा याद किया। कोड में अधिक मूलभूत परिवर्तन किसी सूची में सभी मानों को एक तत्व पर संचालित करने की विधि से है।

पहले से ही मौजूद फ़ंक्शन जैसे iter(इस नाम वाले मामले में pipeline_foreach) जो किसी सूची में सभी तत्वों पर दिए गए ऑपरेशन करते हैं। forलूप के साथ नकल करने की कोई आवश्यकता नहीं थी । एक प्रसिद्ध सूची संचालन का उपयोग करने से भी आपकी मंशा स्पष्ट होती है। साथ mapआप मान बदलने कर रहे हैं। साथ iterआप प्रत्येक तत्व के साथ एक पक्ष प्रभाव प्रदर्शन कर रहे हैं। forलूप के साथ आप ... ठीक है, आप वास्तव में नहीं जानते जब तक आप इसके माध्यम से नहीं देखते हैं।

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

मुझे लगता है कि अंतिम परिणाम कोड में छोटे कार्य हैं जो यहां परीक्षण को परेशान करने के लिए बहुत तुच्छ हैं। आखिरकार, आपको इकाई परीक्षण को replaceया उसके खिलाफ लिखने की आवश्यकता नहीं होनी चाहिए title। अब शायद आप इन्हें अपने फंक्शन और यूनिट टेस्ट में एक साथ रचना करना चाहते हैं कि एक एकल आइटम पर वांछित संयोजन प्राप्त किया जाता है। खुद, मैं शायद सिर्फ एकवचन में बदल format_bandsगया format_band, लूप के लिए गिरा दिया, और बुलाया pipeline_each(bands, format_band)। फिर आप यह सुनिश्चित करने के लिए format_band का परीक्षण कर सकते हैं कि आप कुछ भूल नहीं गए हैं।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.