बार-बार आने वाली इन्वेंटरी तालिकाओं से एक ही सेल का डेटा इकट्ठा करने के लिए, हर तालिका को CSV के रूप में एक्सपोर्ट करें, फिर Finder शॉर्टकट चलाएँ जो उस स्थान का डेटा पढ़कर एक अवलोकन बनाता है। इस चरण-दर-चरण मार्गदर्शिका में B3 का डेटा इकट्ठा किया जाता है, हर स्रोत फ़ाइल का नाम रखा जाता है और पहले से मौजूद परिणाम को ओवरराइट करने से मना किया जाता है।

शॉर्टकट बनाने से पहले सही इनपुट चुनें

यह वर्कफ़्लो उन लोगों के लिए है जो एक जैसे लेआउट वाली कई इन्वेंटरी तालिकाएँ संभालते हैं और अलग अवलोकन में हर तालिका के लिए एक पंक्ति चाहते हैं। उदाहरण में कृत्रिम गणनाओं वाली तीन अस्थायी फ़ाइलें इस्तेमाल की गई हैं। हर फ़ाइल एक एक्सपोर्ट की गई तालिका दर्शाती है; लक्ष्य कॉलम B, पंक्ति 3 है, जिसमें हेडर पंक्ति भी शामिल है।

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

नीचे दिया गया शॉर्टकट डेटा निकालने का काम एक छोटे Python प्रोग्राम को सौंपता है। यह Numbers दस्तावेज़ या Excel वर्कबुक को सादा टेक्स्ट नहीं मानता और यह भी नहीं मानता कि स्प्रेडशीट फ़ाइल स्वीकार करने से किसी कार्रवाई को उसके सेल का डेटा मिल जाएगा। Apple बताता है कि जानकारी पैनल से किसी कार्रवाई के स्वीकार किए गए इनपुट और उससे मिलने वाले आउटपुट की जाँच कैसे करें। अपने Mac पर उपलब्ध कार्रवाइयों की जाँच करते समय उस पैनल का उपयोग करें। Mac पर Shortcuts में कार्रवाई सूची देखें।

शुरू करने से पहले यह निर्णय तालिका देखें:

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

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

अस्थायी इन्वेंटरी फ़ाइलें तैयार करें

इस उदाहरण के लिए Python 3 अलग से इंस्टॉल होना चाहिए। Python की वेबसाइट के मानक इंस्टॉलर से इंस्टॉल करने पर एक्ज़िक्यूटेबल लिंक /usr/local/bin/ में रखे जाते हैं। नीचे दिए गए कमांड स्पष्ट रूप से /usr/local/bin/python3 का उपयोग करते हैं, इसलिए शॉर्टकट के कमांड सर्च पाथ पर निर्भरता नहीं रहती। अपने समर्थित Python रिलीज़ के इंस्टॉलेशन निर्देशों का पालन करें, फिर जाँचें कि यह कमांड काम करता है। macOS पर Python का उपयोग।

/usr/local/bin/python3 --version

अगर यह पाथ मौजूद नहीं है, तो आगे बढ़ने से पहले Python इंस्टॉल करें। प्रोग्राम केवल Python की मानक लाइब्रेरी का उपयोग करता है; किसी अतिरिक्त पैकेज की ज़रूरत नहीं है। Apple की Terminal गाइड बताती है कि एक्ज़िक्यूटेबल का पूरा पाथनेम और उसके बाद आर्ग्युमेंट देकर कमांड चलाए जा सकते हैं। Mac पर Terminal में कमांड चलाएँ और टूल इस्तेमाल करें।

कृत्रिम इनपुट बनाने के लिए यह पूरा कमांड Terminal में पेस्ट करें। यह आपके Desktop पर Inventory Demo बनाता है और अगर वह फ़ोल्डर पहले से मौजूद है तो रुक जाता है। इन उदाहरणों को किसी मौजूदा डायरेक्टरी में मिलाने के बजाय एक नया अस्थायी फ़ोल्डर इस्तेमाल करें।

/usr/local/bin/python3 - <<'PY'
import csv
from pathlib import Path

