अन्य लोगों को यह सुनिश्चित करने का मजबूत तरीका है कि मेरे अजगर कार्यक्रम को चला सकें


17

मैं GitHub पर एक पायथन प्रोग्राम रखना चाहता हूं और अन्य लोगों को इसे डाउनलोड करके इसे अपने कंप्यूटर पर मिश्रित ऑपरेटिंग सिस्टम के साथ चलाना है। मैं अजगर के लिए अपेक्षाकृत नया हूं लेकिन इस पर पर्याप्त ध्यान दिया है कि सभी शामिल मॉड्यूल के मिश्रित संस्करणों को एक साथ काम करने में समस्या हो सकती है। मैंने सिर्फ requirements.txt( pipreqsकमांड के साथ उत्पन्न और तैनात pip install -r /path/to/requirements.txt) के उपयोग की खोज की, लेकिन यह देखकर बहुत आश्चर्य हुआ कि requirements.txtवास्तव में यह नहीं बताया गया है कि अजगर के किस संस्करण का उपयोग किया जा रहा है, तो जाहिर है कि यह अपने आप में पूर्ण समाधान नहीं है। तो मेरा सवाल यह है: विनिर्देशों / फाइलों / कुछ-और के सेट को क्या यह सुनिश्चित करने के लिए आवश्यक है कि मेरी परियोजना को डाउनलोड करने वाला व्यक्ति वास्तव में इसे सबसे कम संभव समस्याओं के साथ चला सकेगा।

संपादित करें: मेरी योजना को सबसे अधिक उत्तोलन प्राप्त करने के लिए जो भी उत्तर दिया गया था। लेकिन अब तक, 4 उत्तर और 127 विचारों के बाद, एक भी उत्तर में एक भी उत्थान नहीं हुआ है। यदि कुछ उत्तर अच्छे नहीं हैं, तो कुछ टिप्पणियों को देखना उपयोगी होगा कि वे अच्छे क्यों नहीं हैं।


1
सबसे कम संभव समस्याओं के लिए, क्या आपने डॉकर (या अन्य कंटेनर-आधारित समाधान) पर विचार किया है? docker.com
Zaccharie Ramzi

पुन: डॉकर ... बस यह पाया गया: "डेवलपर यह आश्वासन दे सकता है कि एप्लिकेशन किसी अन्य लिनक्स मशीन पर चलेगा" - लेकिन मैं चाहता हूं कि यह किसी भी ओएस पर काम करे। ( Openource.com/resources/what-docker )
मिक

आम तौर पर आपके पास सभी शास्त्रीय OS: windows ( docs.docker.com/docker-for-windows ) और mac ( docs.docker.com/docker-for-windows ) के लिए समर्थन है
Zaccharie Ramzi

2
यहाँ उत्तर अत्यधिक प्रासंगिक है। अजगर कार्यक्रम बातें कर रही है कि कर रहे हैं sysया osया उपप्रक्रिया प्रकार कार्य या अधिक गणितीय / विश्लेषणात्मक? पूर्व पायथन के प्रत्येक संस्करण के साथ बदल सकता है और बाद में स्वतंत्र रूप से काफी संस्करण हो सकता है। क्या निर्भर पुस्तकालयों? सुन्न और पांडा प्लेटफार्मों भर में एक अद्भुत काम करते हैं ताकि आप बस जांच कर सकें कि आपके पास एक मिन संस्करण है। पायथन का मुख्य संस्करण क्या है? निर्भर पुस्तकालयों के साथ अजगर 2.x और 3.x के बीच का अंतर अभी भी कठिन हो जाता है। यदि आप एक सामान्य प्रमुख रिलीज़ को लक्षित करते हुए अच्छा कोड लिखते हैं जो एक शानदार शुरुआत है।
dawg

2
जवाबों के असंख्य के रूप में, इस बारे में जाने के कई तरीके हैं। अगर एप्लिकेशन क्या है , यह जानने के आधार पर उत्तर बदल जाएगा, तो मैं वास्तव में उत्सुक हूं । मेरा मानना ​​है कि यह मायने नहीं रखना चाहिए, लेकिन मुझे संदेह है कि यह हो सकता है। मुझे यह भी लगता है कि यह बहुत हद तक इच्छित दर्शकों पर निर्भर करता है। प्रेमी भौतिकी पीएचडी चेकर्स के एक pygame खेल जो बनाम इंटरनेट एक मशीन सीखने के आवेदन चल रहा है।
मार्सेल विल्सन

जवाबों:


