Esta página fue traducida por una máquina y aún no ha sido revisada por una persona. El inglés es la referencia; las correcciones son bienvenidas en GitHub. GitHub

Cookwala / SDK y escenarios / 002

Parse a food bank's SMS day: offer, claim, handover with a partial rejection

The Humanitarian Profile's SMS grammar lets a program run on basic phones. Parse the three messages of a typical rescue and see the cold-chain checks the gateway applies before it writes a document.

Audiencia: food bank · Objetivo: Ayudar a acabar con el hambre · Nivel: beginner

Leer primero: /docs/HUMANITARIAN-PROFILE/ /humanitarian/

Pasos

  1. A supermarket offers 36 kg of yogurt, chilled, at 4 °C, use by 5 November. parseSms

  2. The same yogurt declared ambient: the gateway infers the food class from the words and refuses to list it. parseSms

  3. A food bank claims the whole offer. parseSms

  4. At handover 30 kg are accepted and 6 kg rejected for damaged packaging, measured at 4.6 °C. The reason code maps to the profile's enum. parseSms

  5. Arabic-Indic digits are accepted wherever a digit is, so a phone set to an Arabic keyboard works. parseSms

Resultado

You can turn messages into structured commands and know which ones a gateway refuses. Next: scenario 003 checks a whole flow against a rule pack.

Línea de comandos

cookwala sms "OFFER 36KG YOGURT C 4C UB0511"
cookwala sms "HAND A7K 30 REJ 6 PACK T4.6"

Salida grabada

Estado: ok

[1] parseSms: {"ok": true, "command": "OFFER", "kg": 36.0, "item": "yogurt", "storage": "chilled", "tempC": 4.0, "dateMark": {"kind": "use_by", "dayMonth": "05-11"}, "foodClasses": ["dairy"], "findings": []}
[2] parseSms: {"ok": true, "command": "OFFER", "kg": 12.0, "item": "yogurt", "storage": "ambient", "foodClasses": ["dairy"], "findings": ["safety.storage_class_mismatch"]}
[3] parseSms: {"ok": true, "command": "CLAIM", "offer": "A7K", "all": true, "findings": []}
[4] parseSms: {"ok": true, "command": "HAND", "offer": "A7K", "kgAccepted": 30.0, "kgRejected": 6.0, "reason": "packaging_damaged", "reasonCode": "PACK", "tempC": 4.6, "findings": []}
[5] parseSms: {"ok": true, "command": "HAND", "offer": "A7K", "kgAccepted": 30.0, "tempC": 4.6, "findings": []}

Código

Ejecutar: python scenarios/out/002-sms-offer-claim-handover/python.py

# Scenario 002: Parse a food bank's SMS day: offer, claim, handover with a partial rejection
# The Humanitarian Profile's SMS grammar lets a program run on basic phones. Parse the three messages of a typical rescue and see the cold-chain checks the gateway applies before it writes a document.
# Run a hub first: python hub/cookwala_hub.py --recipes examples
import json, os
from cookwala.client import CookwalaClient, CookwalaProblem

def load(path):
    with open(path, encoding="utf-8") as f:
        return json.load(f)

def pick(obj, path):
    for part in path.replace("]", "").replace("[", ".").split("."):
        obj = obj[int(part)] if part.isdigit() else (len(obj) if part == "length" else obj.get(part))
    return obj

c = CookwalaClient(os.environ.get("COOKWALA_HUB", "http://localhost:7878"))


# Step 1: A supermarket offers 36 kg of yogurt, chilled, at 4 °C, use by 5 November.
offer = c.parse_sms("OFFER 36KG YOGURT C 4C UB0511")
assert pick(offer, "ok") == True, pick(offer, "ok")
print("ok", "ok", "=", True)
assert pick(offer, "command") == "OFFER", pick(offer, "command")
print("ok", "command", "=", "OFFER")
assert pick(offer, "kg") == 36.0, pick(offer, "kg")
print("ok", "kg", "=", 36.0)
assert pick(offer, "storage") == "chilled", pick(offer, "storage")
print("ok", "storage", "=", "chilled")
assert pick(offer, "foodClasses") == ["dairy"], pick(offer, "foodClasses")
print("ok", "foodClasses", "=", ["dairy"])
assert pick(offer, "findings.length") == 0, pick(offer, "findings.length")
print("ok", "findings.length", "=", 0)

# Step 2: The same yogurt declared ambient: the gateway infers the food class from the words and refuses to list it.
ambient = c.parse_sms("OFFER 12KG YOGURT A")
assert pick(ambient, "findings") == ["safety.storage_class_mismatch"], pick(ambient, "findings")
print("ok", "findings", "=", ["safety.storage_class_mismatch"])

# Step 3: A food bank claims the whole offer.
claim = c.parse_sms("CLAIM A7K ALL")
assert pick(claim, "command") == "CLAIM", pick(claim, "command")
print("ok", "command", "=", "CLAIM")
assert pick(claim, "all") == True, pick(claim, "all")
print("ok", "all", "=", True)

# Step 4: At handover 30 kg are accepted and 6 kg rejected for damaged packaging, measured at 4.6 °C. The reason code maps to the profile's enum.
hand = c.parse_sms("HAND A7K 30 REJ 6 PACK T4.6")
assert pick(hand, "kgAccepted") == 30.0, pick(hand, "kgAccepted")
print("ok", "kgAccepted", "=", 30.0)
assert pick(hand, "kgRejected") == 6.0, pick(hand, "kgRejected")
print("ok", "kgRejected", "=", 6.0)
assert pick(hand, "reason") == "packaging_damaged", pick(hand, "reason")
print("ok", "reason", "=", "packaging_damaged")
assert pick(hand, "tempC") == 4.6, pick(hand, "tempC")
print("ok", "tempC", "=", 4.6)

# Step 5: Arabic-Indic digits are accepted wherever a digit is, so a phone set to an Arabic keyboard works.
digits = c.parse_sms("HAND A7K ٣٠ T4.6")
assert pick(digits, "kgAccepted") == 30.0, pick(digits, "kgAccepted")
print("ok", "kgAccepted", "=", 30.0)

print("scenario complete")

scenarios/002-sms-offer-claim-handover.json

Anterior: 001 Siguiente: 003