root = Path.home() / "Desktop" / "Inventory Demo"
root.mkdir()
examples = [
    ("Birch", "A", "12"),
    ("Cedar", "B", "7"),
    ("Maple", "C", "0"),
]
for name, bin_name, count in examples:
    with (root / f"{name}.csv").open(
        "x", encoding="utf-8", newline=""
    ) as handle:
        csv.writer(handle).writerows([
            ["Item", "Value"],
            ["Bin", bin_name],
            ["Counted units", count],
        ])
print(root)
PY

Numbers एक्सपोर्ट चरण को अलग से जाँचने के लिए, Numbers में कोई एक अस्थायी CSV खोलें और File > Export To > CSV का उपयोग करके उसे किसी अलग अस्थायी फ़ोल्डर में एक्सपोर्ट करें। हर तालिका के लिए एक फ़ाइल चुनें, Include table names बंद रखें और UTF-8 एन्कोडिंग इस्तेमाल करें। एक्सपोर्ट की गई तालिका देखकर पुष्टि करें कि A3 और B3 में इच्छित लेबल और मान अब भी मौजूद हैं। Apple ने इन एक्सपोर्ट विकल्पों का दस्तावेज़ दिया है। Numbers एक्सपोर्ट सेटिंग।

स्प्रेडशीट का एक्सटेंशन बदलकर .csv न करें; यह एक्सपोर्ट करने का विकल्प नहीं है। यह प्रोग्राम वास्तविक कॉमा-विभाजित टेक्स्ट की अपेक्षा करता है। आगे की मार्गदर्शिका के लिए तीनों मूल कृत्रिम CSV फ़ाइलें साथ रखें।

अवलोकन बनाने वाला प्रोग्राम बनाएँ

नीचे दिए गए पूरे प्रोग्राम को किसी सादे टेक्स्ट एडिटर में Inventory Demo के अंदर overview.py नाम से सेव करें। पुष्टि करें कि फ़ाइल का नाम .py पर खत्म होता है, .py.txt पर नहीं। प्रोग्राम स्रोत फ़ाइलों के पाथ को आर्ग्युमेंट के रूप में लेता है, B3 पढ़ता है और उनके साझा फ़ोल्डर में overview.csv बनाता है।

import csv
import io
import sys
from pathlib import Path

ROW, COLUMN = 2, 1  # Zero-based: B3
LABEL = "Counted units"

def build_overview(arguments):
    if not arguments:
        raise ValueError("Select at least one source CSV.")
    paths = [Path(name).expanduser().resolve(strict=True)
             for name in arguments]
    if len(set(paths)) != len(paths):
        raise ValueError("The same source was supplied twice.")
    if len({path.parent for path in paths}) != 1:
        raise ValueError("Keep all source CSVs in one folder.")
    rows = []
    for path in sorted(paths, key=lambda p: p.name):
        if (not path.is_file() or path.suffix.lower() != ".csv"
                or path.name.casefold() == "overview.csv"):
            raise ValueError(f"Not a source CSV: {path.name}")
        with path.open(encoding="utf-8-sig", newline="") as handle:
            records = list(csv.reader(handle, strict=True))
        if len(records) <= ROW or len(records[ROW]) <= COLUMN:
            raise ValueError(f"{path.name}: B3 does not exist.")
        if records[ROW][0] != LABEL:
            raise ValueError(f"{path.name}: A3 must be {LABEL!r}.")
        value = records[ROW][COLUMN]
        status = "blank" if value.strip() == "" else "present"
        rows.append([path.name, "B3", value, status])
    buffer = io.StringIO(newline="")
    writer = csv.writer(buffer)
    writer.writerow(["Source file", "Cell", "Value", "Status"])
    writer.writerows(rows)
    return paths[0].parent / "overview.csv", buffer.getvalue()

def main(arguments):
    try:
        destination, content = build_overview(arguments)
        with destination.open("x", encoding="utf-8", newline="") as handle:
            handle.write(content)
    except (OSError, ValueError, csv.Error) as error:
        print(f"Stopped: {error}", file=sys.stderr)
        return 1
    print(f"Created: {destination}")
    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))