15

क्या आपने एक setup.pyफ़ाइल स्थापित करने पर विचार किया है ? यह आपके सभी ... अच्छी तरह से एक ही स्थान पर सेटअप करने का एक आसान तरीका है। तो आपके सभी उपयोगकर्ता को ए) क्लोन करना है जो आपके रेपो और बी) को चलाने के pip install .लिए चलता हैsetup.py

इस बारे में एक महान स्टैक चर्चा है।

साथ ही अनुरोधकर्ता द्वारा लिखित एक हैंडल उदाहरण।

यह अधिकांश उपयोग के मामलों को कवर करना चाहिए। अब अगर आप इसे वास्तव में वितरण योग्य बनाना चाहते हैं तो आप इसे आधिकारिक वितरण केंद्र PyPi में स्थापित करना चाहते हैं ।

इससे परे कि अगर आप पूछ रहे हैं कि "ओएस स्वतंत्र" प्रोग्राम कैसे बनाया जाए, तो एक आकार सभी को फिट नहीं है। यह इस बात पर निर्भर करता है कि आप अपने कोड के साथ क्या कर रहे हैं। शोध करने की आवश्यकता है कि आपका विशेष कोड उन ओएस आदि के साथ कैसे इंटरैक्ट करता है।


7

ऐसा करने के लिए कई, कई, कई, कई, कई, कई, कई तरीके हैं। मैं प्रत्येक के पीछे सिद्धांतों पर स्केट करूंगा, और यह केस का उपयोग करेगा।

1. एक अजगर पर्यावरण

इसे करने के कई तरीके हैं। pipenv, कोंडा, requirments.txtआदि।

इनमें से कुछ के साथ, आप अजगर संस्करणों को निर्दिष्ट कर सकते हैं। दूसरों के साथ, बस अजगर संस्करणों की एक श्रृंखला निर्दिष्ट करें जिन्हें आप जानते हैं कि यह इसके साथ काम करता है - उदाहरण के लिए, यदि आप अजगर 3.7 का उपयोग कर रहे हैं, तो यह 3.6 का समर्थन नहीं करने की संभावना नहीं है; केवल एक या दो मामूली बदलाव हैं। 3.8 को भी काम करना चाहिए।

इसी तरह की एक और विधि है setup.py। इनका उपयोग आमतौर पर पुस्तकालयों को वितरित करने के लिए किया जाता है - जैसे PyInstaller (एक अन्य समाधान जिसका मैं नीचे उल्लेख करूँगा), या सुन्न, या wxPython, या PyQt5 आदि - आयात / कमांड लाइन उपयोग के लिए। अजगर पैकेजिंग गाइड काफी उपयोगी है, और वहाँ ट्यूटोरियल के भार हैं। (Google python setup.py tutorial) आप इन फ़ाइलों में आवश्यकताओं को भी निर्दिष्ट कर सकते हैं।

2. एक कंटेनर

डोकर बड़ा है। यदि आपने इसके बारे में नहीं सुना है, तो मुझे आश्चर्य होगा। एक सारांश के एक त्वरित गूगल के साथ आता है यह , जो मैं का हिस्सा उद्धृत करता हूँ:

तो हर कोई कंटेनर और डॉकरों से प्यार क्यों करता है? जेम्स बॉटले, पूर्व में सर्वर वर्चुअलाइजेशन के सीटीओ और एक प्रमुख लिनक्स कर्नेल डेवलपर, हाइपर-वी, केवीएम और एक्सएम जैसे वीएम हाइपरविजर को समझाते थे, सभी "वर्चुअल हार्डवेयर के अनुकरण पर आधारित हैं। इसका मतलब है कि वे वसा के संदर्भ में मोटे हैं।" सिस्टम आवश्यकताएं।"

कंटेनर, हालांकि, साझा ऑपरेटिंग सिस्टम का उपयोग करते हैं। इसका मतलब यह है कि वे सिस्टम संसाधन की दृष्टि से हाइपरविजर की तुलना में अधिक कुशल हैं। हार्डवेयर के वर्चुअलाइजेशन के बजाय, कंटेनर एक ही लिनक्स उदाहरण के शीर्ष पर आराम करते हैं। इसका मतलब है कि आप "बेकार 99.9 प्रतिशत वीएम जंक को पीछे छोड़ सकते हैं, जो आपको अपने आवेदन में एक छोटे, साफ कैप्सूल के साथ छोड़ देगा।"

