Files
CoolProp/dev/scripts/examples/example_generator.py
2019-01-12 20:45:25 -07:00

1009 lines
31 KiB
Python

import json, sys
from six import string_types
header_template = """
[
]
"""
# Each entry in the list is a chunk (probably a line) in the to-be-generated code
high_level_interface = [
"",
{
"type": "print",
"arguments": [
"'**************** INFORMATION ***************'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'This example was auto-generated by the language-agnostic dev/scripts/example_generator.py script written by Ian Bell'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'CoolProp version:'",
{
"type": "function",
"function": "get_global_param_string",
"arguments": [
"'version'"
]
}
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'CoolProp gitrevision:'",
{
"type": "function",
"function": "get_global_param_string",
"arguments": [
"'gitrevision'"
]
}
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'CoolProp Fluids:'",
{
"type": "function",
"function": "get_global_param_string",
"arguments": [
"'FluidsList'"
]
}
],
"EOL":True
},
"",
{
"type": "comment",
"comment": "See http://www.coolprop.org/coolprop/HighLevelAPI.html#table-of-string-inputs-to-propssi-function for a list of inputs to high-level interface",
"EOL": True
},
{
"type": "print",
"arguments": [
"'*********** HIGH LEVEL INTERFACE *****************'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'Critical temperature of water:'",
{
"type": "function",
"function": "Props1SI",
"arguments": [
"'Water'",
"'Tcrit'"
]
},
"'K'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'Boiling temperature of water at 101325 Pa:'",
{
"type": "function",
"function": "PropsSI",
"arguments": [
"'T'", "'P'", "101325", "'Q'", "0", "'Water'"
]
},
"'K'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'Phase of water at 101325 Pa and 300 K:'",
{
"type": "function",
"function": "PhaseSI",
"arguments": [
"'P'", "101325", "'T'", "300", "'Water'"
]
}
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'c_p of water at 101325 Pa and 300 K:'",
{
"type": "function",
"function": "PropsSI",
"arguments": [
"'C'", "'P'", "101325", "'T'", "300", "'Water'"
]
},
"'J/kg/K'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'c_p of water (using derivatives) at 101325 Pa and 300 K:'",
{
"type": "function",
"function": "PropsSI",
"arguments": [
"'d(H)/d(T)|P'", "'P'", "101325", "'T'", "300", "'Water'"
]
},
"'J/kg/K'"
],
"EOL":True
},
"",
{
"type": "print",
"arguments": ["'*********** HUMID AIR PROPERTIES *****************'"],
"EOL":True
},
{
"type": "print",
"arguments": [
"'Humidity ratio of 50% rel. hum. air at 300 K, 101325 Pa:'",
{
"type": "function",
"function": "HAPropsSI",
"arguments": [
"'W'", "'T'", "300", "'P'", "101325", "'R'", "0.5"
]
},
"'kg_w/kg_da'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'Relative humidity from last calculation:'",
{
"type": "function",
"function": "HAPropsSI",
"arguments": [
"'R'", "'T'", "300", "'P'", "101325", "'W'",
{
"type": "function",
"function": "HAPropsSI",
"arguments": [
"'W'", "'T'", "300", "'P'", "101325", "'R'", "0.5"
]
}
]
},
"'(fractional)'"
],
"EOL":True
},
"",
{
"type": "print",
"arguments": ["'*********** INCOMPRESSIBLE FLUID AND BRINES *****************'"],
"EOL":True
},
{
"type": "print",
"arguments": [
"'Density of 50% (mass) ethylene glycol/water at 300 K, 101325 Pa:'",
{
"type": "function",
"function": "PropsSI",
"arguments": [
"'D'", "'T'", "300", "'P'", "101325", "'INCOMP::MEG-50%'"
]
},
"'kg/m^3'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'Viscosity of Therminol D12 at 350 K, 101325 Pa:'",
{
"type": "function",
"function": "PropsSI",
"arguments": [
"'V'", "'T'", "350", "'P'", "101325", "'INCOMP::TD12'"
]
},
"'Pa-s'"
],
"EOL":True
},
"",
{
"type": "comment",
"comment": "If you don't have REFPROP installed, disable the following lines",
"EOL": True
},
{
"type": "print",
"arguments": ["'*********** REFPROP *****************'"],
"EOL":True
},
{
"type": "print",
"arguments": [
"'REFPROP version:'",
{
"type": "function",
"function": "get_global_param_string",
"arguments": [
"'REFPROP_version'"
]
}
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'Critical temperature of water:'",
{
"type": "function",
"function": "Props1SI",
"arguments": [
"'REFPROP::Water'",
"'Tcrit'"
]
},
"'K'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'Boiling temperature of water at 101325 Pa:'",
{
"type": "function",
"function": "PropsSI",
"arguments": [
"'T'", "'P'", "101325", "'Q'", "0", "'REFPROP::Water'"
]
},
"'K'"
],
"EOL":True
},
{
"type": "print",
"arguments": [
"'c_p of water at 101325 Pa and 300 K:'",
{
"type": "function",
"function": "PropsSI",
"arguments": [
"'C'", "'P'", "101325", "'T'", "300", "'REFPROP::Water'"
]
},
"'J/kg/K'"
],
"EOL":True
}
]
low_level_interface_with_mixtures = [
"",
{
"type": "print",
"arguments": ["'*********** LOW-LEVEL INTERFACE *****************'"],
"EOL":True
},
{
"type": "custom_assignment",
"variable_type": "AbstractState",
"variable_name": "AS",
"RHS": {
"type": "function",
"function": "factory",
"arguments": [
"'HEOS'", "'Water&Ethanol'"
]
},
"EOL":True
},
{
"type": "custom_assignment",
"variable_name": "z",
"variable_type": "vector",
"RHS": {
"type": "vector",
"arguments": [
"0.5",
"0.5"
]
},
"EOL":True
},
{
"type": "class_dereference",
"name": "AS",
"RHS": {
"type": "function",
"function": "set_mole_fractions",
"arguments": [
"z"
]
},
"EOL":True
},
{
"type": "class_dereference",
"name": "AS",
"RHS": {
"type": "function",
"function": "update",
"arguments": [
{
"type": "enum",
"enum": "input_pairs",
"key": "PQ_INPUTS"
},
"101325", "1"
]
},
"EOL": True
},
{
"type": "print",
"arguments": [
"'Normal boiling point temperature of water and ethanol:'",
{
"type": "class_dereference",
"name": "AS",
"RHS": {
"type": "function",
"function": "T",
"arguments": []
}
},
"'K'"
],
"EOL":True
},
"",
{
"type": "comment",
"comment": "If you don't have REFPROP installed, disable the following block",
"EOL": True
},
{
"type": "print",
"arguments": ["'*********** LOW-LEVEL INTERFACE (REFPROP) *****************'"],
"EOL":True
},
{
"type": "custom_assignment",
"variable_type": "AbstractState",
"variable_name": "AS2",
"RHS": {
"type": "function",
"function": "factory",
"arguments": [
"'REFPROP'", "'Methane&Ethane'"
]
},
"EOL":True
},
{
"type": "custom_assignment",
"variable_name": "z2",
"variable_type": "vector",
"RHS": {
"type": "vector",
"arguments": [
"0.2",
"0.8"
]
},
"EOL":True
},
{
"type": "class_dereference",
"name": "AS2",
"RHS": {
"type": "function",
"function": "set_mole_fractions",
"arguments": [
"z2"
]
},
"EOL":True
},
{
"type": "class_dereference",
"name": "AS2",
"RHS": {
"type": "function",
"function": "update",
"arguments": [
{
"type": "enum",
"enum": "input_pairs",
"key": "QT_INPUTS"
},
"1", "120"
]
},
"EOL": True
},
{
"type": "print",
"arguments": [
"'Vapor molar density:'",
{
"type": "class_dereference",
"name": "AS2",
"RHS": {
"type": "function",
"function": "keyed_output",
"arguments": [
{
"type": "enum",
"enum": "parameters",
"key": "iDmolar"
}
]
}
},
"'mol/m^3'"
],
"EOL": True
}
]
low_level_interface = [
"",
{
"type": "print",
"arguments": ["'*********** TABULAR BACKENDS *****************'"],
"EOL":True
},
{
"type": "custom_assignment",
"variable_type": "AbstractState",
"variable_name": "TAB",
"RHS": {
"type": "function",
"function": "factory",
"arguments": [
"'BICUBIC&HEOS'", "'R245fa'"
]
},
"EOL":True
},
{
"type": "class_dereference",
"name": "TAB",
"RHS": {
"type": "function",
"function": "update",
"arguments": [
{
"type": "enum",
"enum": "input_pairs",
"key": "PT_INPUTS"
},
"101325", "300"
]
},
"EOL": True
},
{
"type": "print",
"arguments": [
"'Mass density of refrigerant R245fa at 300 K, 101325 Pa:'",
{
"type": "class_dereference",
"name": "TAB",
"RHS": {
"type": "function",
"function": "rhomass",
"arguments": []
}
},
"'kg/m^3'"
],
"EOL":True
},
{
"type": "print",
"arguments": ["'*********** SATURATION DERIVATIVES (LOW-LEVEL INTERFACE) ***************'"],
"EOL":True
},
{
"type": "custom_assignment",
"variable_type": "AbstractState",
"variable_name": "AS_SAT",
"RHS": {
"type": "function",
"function": "factory",
"arguments": [
"'HEOS'", "'R245fa'"
]
},
"EOL":True
},
{
"type": "class_dereference",
"name": "AS_SAT",
"RHS": {
"type": "function",
"function": "update",
"arguments": [
{
"type": "enum",
"enum": "input_pairs",
"key": "PQ_INPUTS"
},
"101325", "0"
]
},
"EOL": True
},
{
"type": "print",
"arguments": [
"'First saturation derivative:'",
{
"type": "class_dereference",
"name": "AS_SAT",
"RHS": {
"type": "function",
"function": "first_saturation_deriv",
"arguments": [
{
"type": "enum",
"enum": "parameters",
"key": "iP"
},
{
"type": "enum",
"enum": "parameters",
"key": "iT"
}
]
}
},
"'Pa/K'"
],
"EOL": True
}
]
class BaseParser(object):
def __init__(self):
self.pieces = high_level_interface + low_level_interface + low_level_interface_with_mixtures
def footer(self):
return ''
def parse(self):
lines = []
for line in self.pieces:
if isinstance(line, string_types):
lines.append(line)
elif isinstance(line, dict):
lines.append(self.dict2string(line))
else:
raise ValueError()
return ''.join(self.header()) + '\n'.join([self.indentation + line for line in lines if line]) + ''.join(self.footer())
def write(self, fname, code):
with open(fname, 'w') as fp:
fp.write(code)
def map_function(self, name):
if name in self.function_name_mapping:
return self.function_name_mapping[name]
else:
return name
class Python(BaseParser):
function_name_mapping = dict(Props1SI='PropsSI',
factory='AbstractState')
type_name_mapping = {'vector': None,
'AbstractState': None}
enum_name_mapping = {'input_pairs': "CoolProp", 'parameters': "CoolProp"}
indentation = ''
def parse_arguments(self, arguments):
out = []
for arg in arguments:
if isinstance(arg, string_types) and arg[0] == "'" and arg[-1] == "'":
out.append('\"' + arg[1:-1] + '\"')
elif isinstance(arg, dict):
out.append(self.dict2string(arg))
else:
out.append(arg)
return out
def dict2string(self, d):
if d['type'] == 'comment':
return '# ' + d['comment']
elif d['type'] == 'function':
return self.map_function(d['function']) + '(' + ', '.join(self.parse_arguments(d['arguments'])) + ')'
elif d['type'] == 'print':
return 'print(' + ', '.join(self.parse_arguments(d['arguments'])) + ')'
elif d['type'] == 'vector':
return '[' + ', '.join(self.parse_arguments(d['arguments'])) + ']'
elif d['type'] == 'enum':
return self.enum_name_mapping[d['enum']] + '.' + d['key']
elif d['type'] == 'class_dereference':
return d['name'] + '.' + self.dict2string(d['RHS'])
elif d['type'] == 'custom_assignment':
type_name = self.type_name_mapping[d['variable_type']]
if type_name:
LHS = type_name + ' ' + d['variable_name']
else:
LHS = d['variable_name']
return ' '.join([LHS, '=', self.dict2string(d['RHS'])])
else:
return '??????????????????????????????'
def header(self):
return '\n'.join(['from __future__ import print_function',
'from CoolProp import AbstractState',
'from CoolProp.CoolProp import PhaseSI, PropsSI, get_global_param_string',
'import CoolProp.CoolProp as CoolProp',
'from CoolProp.HumidAirProp import HAPropsSI',
'from math import sin\n'])
class Octave(BaseParser):
function_name_mapping = dict(Props1SI='CoolProp.Props1SI',
PropsSI='CoolProp.PropsSI',
PhaseSI='CoolProp.PhaseSI',
HAPropsSI='CoolProp.HAPropsSI',
get_global_param_string='CoolProp.get_global_param_string',
factory='AbstractState.factory')
type_name_mapping = {'vector': None,
'AbstractState': None}
enum_name_mapping = {'input_pairs': "CoolProp", 'parameters': "CoolProp"}
indentation = ' ' * 0
def parse_arguments(self, arguments):
out = []
for arg in arguments:
if isinstance(arg, string_types) and arg[0] == "'" and arg[-1] == "'":
out.append('\'' + arg[1:-1] + '\'')
elif isinstance(arg, dict):
out.append(self.dict2string(arg))
else:
out.append(arg)
return out
def dict2string(self, d):
if d['type'] == 'comment':
l = '% ' + d['comment']
elif d['type'] == 'function':
l = self.map_function(d['function']) + '(' + ', '.join(self.parse_arguments(d['arguments'])) + ')'
elif d['type'] == 'print':
args = self.parse_arguments(d['arguments'])
args = ['num2str(' + arg + ')' for arg in args]
l = 'disp([' + ', \' \', '.join(args) + '])'
elif d['type'] == 'vector':
args = self.parse_arguments(d['arguments'])
l = '[' + ', '.join(args) + ']'
elif d['type'] == 'class_dereference':
l = d['name'] + '.' + self.dict2string(d['RHS'])
elif d['type'] == 'enum':
l = self.enum_name_mapping[d['enum']] + '.' + d['key']
elif d['type'] == 'custom_assignment':
type_name = self.type_name_mapping[d['variable_type']]
if type_name:
LHS = type_name + ' ' + d['variable_name']
else:
LHS = d['variable_name']
if d['RHS']['type'] != 'vector':
RHS = self.dict2string(d['RHS'])
else: # Custom processing for vector assignment
pushes = [d['variable_name'] + '.push_back(' + arg + ');' for arg in d['RHS']['arguments']]
RHS = 'DoubleVector(); ' + ' '.join(pushes)
l = ' '.join([LHS, '=', RHS])
else:
l = '??????????????????????????????'
if 'EOL' in d and d['EOL']:
l += ';'
return l
def header(self):
return '\n'.join(['CoolProp\n'])
class R(BaseParser):
function_name_mapping = dict(factory='AbstractState_factory')
type_name_mapping = {'vector': None,
'AbstractState': None}
enum_name_mapping = {'input_pairs': "CoolProp", 'parameters': "CoolProp"}
indentation = ' ' * 0
def parse_arguments(self, arguments):
out = []
for arg in arguments:
if isinstance(arg, string_types) and arg[0] == "'" and arg[-1] == "'":
out.append('\'' + arg[1:-1] + '\'')
elif isinstance(arg, dict):
out.append(self.dict2string(arg))
else:
out.append(arg)
return out
def dict2string(self, d):
if d['type'] == 'comment':
l = '# ' + d['comment']
elif d['type'] == 'function':
l = self.map_function(d['function']) + '(' + ', '.join(self.parse_arguments(d['arguments'])) + ')'
elif d['type'] == 'print':
args = self.parse_arguments(d['arguments'])
l = 'writeLines(paste(' + ', \' \', '.join(args) + '))'
elif d['type'] == 'vector':
args = self.parse_arguments(d['arguments'])
l = '[' + ', '.join(args) + ']'
elif d['type'] == 'class_dereference':
l = d['name'] + '$' + self.dict2string(d['RHS'])
elif d['type'] == 'enum':
l = '"' + d['key'] + '"'
elif d['type'] == 'custom_assignment':
type_name = self.type_name_mapping[d['variable_type']]
if type_name:
LHS = type_name + ' ' + d['variable_name']
else:
LHS = d['variable_name']
if d['RHS']['type'] != 'vector':
RHS = self.dict2string(d['RHS'])
else: # Custom processing for vector assignment
pushes = [d['variable_name'] + ' <- ' + arg + ';' for arg in d['RHS']['arguments']]
RHS = 'c(' + ', '.join([arg for arg in d['RHS']['arguments']]) + ')'
l = ' '.join([LHS, '=', RHS])
else:
l = '??????????????????????????????'
if 'EOL' in d and d['EOL']:
l += ''
return l
def header(self):
return 'dyn.load(paste("CoolProp", .Platform$dynlib.ext, sep=""))\nlibrary(methods) # See http://stackoverflow.com/a/19468533\nsource("CoolProp.R")\ncacheMetaData(1)\n'
class MATLAB(BaseParser):
function_name_mapping = dict(Props1SI='CoolProp.Props1SI',
PropsSI='CoolProp.PropsSI',
PhaseSI='CoolProp.PhaseSI',
HAPropsSI='CoolProp.HAPropsSI',
get_global_param_string='CoolProp.get_global_param_string',
factory='CoolProp.AbstractState.factory')
enum_name_mapping = {'input_pairs': "CoolProp", 'parameters': "CoolProp"}
type_name_mapping = {'vector': None,
'AbstractState': None}
indentation = ''
def parse_arguments(self, arguments):
out = []
for arg in arguments:
if isinstance(arg, string_types) and arg[0] == "'" and arg[-1] == "'":
out.append('\'' + arg[1:-1] + '\'')
elif isinstance(arg, dict):
out.append(self.dict2string(arg))
else:
out.append(arg)
return out
def dict2string(self, d):
if d['type'] == 'comment':
l = '% ' + d['comment']
elif d['type'] == 'function':
l = self.map_function(d['function']) + '(' + ', '.join(self.parse_arguments(d['arguments'])) + ')'
elif d['type'] == 'print':
args = self.parse_arguments(d['arguments'])
args = ['num2str(' + arg + ')' for arg in args]
l = 'disp([' + ', \' \', '.join(args) + '])'
elif d['type'] == 'vector':
args = self.parse_arguments(d['arguments'])
l = '[' + ', '.join(args) + ']'
elif d['type'] == 'enum':
l = self.enum_name_mapping[d['enum']] + '.' + d['key']
elif d['type'] == 'class_dereference':
l = d['name'] + '.' + self.dict2string(d['RHS'])
elif d['type'] == 'custom_assignment':
type_name = self.type_name_mapping[d['variable_type']]
if type_name:
LHS = type_name + ' ' + d['variable_name']
else:
LHS = d['variable_name']
# Custom processing for vector assignment
if d['RHS']['type'] != 'vector':
RHS = self.dict2string(d['RHS'])
else: # vector
pushes = [d['variable_name'] + '.push_back(' + arg + ');' for arg in d['RHS']['arguments']]
RHS = 'CoolProp.DoubleVector(); ' + ' '.join(pushes)
l = ' '.join([LHS, '=', RHS])
else:
l = '??????????????????????????????'
if 'EOL' in d and d['EOL']:
l += ';'
return l
def header(self):
return ''
class Java(BaseParser):
function_name_mapping = dict(Props1SI='CoolProp.Props1SI',
PropsSI='CoolProp.PropsSI',
PhaseSI='CoolProp.PhaseSI',
HAPropsSI='CoolProp.HAPropsSI',
get_global_param_string='CoolProp.get_global_param_string',
factory='AbstractState.factory')
type_name_mapping = {'vector': 'DoubleVector',
'AbstractState': 'AbstractState'}
enum_name_mapping = {'input_pairs': "input_pairs", 'parameters': "parameters"}
indentation = ' ' * 8
def parse_arguments(self, arguments):
out = []
for arg in arguments:
if isinstance(arg, string_types) and arg[0] == "'" and arg[-1] == "'":
out.append('\"' + arg[1:-1] + '\"')
elif isinstance(arg, dict):
out.append(self.dict2string(arg))
else:
out.append(arg)
return out
def dict2string(self, d):
if d['type'] == 'comment':
l = '// ' + d['comment']
elif d['type'] == 'print':
l = 'System.out.println(' + ' + " " + '.join(self.parse_arguments(d['arguments'])) + ')'
elif d['type'] == 'function':
l = self.map_function(d['function']) + '(' + ', '.join(self.parse_arguments(d['arguments'])) + ')'
elif d['type'] == 'vector':
l = '{' + ', '.join(self.parse_arguments(d['arguments'])) + '}'
elif d['type'] == 'enum':
l = self.enum_name_mapping[d['enum']] + '.' + d['key']
elif d['type'] == 'class_dereference':
l = d['name'] + '.' + self.dict2string(d['RHS'])
elif d['type'] == 'custom_assignment':
type_name = self.type_name_mapping[d['variable_type']]
if type_name:
LHS = type_name + ' ' + d['variable_name']
else:
LHS = d['variable_name']
if d['RHS']['type'] != 'vector':
RHS = self.dict2string(d['RHS'])
else: # Custom processing for vector assignment
pushes = [d['variable_name'] + '.add(' + arg + ');' for arg in d['RHS']['arguments']]
RHS = 'new DoubleVector(); ' + ' '.join(pushes)
l = ' '.join([LHS, '=', RHS])
else:
raise ValueError
if 'EOL' in d and d['EOL']:
l += ';'
return l
def header(self):
return 'public class Example {\n static {\n System.loadLibrary("CoolProp");\n }\n\n public static void main(String argv[]){\n'
def footer(self):
return '\n }\n}'
class Csharp(BaseParser):
function_name_mapping = dict(Props1SI='CoolProp.Props1SI',
PropsSI='CoolProp.PropsSI',
PhaseSI='CoolProp.PhaseSI',
HAPropsSI='CoolProp.HAPropsSI',
get_global_param_string='CoolProp.get_global_param_string',
factory='AbstractState.factory')
type_name_mapping = {'vector': "DoubleVector",
'AbstractState': 'AbstractState'}
enum_name_mapping = {'input_pairs': "input_pairs", 'parameters': "parameters"}
indentation = ' ' * 12
def parse_arguments(self, arguments):
out = []
for arg in arguments:
if isinstance(arg, string_types) and arg[0] == "'" and arg[-1] == "'":
out.append('\"' + arg[1:-1] + '\"')
elif isinstance(arg, dict):
out.append(self.dict2string(arg))
else:
out.append(arg)
return out
def dict2string(self, d):
if d['type'] == 'comment':
l = '// ' + d['comment']
elif d['type'] == 'print':
l = 'Console.Write(' + ' + " " + '.join(self.parse_arguments(d['arguments'])) + ' + "\\n")'
elif d['type'] == 'function':
l = self.map_function(d['function']) + '(' + ', '.join(self.parse_arguments(d['arguments'])) + ')'
elif d['type'] == 'vector':
l = 'new DoubleVector(new double[]{' + ', '.join(self.parse_arguments(d['arguments'])) + '})'
elif d['type'] == 'enum':
l = self.enum_name_mapping[d['enum']] + '.' + d['key']
elif d['type'] == 'class_dereference':
l = d['name'] + '.' + self.dict2string(d['RHS'])
elif d['type'] == 'custom_assignment':
type_name = self.type_name_mapping[d['variable_type']]
if type_name:
LHS = type_name + ' ' + d['variable_name']
else:
LHS = d['variable_name']
l = ' '.join([LHS, '=', self.dict2string(d['RHS'])])
else:
raise ValueError
if 'EOL' in d and d['EOL']:
l += ';'
return l
def header(self):
return 'using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace ConsoleApplication1\n{\n class Program\n {\n static void Main(string[] args)\n {\n'
def footer(self):
return '\n }\n }\n}'
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("language", help="The target language (Python, Java, Csharp, etc.)")
parser.add_argument("destination", help="The path to the output file")
args = parser.parse_args()
writer = locals()[args.language]()
writer.write(args.destination, writer.parse())
print("written to %s" % args.destination)