प्रोग्राम कॉमा या लाइन ब्रेक पर टेक्स्ट बाँटने के बजाय CSV पार्सर का उपयोग करता है। Python का reader फ़ील्ड को स्ट्रिंग के रूप में लौटाता है और दस्तावेज़ के अनुसार CSV फ़ाइलें newline="" के साथ खोली जानी चाहिए। इससे उद्धृत फ़ील्ड में मौजूद कॉमा या शामिल लाइन ब्रेक सही ढंग से संभाले जाते हैं। प्रोग्राम निकाले गए मान को जस का तस रखता है; न उसका जोड़ करता है, न उसे संख्या में बदलता है। CSV फ़ाइल पढ़ना और लिखना।

परिणाम को जाँचना आसान बनाने के लिए कुछ सीमाएँ जानबूझकर रखी गई हैं। हर इनपुट का मौजूद होना ज़रूरी है, हल किए गए सभी स्रोत पाथ एक ही फ़ोल्डर में होने चाहिए और दोहराए गए हल किए गए पाथ अस्वीकार किए जाते हैं। प्रोग्राम Finder में चयन के क्रम पर निर्भर रहने के बजाय फ़ाइल नाम के अनुसार क्रम लगाता है। यह overview.csv नाम वाले इनपुट को भी अस्वीकार करता है, ताकि पिछला परिणाम गलती से शामिल न हो जाए।

आउटपुट बनाना शुरू होने से पहले सभी स्रोत पढ़े और जाँचे जाते हैं। B3 मौजूद न हो या A3 में लेबल अपेक्षित न हो, तो रन रुक जाता है। मौजूद लेकिन खाली B3 से blank चिह्नित पंक्ति बनती है; 0 का मान 0 ही रहता है और उसे present चिह्नित किया जाता है। इस तरह अनुपस्थित सेल, खाली सेल और शून्य गणना के अलग-अलग नतीजे होते हैं।

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

प्रोग्राम को Finder शॉर्टकट से जोड़ें

Shortcuts में Inventory Overview नाम का शॉर्टकट बनाएँ। Details खोलें, Use as Quick Action चालू करें और Finder चुनें। इनपुट कॉन्फ़िगरेशन में Files चालू रखें और असंबंधित सामग्री प्रकार बंद करें। Apple बताता है कि फ़ाइलें या फ़ोल्डर स्वीकार करने वाले शॉर्टकट Finder में उपलब्ध होते हैं और स्वीकार किए जाने वाले इनपुट को सीमित करने के नियंत्रण भी देता है। Mac पर काम करते हुए शॉर्टकट चलाएँ, शॉर्टकट के इनपुट को सीमित करें।

बिना इनपुट की स्थिति को Stop and Respond पर सेट करें और संदेश के रूप में Select the source CSV files in Finder. जैसा पाठ दें। इससे खाली चयन अस्पष्ट रन नहीं बनता। यह विकल्प और उसका प्रतिसाद फ़ील्ड Apple की इनपुट कॉन्फ़िगरेशन गाइड में बताए गए हैं। अनुपस्थित इनपुट पर प्रतिक्रिया चुनें।

Run Shell Script जोड़ें। Shell को /bin/zsh पर सेट करें, उसके Input को Shortcut Input से जोड़ें और Pass Input को as arguments पर सेट करें। नमूना स्क्रिप्ट की जगह यह पूरा कमांड डालें:

/usr/local/bin/python3 "$HOME/Desktop/Inventory Demo/overview.py" "$@"

उद्धरण चिह्न बनाए रखें। उद्धृत "$@" आने वाले आर्ग्युमेंट को अलग-अलग भेजता है, इसलिए स्पेस वाले फ़ाइल नाम सुरक्षित रहते हैं। इसी कारण स्क्रिप्ट के पाथनेम को भी उद्धरणों में रखा गया है। zsh मैनुअल पोज़िशनल पैरामीटर और उद्धृत ऐरे तत्वों के अलग-अलग विस्तार का विवरण देता है; Apple की Terminal गाइड भी पाथनेम को उद्धरणों में रखने की जानकारी देती है। पैरामीटर, Terminal में फ़ाइलें और फ़ोल्डर निर्दिष्ट करें।

अगर Shortcuts को स्क्रिप्टिंग चालू करना ज़रूरी लगे, तो Shortcuts > Settings > Advanced चुनें और Allow Running Scripts चुनें। Apple बताता है कि शॉर्टकट से स्क्रिप्ट चलाने की अनुमति देने के लिए यह सेटिंग कहाँ है। Shortcuts की उन्नत सेटिंग।