इसे आपके लिए संक्षेप में प्रस्तुत करना चाहिए। (ध्यान दें कि आपको कंटेनरों के लिए विशिष्ट OS की आवश्यकता नहीं है।)

3. एक निष्पादन योग्य फ़ाइल

2 मुख्य उपकरण हैं जो लेखन के समय ऐसा करते हैं। PyInstaller, और cx_Freeze। दोनों सक्रिय रूप से विकसित हैं। दोनों ओपन सोर्स हैं।

आप अपनी स्क्रिप्ट लेते हैं, और उपकरण इसे बाइटकोड के लिए संकलित करता है, आयात पाता है, उन को कॉपी करता है, और एक पोर्टेबल पायथन वातावरण बनाता है जो आपकी स्क्रिप्ट को अंतिम उपयोगकर्ता के बिना अजगर की आवश्यकता के बिना लक्ष्य प्रणाली पर चलाता है।

व्यक्तिगत रूप से, मैं PyInstaller पसंद करता हूं - मैं डेवलपर्स में से एक हूं। PyInstaller एक कमांड लाइन स्क्रिप्ट के माध्यम से अपनी सभी कार्यक्षमता प्रदान करता है, और अधिकांश पुस्तकालयों का समर्थन करता है जो आप सोच सकते हैं - और अधिक समर्थन करने के लिए विस्तार योग्य है। cx_Freeze को सेटअप स्क्रिप्ट की आवश्यकता होती है।

दोनों उपकरण विंडोज़, लिनक्स, मैकओएस और अधिक का समर्थन करते हैं। PyInstaller सिंगल फ़ाइल एक्ज़ेक या एक फ़ोल्डर बंडल बना सकता है, जबकि cx_Freeze केवल एक फ़ोल्डर बंडल का समर्थन करता है। PyInstaller 3.6 अजगर 2.7, और 3.5-3.7 का समर्थन करता है - लेकिन 4.0 अजगर 2 का समर्थन नहीं करेगा । cx_Freeze ने पिछले प्रमुख रिलीज (6.0 मुझे लगता है) के रूप में अजगर 2 समर्थन को गिरा दिया है।

