Clone the repo and install using pip.
$ git clone https://github.com/zilogic-systems/yamlcalc.git $ pip install --user yamlcalc
The top level element of the YAML file should be a map. If a string in
the document starts with an =
then it is interpreted as a Python
expression and is evaluated.
Input | Output |
---|---|
a: 5
b: 6
c: = 1 + 2 |
a: 5
b: 6
c: 3 |
The keys of the top level dict can be used as global variable names within Python expressions. They expand to their corresponding values in the YAML document.
Input | Output |
---|---|
a: 5
b: 6
c: = a + b |
a: 5
b: 6
c: 11 |
If the value of a variable is a list, list operations can be performed on them.
Input | Output |
---|---|
a:
- 1
- 2
- 3
- 4
b: = a[1]
c: = sum(a) |
a:
- 1
- 2
- 3
- 4
b: 2
c: 10 |
Tip
|
All Python standard built-ins are available within expressions. |
If the value is a dictionary, dictionary operations can be performed, as expected. In addition, the keys in the mapping can be accessed using object attribute access notation.
Input | Output |
---|---|
a:
x: 10
y: 20
z: 30
b: = a["z"]
c: = a.y |
a:
x: 10
y: 20
z: 30
b: 30
c: 20 |
The result of the expressions are not restricted to scalar values, it could also be a list / dict returned from functions or generator expressions.
Input | Output |
---|---|
a: = range(1, 4)
b: = [i * 2 for i in a]
c: = list(sorted(a, reverse=True)) |
a:
- 1
- 2
- 3
b:
- 2
- 4
- 6
c:
- 3
- 2
- 1 |
YAML documents can contain nested structures. Expressions within
container types (lists / dictionaries) can use the special self
variable to refer to the container.
The following example shows a list of products, represented as a
nested datastructure. The base price is specified and the tax and
total price is calculated using expressions. The expressions use
self
to refer to other members within their structure.
Input | Output |
---|---|
products:
- name: zkit-arm-1343
price: 2540
tax: = self.price * 5 / 100
total: = self.price + self.tax
- name: zkit-arm-1769
price: 5680
tax: = self.price * 5 / 100
total: = self.price + self.tax |
products:
- name: zkit-arm-1343
price: 2540
tax: 127
total: 2667
- name: zkit-arm-1769
price: 5680
tax: 284
total: 5964 |
YAMLCalc is not restricted to YAML for output, alternate output
formats can be specified, to better visualize the data. The output
type and parameters are specified in the VIEW
special global
variable.
Input | Output |
---|---|
products:
- name: zkit-arm-1343
price: 2540
tax: = self.price * 5 / 100
total: = self.price + self.tax
- name: zkit-arm-1769
price: 5680
tax: = self.price * 5 / 100
total: = self.price + self.tax
VIEW:
type: csv
cols: [Name, Price]
rows: = [[p.name, p.total] for p in products] |
|
If additional functions are required, they can be defined or imported
from another module / package. The Python statements in the special
DEFS
global variable is executed. Imports and function definition
populate the global namespace, and are accessible in all expressions.
Input | Output |
---|---|
DEFS: |
import math
def abc(a, b, c):
return a + b + c
a: = math.sin(1)
x: = abc(1, 2, 3) |
DEFS: |2
import math
def abc(a, b, c):
return a + b + c
a: 0.8414709848078965
x: 6 |
YAMLCalc also provides a mechanism to generate charts from the
data. Charts are generated using pygal
.
Input | Output |
---|---|
DEFS: |
def sum_for_cat(journal, cat):
return sum(i[2] for i in journal if i[3] == cat)
journal:
- [2016-03-01, rent, 10000, housing]
- [2016-03-02, fuel, 300, vehicle]
- [2016-03-03, maintenance, 1000, housing]
- [2016-03-03, bike service, 500, vehicle]
- [2016-03-03, fruits, 1000, food]
- [2016-03-04, snacks, 200, food]
- [2016-03-05, water, 35, food]
- [2016-03-07, fuel, 300, vehicle]
- [2016-03-08, movie, 360, leisure]
- [2016-03-08, grocery, 2000, food]
VIEW:
type: chart
chart: pie
inner_radius: 0.4
rows:
- [Housing, "= sum_for_cat(journal, 'housing')"]
- [Leisure, "= sum_for_cat(journal, 'leisure')"]
- [Food, "= sum_for_cat(journal, 'food')"]
- [Vehicle, "= sum_for_cat(journal, 'vehicle')"] |
-
Add support for multiple views.
-
Add support for proper propogation of errors.
-
Add better support for validation of view types and chart types.
-
Add better support for error reporting.
-
This project was heavily influenced by the "Spreadsheet" ActiveState Recipe by Raymond Hettinger.
-
Thanks to ArtistsValley for the abacus icon: http://www.iconspedia.com/icon/abacus-icon-26575.html