Repository: accelerated-text/accelerated-text (language: python)

Issue:
Non-existing or empty values in data rows
Currently, if you don't provide the value for a data cell, it will yield a missing value exception: 
https://github.com/tokenmill/accelerated-text/blob/a322f9b6436923a3f624a0bdd53d6466541e047e/core/src/acc_text/nlg/graph/data.clj#L8

```
(defn get-data [data key]
  (if (contains? data key)
    (get data key)
    (throw (Exception. (format "Missing value for data cell: `%s`" key)))))
```

I think this should be a warning and default value of a missing key should be null/empty string. Otherwise, this kind of document plans are not possible and API client needs to provide all values which limits the document plans to a good degree:

See `client.corporate.name` check:
![image](https://user-images.githubusercontent.com/656635/112956324-035d0500-9149-11eb-9161-e1fd2c394797.png)



Discussion / hints:
**Sample requests**

Request that works:
```
{
  "documentPlanName": "utter_kb_attr_project_client",
  "dataRow": {
    "client.corporate.name": "",
    "first_name": "Hilal",
    "last_name": "Kahraman"
  },
  "readerFlagValues": {
    "Eng": true
  },
  "async": false
}
```

Request that throws:
```
{
  "documentPlanName": "utter_kb_attr_project_client",
  "dataRow": {
    "first_name": "Hilal",
    "last_name": "Kahraman"
  },
  "readerFlagValues": {
    "Eng": true
  },
  "async": false
}
```

But because our API client basically dumps whole objects into the request, we really don't want to strictly bind the required parameters of a document plan with our API client. Basically, our client should be dumb and document plan should be smart.
Well.. I tried to write my first Clojure code:
https://github.com/MotaWord/accelerated-text/commit/936d2f3622d39436491f074ccc4259405c33fb65

```clj
(defn get-data [data key]
  (if (contains? data key)
    (get data key)
    (throw (Exception. (format "Missing value for data cell: `%s`" key)))))
    (do
      (log/error (format "Missing value for data cell: `%s`" key))
      (""))
```

I can see the log, but it doesn't continue anyway... couldn't figure out the `resolve-data` logic.

Fix patch:
diff --git a/api/src/api/config.clj b/api/src/api/config.clj
index 4951d824f..6d42749cd 100644
--- a/api/src/api/config.clj
+++ b/api/src/api/config.clj
@@ -12,7 +12,7 @@
    :db-implementation    (when-let [db-implementation (or (System/getenv "DB_IMPLEMENTATION") "datomic")]
                            (keyword db-implementation))
    :db-uri               (System/getenv "DB_URI")
-   :display-error        (Boolean/valueOf (System/getenv "DISPLAY_ERROR"))
+   :display-error        (Boolean/valueOf ^String (or (System/getenv "DISPLAY_ERROR") "TRUE"))
    :default-language     (or (System/getenv "DEFAULT_LANGUAGE") "Eng")
    :enabled-languages    (set (read-conf-line (or (System/getenv "ENABLED_LANGUAGES") "Eng")))
    :enabled-readers      (set (read-conf-line (or (System/getenv "ENABLED_READERS") "")))
diff --git a/core/src/acc_text/nlg/graph/condition.clj b/core/src/acc_text/nlg/graph/condition.clj
index a5459cc2f..2d33f37c4 100644
--- a/core/src/acc_text/nlg/graph/condition.clj
+++ b/core/src/acc_text/nlg/graph/condition.clj
@@ -5,15 +5,16 @@
             [loom.graph :as graph]))
 
 (defn string->boolean [s]
-  (case (-> s (str/lower-case) (str/trim))
-    "" false
-    "true" true
-    "false" false
-    "yes" true
-    "no" false
-    "1" true
-    "0" false
-    true))
+  (when (some? s)
+    (case (-> s (str/lower-case) (str/trim))
+      "" false
+      "true" true
+      "false" false
+      "yes" true
+      "no" false
+      "1" true
+      "0" false
+      true)))
 
 (defn operator->fn [x]
   (case x


Test patch:
diff --git a/core/test/acc_text/nlg/core_test.clj b/core/test/acc_text/nlg/core_test.clj
index c353ce0cc..2c802c6de 100644
--- a/core/test/acc_text/nlg/core_test.clj
+++ b/core/test/acc_text/nlg/core_test.clj
@@ -124,3 +124,8 @@
         context (test-utils/load-test-context "complex-amr-test")]
     (is (= ["House on the hill. Cat on the hill. Big house on the hill. Big cat on the hill."]
            (map :text (core/generate-text semantic-graph context "Eng"))))))