कॉन्फ़िगर किया गया फ़्लो यह है: चुने गए फ़ाइल ऑब्जेक्ट शॉर्टकट में आते हैं, उनके पाथ शेल आर्ग्युमेंट बनते हैं और Python उन फ़ाइलों को पढ़कर अवलोकन लिखता है। शेल कार्रवाई का सफल टेक्स्ट परिणाम Created: संदेश होता है, जिसमें गंतव्य पाथनेम दिया होता है। यह संदेश CSV फ़ाइल स्वयं नहीं है। इसके बाद सेव करने की कोई कार्रवाई ज़रूरी नहीं, क्योंकि प्रोग्राम फ़ाइल पहले ही बना चुका है।

Finder में केवल Birch.csv, Cedar.csv और Maple.csv चुनें। चयन पर Control-क्लिक करें और Quick Actions > Inventory Overview चुनें। अगर शॉर्टकट दिखाई नहीं दे रहा है, तो चालू Finder एक्सटेंशन देखने के लिए More > Customize इस्तेमाल करें, फिर स्वीकार किए जाने वाले इनपुट प्रकार दोबारा जाँचें। Apple Finder Quick Actions को कस्टमाइज़ करने और उस मेनू में शॉर्टकट जोड़ने का तरीका बताता है। Mac पर Finder में त्वरित कार्रवाइयाँ करें।

परिणाम जाँचें और बार-बार चलने की स्थिति सँभालें

डेमो फ़ोल्डर से overview.csv को Numbers में खोलें। दिए गए कृत्रिम फ़ाइलों के साथ इसकी सामग्री यह होनी चाहिए:

Source file,Cell,Value,Status
Birch.csv,B3,12,present
Cedar.csv,B3,7,present
Maple.csv,B3,0,present

जाँचें कि हर चुने गए स्रोत के लिए आउटपुट में एक पंक्ति है और फ़ाइल नाम से इच्छित तालिका की पहचान होती है। उदाहरण के मान केवल समझाने के लिए हैं, मापी गई इन्वेंटरी के नतीजे नहीं। प्रोग्राम बताता है कि मान मौजूद है या नहीं; यह नहीं जाँचता कि मान वैध गणना है।

कुछ अलग दिखे तो यह जाँच क्रम अपनाएँ:

  1. Finder में शॉर्टकट नहीं दिख रहा: इसकी Finder सेटिंग, स्वीकार किया जाने वाला Files इनपुट और चालू एक्सटेंशन जाँचें।
  2. एक्ज़िक्यूटेबल या स्क्रिप्ट नहीं मिल रही: Python का पाथनेम जाँचें और पुष्टि करें कि overview.py निर्दिष्ट डेमो फ़ोल्डर में है।
  3. B3 मौजूद नहीं या A3 गलत है: प्रोग्राम बदलने से पहले स्रोत के एक्सपोर्ट किए गए रिकॉर्ड और एक्सपोर्ट विकल्प जाँचें।
  4. अप्रत्याशित खाली मान: B3 देखें; प्रोग्राम जानबूझकर खाली मान को खाली ही रखता है।
  5. गंतव्य पहले से मौजूद है: पिछला अस्थायी अवलोकन नाम बदलें या दोबारा चलाने से पहले उसे स्रोत फ़ोल्डर से बाहर ले जाएँ।

इनपुट का रास्ता जाँचने के लिए आप वही शॉर्टकट Terminal से भी चला सकते हैं। Apple बताता है कि फ़ाइल इनपुट देने के लिए -i इस्तेमाल होता है; पाथनेम को पाइप करने पर टेक्स्ट भेजा जाता है। नीचे दी गई स्पष्ट फ़ाइलें इस्तेमाल करें और आउटपुट फ़्लैग न दें, क्योंकि आउटपुट बनाना Python प्रोग्राम का काम है। नाम टकराने का वही नियम लागू होता है। कमांड लाइन से शॉर्टकट चलाएँ।

shortcuts run "Inventory Overview" -i \
  "$HOME/Desktop/Inventory Demo/Birch.csv" \
  "$HOME/Desktop/Inventory Demo/Cedar.csv" \
  "$HOME/Desktop/Inventory Demo/Maple.csv"

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

स्रोत