Solar Generation

We have a text file with information about the power generated by a solar plant. Each line contains the data corresponding to a solar panel. It includes the following data separated by ';' :

  • the id of the group where the solar panel belongs to

  • its localization inside the group

  • its status (whether is 'on' or 'off')

  • a sequence of the measures of the power generated by the panel at different times: each measure is either a float value or the string '*' which indicates that the measurement system failed.

For example, see the first 5 lines of (first 5 panels) of the file solargen_data.txt:

gA;3-15;on;3.5;2.5;4.0;*;7.0;3.2;4.0
gA;3-16;off;0.0;0.2;0.0;*;0.3;*
gA;3-17;on;3.0;3.3;4.4;2.0;7.0;3.0;4.0;5.0
gB;1-1;on;2.3;3.5
gB;1-2;on;2.7;3.8

Notice that the panel '3-15' in group 'gA' generated \(3.5+2.5+4.0+7.0+3.2+4.0 = 24.2\) kWh, and the total generated by group 'gA' is \(= 55.9\) kWh ( \(24.2\) from panel '3-15' plus \(31.7\) from panel '3-17', and nothing from panel '3-16' since it is off).

You are required to implement the following functions in the module solargen.py (file solargen.py):


Extraction

Program the function:

solargen_extract(filename)

such that given

a str with the filename of a file with data from a solar generation plant as described above

returns

a list where each component is a sublist corresponding only to the panels in filename which status is 'on'. For each line the sublist contains a str with the group id, and a sequence of float with the measures that are not an '*'.

The following example shows the result of extracting the data from the solargen_data.txt file:

>>> from solargen import solargen_extract

>>> sg1L = solargen_extract('solargen_data.txt')
>>> sg1L_corr = [
... ['gA', 3.5, 2.5, 4.0, 7.0, 3.2, 4.0],
... ['gA', 3.0, 3.3, 4.4, 2.0, 7.0, 3.0, 4.0, 5.0],
... ['gB', 2.3, 3.5],
... ['gB', 2.7, 3.8],
... ['gB', 3.3, 3.9],
... ['gC', 3.6, 4.0, 7.0, 4.5, 3.0],
... ['gC', 2.4, 3.0, 4.1],
... ['gC', 3.3, 4.0, 3.9, 3.2],
... ['gB', 4.1, 4.1, 4],
... ['gB', 2.9, 2.0, 4.3],
... ]

>>> if sg1L == sg1L_corr:
...     True
... else:
...     print(sg1L)
...     print(sg1L_corr)
True

This file is available at solargen_extract-test.txt.


Addition

Program the function:

solargen_sum(solargen_L)

such that given

a list like the one produced by the previous function solargen_extract

returns

a dict that associates each group name (str) to a two-component list, both calculated according to the info in the input list solargen_L:

  1. A float with the total power of the group (namely the sum of the power measures of all the panels belonging to that group)

  2. An int with the number of measures coming from active panels of that group

The following example shows the dict resulting from the previous list:

>>> from solargen import solargen_sum

>>> sgL = [
... ['gA', 3.5, 2.5, 4.0, 7.0, 3.2, 4.0],
... ['gA', 3.0, 3.3, 4.4, 2.0, 7.0, 3.0, 4.0, 5.0],
... ['gB', 2.3, 3.5],
... ['gB', 2.7, 3.8],
... ['gB', 3.3, 3.9],
... ['gC', 3.6, 4.0, 7.0, 4.5, 3.0],
... ['gC', 2.4, 3.0, 4.1],
... ['gC', 3.3, 4.0, 3.9, 3.2],
... ['gB', 4.1, 4.1, 4],
... ['gB', 2.9, 2.0, 4.3],
... ]

>>> sgD = solargen_sum(sgL)
>>> sgD_corr = {'gA': [55.9, 14], 'gB': [40.9, 12], 'gC': [46.0, 12]}

>>> if sgD == sgD_corr:
...     True
... else:
...     print(sgD)
...     print(sgD_corr)
True

This file is available at solargen_sum-test.txt.


Sorting

Program the function:

solargen_sort(sum_D)

such that given

a dict like the one produced by the previous function solargen_sum

returns

a list with a component for each key in sum_D (namely a group), with the info calculated and ordered according to the info in the input dict sum_D. The info for each group has the form of the following 4-place tuple:

  1. a str with the group id

  2. a 3-decimals float with the power per panel average

  3. a float with the sum of the power generated by all the panels belonging to that group (as in the input dict)

  4. a int with the number of measures coming from active panels of that group (as in the input dict).

The ordering of the list is determined by following criteria:

  1. Decreasing order of the integer part of the power per panel average

  2. Increasing order of the number of measures

  3. Decreasing order of the total power

For example, given the dict sumD = {'gA': 55.9, 'gB': 40.9, 'gC': 46.0}, the output of solargen_sort(sum_D) should be [('gC', 3.833, 46.0, 12), ('gB', 3.408, 40.9, 12), ('gA', 3.993, 55.9, 14)]. Notice that:

  1. There is a component for each group which includes the group id, the power/panel average rounded to 3 decimals, the total power of that group, and its number of measures coming from active panels.

  2. They would be first ordered by the integer part of the power/panel average but this is 3 in all groups. Therefore they are increasingly ordered by the number of panels (12, 12 and 14) and finally, decreasing but the total power: first gC with 46.0 and then gB with 40.9.

The following example shows the dict resulting from the previous list:

>>> from solargen import solargen_sort

>>> sumD = {'gA': [55.9, 14], 'gB': [40.9, 12], 'gC': [46.0, 12]}
>>> ordsumL = solargen_sort(sumD)
>>> ordsumL_corr = [('gC', 3.833, 46.0, 12), ('gB', 3.408, 40.9, 12), ('gA', 3.993, 55.9, 14)]
>>> if ordsumL == ordsumL_corr:
...     True
... else:
...     print(ordsumL)
...     print(ordsumL_corr)
True

This file is available at solargen_sort-test.txt.


Writting

Program the function:

solargen_write(ls, filename)

such that given

  • ls a list like the one produced by the previous function solargen_sort

  • filename a str with the name of an output fil

does two things:

  • writes a line in the file filename for each group with the following info serparated by ';':

    • the group

    • the power per panel average rounded to 3 decimals

    • the total power

    • the number of measures coming from active panels

  • returns the number of lines written (which should correspond to the number of groups for which the power generated has been calculated).

For instance, the call solargen_write(ls, 'sgout.txt'), where ls is the list produced by te previous function, should return 3 and produce the following file:

gC;3.833;46.0;12
gB;3.408;40.9;12
gA;3.993;55.9;14

A doctest file is available at solargen_write-test.txt.