+
+(deftest ^:integration missing-data-conditions
+  (let [semantic-graph (test-utils/load-test-semantic-graph "missing-data-conditions")]
+    (is (= ["1 2."] (map :text (core/generate-text semantic-graph {:data {"a" "1", "b" "2"}} "Eng"))))
+    (is (= ["1 3."] (map :text (core/generate-text semantic-graph {:data {"a" "1", "b" "2", "c" "3"}} "Eng"))))))
diff --git a/core/test/resources/semantic-graphs/missing-data-conditions.edn b/core/test/resources/semantic-graphs/missing-data-conditions.edn
new file mode 100644
index 000000000..e08e291f3
--- /dev/null
+++ b/core/test/resources/semantic-graphs/missing-data-conditions.edn
@@ -0,0 +1,58 @@
+#:acc-text.nlg.semantic-graph{:id          "PAsZpdZxlPXLjggI",
+                              :uid         "a7a452df-26f5-4113-a3df-5895b1a83a79",
+                              :name        "conditions test",
+                              :kind        "Document",
+                              :category    "Str",
+                              :description "",
+                              :relations   ({:from  "rviqrSdvHPXTyKGwFhQt",
+                                             :to    "PnmqkUxnotmTNrcQJUaI",
+                                             :role  :segment,
+                                             :index 0}
+                                            {:from  "PnmqkUxnotmTNrcQJUaI",
+                                             :to    "B8~qRx`3h;!/%?OET*7e",
+                                             :role  :instance,
+                                             :index 0}
+                                            {:from  "PnmqkUxnotmTNrcQJUaI",
+                                             :to    "PcXg+rL5qp+o^P))Xe(T",
+                                             :role  :instance,
+                                             :index 1}
+                                            {:from  "PcXg+rL5qp+o^P))Xe(T",
+                                             :to    "zJjqYjGHmYlLRefdCgvo",
+                                             :role  :statement,
+                                             :index 0}
+                                            {:from  "PcXg+rL5qp+o^P))Xe(T",
+                                             :to    "RoPYctglDoDubiLYLiFN",
+                                             :role  :statement,
+                                             :index 1}
+                                            {:from "zJjqYjGHmYlLRefdCgvo", :to "B~MYRCE``=QaI%^5-kX,", :role :predicate}
+                                            {:from "zJjqYjGHmYlLRefdCgvo",
+                                             :to   "}T8e:aUbbD-bFgxn7k6[",
+                                             :role :then-expression}
+                                            {:from "RoPYctglDoDubiLYLiFN",
+                                             :to   "r$-a9{F[Bze.jP:U*YqH",
+                                             :role :then-expression}),
+                              :concepts    ({:id "rviqrSdvHPXTyKGwFhQt", :position 1, :type :document-plan}
+                                            {:id "PnmqkUxnotmTNrcQJUaI", :position 2, :type :segment}
+                                            {:id       "B8~qRx`3h;!/%?OET*7e",
+                                             :position 3,
+                                             :type     :data,
+                                             :name     "a",
+                                             :category "Str"}
+                                            {:id "PcXg+rL5qp+o^P))Xe(T", :position 4, :type :condition}
+                                            {:id "zJjqYjGHmYlLRefdCgvo", :position 5, :type :if-statement}
+                                            {:id       "B~MYRCE``=QaI%^5-kX,",
+                                             :position 6,
+                                             :type     :data,
+                                             :name     "c",
+                                             :category "Str"}
+                                            {:id       "}T8e:aUbbD-bFgxn7k6[",
+                                             :position 7,
+                                             :type     :data,
+                                             :name     "c",
+                                             :category "Str"}
+                                            {:id "RoPYctglDoDubiLYLiFN", :position 8, :type :else-statement}
+                                            {:id       "r$-a9{F[Bze.jP:U*YqH",
+                                             :position 9,
+                                             :type     :data,
+                                             :name     "b",
+                                             :category "Str"})}