वैसे भी, उपकरण सुविधाओं के बारे में पर्याप्त है; आप स्वयं उन पर गौर कर सकते हैं। ( अधिक जानकारी के लिए https://pyinstaller.org और https://cx-freeze.readthedocs.io देखें )

इस वितरण विधि का उपयोग करते समय, आप आमतौर पर GitHub रेपो पर स्रोत कोड प्रदान करते हैं, एक जोड़े को (प्रत्येक प्लेटफ़ॉर्म के लिए एक) डाउनलोड के लिए तैयार करते हैं, और कोड को एक निष्पादन योग्य फ़ाइल में कैसे बनाया जाए, इस पर निर्देश देते हैं।


1

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

प्रोजेक्ट वेबसाइट टूल का उपयोग करने के तरीके को समझाने के लिए एक बहुत अच्छा काम करता है, लेकिन, पूर्णता के लिए, मैं यहां एक छोटा स्पष्टीकरण दूंगा।

एक बार जब आप Pipenv स्थापित हो जाते हैं (उदाहरण के लिए, चलाकर pip install --user pipenv), तो आप अपनी परियोजना की निर्देशिका में जा सकते हैं और चला सकते हैं pipenv --python 3.7, इसलिए Pipenv आपकी परियोजना के लिए एक नया virtualenv बनाएगा, एक Pipfile और Pipfile.lock बनाएँ (बाद में उनके लिए अधिक) । यदि आप आगे बढ़ते हैं और pipenv install -r requirements.txtइसे चलाते हैं तो यह आपके सभी पैकेजों को स्थापित कर देगा। अब आप pipenv shellअपने नए virtualenv को सक्रिय करने के लिए, या pipenv run your_main_file.pyकेवल अपनी परियोजना चलाने के लिए कर सकते हैं।

अब अपने Pipfile की सामग्री पर एक नज़र डालते हैं। यह कुछ ऐसा होना चाहिए:

[packages]
Django = "*"
djangorestframework = "*"
iso8601 = "*"
graypy = "*"
whitenoise = "*"

[requires]
python_version = "3.7"

इस फ़ाइल में आपकी परियोजना की निर्भरता के लिए मानव-पठनीय विनिर्देश हैं (ध्यान दें कि यह पायथन संस्करण को भी निर्दिष्ट करता है)। यदि आपकी आवश्यकताएँ। Txt संस्करणों में पिन की गई थीं, तो आपका Pipfile उनके पास भी हो सकता है, लेकिन आप उन्हें सुरक्षित रूप से वाइल्डकार्ड कर सकते हैं, क्योंकि सटीक संस्करण Pipfile.lock में संग्रहीत हैं। अब आप pipenv updateअपनी निर्भरता को अपडेट करने के लिए चीजों को चला सकते हैं और अपने VCS के लिए Pipfile और Pipfile.lock करना न भूलें।

एक बार जब लोग आपके प्रोजेक्ट को क्लोन कर लेते हैं, तो उन्हें बस इतना ही करना होता है pipenv installऔर पिपेनव बाकी चीजों की देखभाल करेगा (यह उनके लिए पायथन का सही संस्करण भी स्थापित कर सकता है)।

मुझे उम्मीद है कि यह उपयोगी था। मैं पिपेनव के साथ किसी भी तरह से संबद्ध नहीं हूं, बस इस भयानक उपकरण को साझा करना चाहता था।


1

यदि आपका प्रोग्राम GUI के बारे में कम है, या आपके पास एक वेब GUI है, तो आप Google Colaboratory का उपयोग करके कोड साझा कर सकते हैं।

https://colab.research.google.com/

हर कोई इसे समान वातावरण के साथ चला सकता है। स्थापना के लिए कोई ज़रूरत नहीं है।


1

यदि आपकी सभी अजगर लिपियों को एक निष्पादन योग्य में परिवर्तित करने से आपकी मदद हो सकती है, तो नीचे दिए गए मेरे उत्तर से मदद मिलेगी ...

मैं 3 साल से शुद्ध रूप से अजगर में एक बड़ा डेस्कटॉप एप्लिकेशन विकसित कर रहा हूं। यह एक GUI- आधारित टूल है जो pyqt Library (क्यूटी C ++ फ्रेमवर्क के पाइथन-बाइंडिंग्स) के ऊपर बनाया गया है।

मैं वर्तमान में " py2exe " पैकेजिंग लाइब्रेरी का उपयोग कर रहा हूं : एक डिस्टुटिल एक्सटेंशन है जो पायथन स्क्रिप्ट से स्टैंडअलोन विंडोज निष्पादन योग्य प्रोग्राम (32-बिट और 64-बिट) बनाने की अनुमति देता है; आपको बस इतना करना है:

  1. py2exe स्थापित करें: 'पाइप स्थापित py2exe'

  2. एक सेटअप थ्रीडी स्क्रिप्ट बनाएँ: इसका उपयोग अंतिम EXE (नाम, आइकन, लेखक, डेटा फ़ाइलें, साझा लाइब्रेरी आदि) की सामग्री को निर्दिष्ट करने के लिए किया जाता है।

  3. Execute: python setup.py py2.exe

मैं इंस्टॉलर बनाने के लिए "इनो सेटअप" सॉफ़्टवेयर का उपयोग कर रहा हूं : शॉर्टकट बनाना, पर्यावरण चर, आइकन, आदि की स्थापना ...


py2exe वर्षों में अपडेट नहीं किया गया है। मुझे कोई हाल की गतिविधि नहीं मिल रही है । मैं तब मान लेता हूँ, यह अस्वीकार्य है। (इसके अलावा, यह केवल अजगर <3.4 का समर्थन करता है। इसका मतलब है कि यह केवल पदावनत अजगर संस्करणों का समर्थन करता है)।
लेजोरूज

0

मुझे लगता है कि आप अपने अजगर के साथ dog का उपयोग कर सकते हैं https://github.com/celery/celery/tree/master/docker

कृपया फ़ाइलों का पालन करें और मुझे लगता है कि आप अपने पायथन स्क्रिप्ट के लिए अपने डॉक फ़ाइल बनाने के तरीके का पता लगा सकते हैं!


-1

क्योंकि यह अन्य उत्तरों से गायब है, मैं एक पूरी तरह से अलग पहलू जोड़ना चाहूंगा:

इकाई का परीक्षण। या सामान्य रूप से परीक्षण।

आमतौर पर, एक ज्ञात अच्छा कॉन्फ़िगरेशन होना अच्छा है। कार्यक्रम की निर्भरताएं क्या हैं, इसके आधार पर, आपको पैकेजों के विभिन्न संयोजनों का परीक्षण करना पड़ सकता है। आप एक स्वचालित फैशन में कर सकते हैं जैसे toxकि एक CI या CD पाइपलाइन के भाग के रूप में।

पैकेजों के किस संयोजन का परीक्षण किया जाना चाहिए, इसका कोई सामान्य नियम नहीं है, लेकिन आमतौर पर python2 / 3 संगतता एक प्रमुख मुद्दा है। यदि आपके पास प्रमुख संस्करण अंतर वाले पैकेजों पर मजबूत निर्भरता है, तो आप इन विभिन्न संस्करणों के खिलाफ परीक्षण पर विचार करना चाह सकते हैं।


यह सॉफ्टवेयर विकास का एक बहुत महत्वपूर्ण पहलू है। हालांकि, यह सवाल का जवाब देने में पूरी तरह से विफल है । इकाई परीक्षण एक कार्यक्रम के वितरण में कैसे मदद करता है?
22

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

मैं विवादित नहीं हूं कि यूनिट परीक्षण यह सुनिश्चित करने में मूल्यवान है कि यह सही ढंग से चलता है, लेकिन ओपी ने पूछा कि फैशन को "आसान स्थापित करने के लिए" कोड को कैसे साझा किया जाए। इसलिए मुझे लगता है कि यह एक विशिष्ट उत्तर है - इस विशिष्ट प्रश्न के लिए।
लेजोरूज

मुझे अभी भी लगता है कि सवाल केवल वितरण का ही नहीं है। इसलिए मैंने यह जवाब जोड़ा है। यदि आप उदाहरण के लिए विंडोज़ पर विकसित होते हैं, तो यदि आप वितरण से पहले इसे चलाना चाहते हैं, तो यूनिक्स पर परीक्षण आवश्यक है।
11:20 बजे Dschoni

जिज्ञासा से बाहर, जो मैंने अभी कहा उससे अलग कैसे है? ... making sure it runs correctly ...? परीक्षण यह सुनिश्चित करने का एक अनिवार्य हिस्सा है कि यह सही ढंग से चलता है, इसलिए यह इसे वितरित करने की तैयारी का एक अनिवार्य हिस्सा है, लेकिन यह वास्तव में इसे वितरित करने के साथ कुछ भी नहीं करना है
लेगोरूज

-1

मैं आपको मौजूदा उपलब्ध समाधानों में से कुछ का एक बहुत ही संक्षिप्त सारांश दूंगा जब यह आपके द्वारा चुने गए पैकेजिंग पैकेजिंग पर आता है (ज्ञान शक्ति है):

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

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

  3. यदि आप अभी भी अपने उपयोगकर्ताओं को किसी भी देव निर्भरता को स्थापित करने के लिए मजबूर किए बिना अपने प्रोजेक्ट को शिप करना चाहते हैं और आप कोड सुरक्षा के बारे में भी परवाह करते हैं, तो आप किसी भी मौजूदा फ्रीजर पर विचार नहीं करना चाहते हैं जो आप nuitka , shedskin , जैसे टूल का उपयोग कर सकते हैं , साइथन या इसी तरह के। आमतौर पर इन उपकरणों द्वारा निर्मित कलाकृतियों से कोड को उलट देना बिल्कुल भी मामूली नहीं है ... दूसरी तरफ क्रैकिंग सुरक्षा एक अलग मामला है और जब तक आप अपने अंतिम-उपयोगकर्ता को एक भौतिक बाइनरी प्रदान नहीं करते हैं, तब तक आप बहुत कुछ नहीं कर सकते इसे धीमा करने के अलावा अन्य इसके बारे में :)

  4. इसके अलावा, अगर आपको अपने अजगर प्रोजेक्ट में बाहरी भाषाओं का उपयोग करने की आवश्यकता होगी, तो दिमाग में आने वाला एक और क्लासिक लिंक होगा https://wiki.python.org/moin/IntegratingPythonWithOtherLanguages , CI को ऐसे टूल के बिल्ड सिस्टम को जोड़कर 1 के नियम बहुत आसान होंगे।

उस ने कहा, मैं सुझाव दूंगा बुलेटप्रूफ 1 को, जैसा कि मुझे पता है कि आपको शुरू करने के लिए पर्याप्त से अधिक अच्छा होगा, यह भी कि विशेष बिंदु को अजगर "मानक" परियोजनाओं के लिए मौजूदा उपयोग के कई मामलों को कवर करना चाहिए।

हालांकि यह उन लोगों का अनुसरण करने के लिए पूरी तरह से मार्गदर्शक होने का इरादा नहीं है, जिन्हें आप अपने अजगर प्रोजेक्ट को कुछ ही समय में जनता के लिए प्रकाशित कर पाएंगे।

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