@@ -33,7 +33,9 @@ def element_type(element):
33
33
"""
34
34
Determine if an element is a list then pass to num_type()
35
35
"""
36
- if ',' in element : # Detect a list
36
+ if ',' in element : # Detect a list.
37
+ # .pan/.ond don't use ',' to indicate 1000. If that changes,
38
+ # a new method of list detection needs to be found.
37
39
values = element .split (',' )
38
40
element_out = []
39
41
for val in values : # Determine datatype of each value
@@ -66,6 +68,46 @@ def parse_panond(fbuf):
66
68
67
69
Notes
68
70
-----
71
+ The parser was intended for use with .pan and .ond files that were created
72
+ for use by PVsyst. At time of publication, no documentation for these
73
+ files was available. So, this parser is based on inferred logic, rather
74
+ than anything specified by PVsyst.
75
+
76
+ The parser assumes that the file being parsed uses indendation of two
77
+ spaces (' ') to create new level in a nested dicitonary, and that
78
+ key/values pairs of interest are separated using '='. This further means
79
+ that lines not containing '=' were ommitted from the final returned
80
+ dictionary.
81
+
82
+ Additionally, the indented lines often contain values themselves. This
83
+ leads to a conflict with the .pan/.ond file and the ability of nested
84
+ dicitonaries to capture that information. The solution implemented here is
85
+ to repeat that key to the new nested dictioary within that new level.
86
+ Example below.
87
+
88
+ Sample file:
89
+
90
+ 'level1 = first level
91
+ key1 = value1
92
+ level2 = second level
93
+ key2 = value2'
94
+
95
+ output:
96
+
97
+ {
98
+ level1: first level
99
+ key1: value1,
100
+ level2:{
101
+ level2: second level,
102
+ key2: value2
103
+ }
104
+ }
105
+
106
+ The parser takes an additional step to infer the datatype present in
107
+ each value. The .pan/.ond files appear to have intentially left datatype
108
+ indicators (e.g. floats have '.' decimals). However, there is still the
109
+ possibility that the datatype applied from this parser is incorrect. In
110
+ that event the user would need to convert to the desired datatype.
69
111
70
112
See Also
71
113
--------
@@ -84,15 +126,19 @@ def parse_panond(fbuf):
84
126
continue
85
127
# Reading blank lines. Stopping one short to avoid index error.
86
128
# Last line never contains important data.
129
+ # Creating variables to assist new level in dictionary creation logic
87
130
indent_lvl_1 = (len (lines [i ]) - len (lines [i ].lstrip (' ' ))) // 2
88
131
indent_lvl_2 = (len (lines [i + 1 ]) - len (lines [i + 1 ].lstrip (' ' ))) // 2
132
+ # Split the line into key/value pair
89
133
line_data = lines [i ].split ('=' )
90
134
key = line_data [0 ].strip ()
135
+ # Logical to make sure there is a value to extract
91
136
if len (line_data ) > 1 :
92
137
value = element_type (line_data [1 ].strip ())
93
138
else :
94
139
value = None
95
- # add a level to the dict. The key here will be ignored.
140
+ # add a level to the dict. If a key/value pair triggers the new level,
141
+ # the key/value will be repeated in the new dict level.
96
142
# Not vital to file function.
97
143
if indent_lvl_2 > indent_lvl_1 :
98
144
current_level = dict_levels [indent_lvl_1 ]
@@ -131,6 +177,9 @@ def read_panond(file):
131
177
132
178
Notes
133
179
-----
180
+ The read function simply converts a file path to a file-like object and
181
+ passes it to the parser. At time of creation, tested .pan/.ond files used
182
+ UTF-8 encoding.
134
183
135
184
See Also
136
185
--------
0 commit comments