Skip to content

Commit df26efa

Browse files
authored
add more attributes to __repr__ methods (#254)
* add more attributes to ModelChain repr * reprs for PVSystem and Location * add tracking repr * add name attribute to PVSystem and ModelChain * update tests * specify gcr in test to avoid platform dependent float precision
1 parent 50829ae commit df26efa

File tree

9 files changed

+82
-54
lines changed

9 files changed

+82
-54
lines changed

docs/sphinx/source/whatsnew/v0.4.2.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ Enhancements
3636
* Added calculate_deltat method to the spa module to calculate the
3737
time difference between terrestrial time and UT1. Specifying a scalar
3838
is sufficient for most calculations. (:issue:`165`)
39+
* Added more attributes to ModelChain, PVSystem, and Location printed
40+
representations. (:issue:`254`)
41+
* Added name attribute to ModelChain and PVSystem. (:issue:`254`)
3942

4043
Code Contributors
4144
~~~~~~~~~~~~~~~~~

pvlib/location.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ def __init__(self, latitude, longitude, tz='UTC', altitude=0,
8484
# super(Location, self).__init__(**kwargs)
8585

8686
def __repr__(self):
87-
return ('{}: latitude={}, longitude={}, tz={}, altitude={}'
88-
.format(self.name, self.latitude, self.longitude,
89-
self.tz, self.altitude))
87+
attrs = ['name', 'latitude', 'longitude', 'altitude', 'tz']
88+
return ('Location: \n ' + '\n '.join(
89+
(attr + ': ' + str(getattr(self, attr)) for attr in attrs)))
9090

9191
@classmethod
9292
def from_tmy(cls, tmy_metadata, tmy_data=None, **kwargs):

pvlib/modelchain.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,10 @@ def __init__(self, system, location,
299299
dc_model=None, ac_model=None, aoi_model=None,
300300
spectral_model=None, temp_model='sapm',
301301
losses_model='no_loss',
302+
name=None,
302303
**kwargs):
303304

305+
self.name = name
304306
self.system = system
305307
self.location = location
306308
self.clearsky_model = clearsky_model
@@ -322,12 +324,24 @@ def __init__(self, system, location,
322324
self.solar_position = None
323325

324326
def __repr__(self):
325-
return ('ModelChain for: ' + str(self.system) +
326-
' orientation_strategy: ' + str(self.orientation_strategy) +
327-
' clearsky_model: ' + str(self.clearsky_model) +
328-
' transposition_model: ' + str(self.transposition_model) +
329-
' solar_position_method: ' + str(self.solar_position_method) +
330-
' airmass_model: ' + str(self.airmass_model))
327+
attrs = [
328+
'name', 'orientation_strategy', 'clearsky_model',
329+
'transposition_model', 'solar_position_method',
330+
'airmass_model', 'dc_model', 'ac_model', 'aoi_model',
331+
'spectral_model', 'temp_model', 'losses_model'
332+
]
333+
334+
def getmcattr(self, attr):
335+
"""needed to avoid recursion in property lookups"""
336+
out = getattr(self, attr)
337+
try:
338+
out = out.__name__
339+
except AttributeError:
340+
pass
341+
return out
342+
343+
return ('ModelChain: \n ' + '\n '.join(
344+
(attr + ': ' + getmcattr(self, attr) for attr in attrs)))
331345

332346
@property
333347
def orientation_strategy(self):

pvlib/pvsystem.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,11 @@ def __init__(self,
116116
modules_per_string=1, strings_per_inverter=1,
117117
inverter=None, inverter_parameters=None,
118118
racking_model='open_rack_cell_glassback',
119+
name=None,
119120
**kwargs):
120121

122+
self.name = name
123+
121124
self.surface_tilt = surface_tilt
122125
self.surface_azimuth = surface_azimuth
123126

@@ -144,10 +147,10 @@ def __init__(self,
144147
super(PVSystem, self).__init__(**kwargs)
145148

146149
def __repr__(self):
147-
return ('PVSystem with tilt:' + str(self.surface_tilt) +
148-
' and azimuth: ' + str(self.surface_azimuth) +
149-
' with Module: ' + str(self.module) +
150-
' and Inverter: ' + str(self.inverter))
150+
attrs = ['name', 'surface_tilt', 'surface_azimuth', 'module',
151+
'inverter', 'albedo', 'racking_model']
152+
return ('PVSystem: \n ' + '\n '.join(
153+
(attr + ': ' + str(getattr(self, attr)) for attr in attrs)))
151154

152155
def get_aoi(self, solar_zenith, solar_azimuth):
153156
"""Get the angle of incidence on the system.
@@ -575,12 +578,12 @@ def __init__(self, pvsystem=None, location=None, **kwargs):
575578
super(LocalizedPVSystem, self).__init__(**new_kwargs)
576579

577580
def __repr__(self):
578-
return ('LocalizedPVSystem with tilt:' + str(self.surface_tilt) +
579-
' and azimuth: ' + str(self.surface_azimuth) +
580-
' with Module: ' + str(self.module) +
581-
' and Inverter: ' + str(self.inverter) +
582-
' at Latitude: ' + str(self.latitude) +
583-
' and Longitude: ' + str(self.longitude))
581+
attrs = [
582+
'name', 'latitude', 'longitude', 'altitude', 'tz', 'surface_tilt',
583+
'surface_azimuth', 'module', 'inverter', 'albedo', 'racking_model'
584+
]
585+
return ('LocalizedPVSystem: \n ' + '\n '.join(
586+
(attr + ': ' + str(getattr(self, attr)) for attr in attrs)))
584587

585588

586589
def systemdef(meta, surface_tilt, surface_azimuth, albedo, modules_per_string,

pvlib/test/test_location.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ def test_location_invalid_tz_type():
4242

4343
def test_location_print_all():
4444
tus = Location(32.2, -111, 'US/Arizona', 700, 'Tucson')
45-
expected_str = 'Tucson: latitude=32.2, longitude=-111, tz=US/Arizona, altitude=700'
45+
expected_str = 'Location: \n name: Tucson\n latitude: 32.2\n longitude: -111\n altitude: 700\n tz: US/Arizona'
4646
assert tus.__str__() == expected_str
4747

4848
def test_location_print_pytz():
4949
tus = Location(32.2, -111, aztz, 700, 'Tucson')
50-
expected_str = 'Tucson: latitude=32.2, longitude=-111, tz=US/Arizona, altitude=700'
50+
expected_str = 'Location: \n name: Tucson\n latitude: 32.2\n longitude: -111\n altitude: 700\n tz: US/Arizona'
5151
assert tus.__str__() == expected_str
5252

5353

@@ -283,5 +283,6 @@ def test_get_airmass_valueerror():
283283

284284
def test_Location___repr__():
285285
tus = Location(32.2, -111, 'US/Arizona', 700, 'Tucson')
286-
assert tus.__repr__()==('Tucson: latitude=32.2, longitude=-111, '+
287-
'tz=US/Arizona, altitude=700')
286+
287+
expected = 'Location: \n name: Tucson\n latitude: 32.2\n longitude: -111\n altitude: 700\n tz: US/Arizona'
288+
assert tus.__repr__() == expected

pvlib/test/test_modelchain.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,12 @@ def test_ModelChain___repr__(system, location):
408408

409409
strategy = 'south_at_latitude_tilt'
410410

411-
mc = ModelChain(system, location, orientation_strategy=strategy)
411+
mc = ModelChain(system, location, orientation_strategy=strategy,
412+
name='my mc')
413+
414+
expected = 'ModelChain: \n name: my mc\n orientation_strategy: south_at_latitude_tilt\n clearsky_model: ineichen\n transposition_model: haydavies\n solar_position_method: nrel_numpy\n airmass_model: kastenyoung1989\n dc_model: sapm\n ac_model: snlinverter\n aoi_model: sapm_aoi_loss\n spectral_model: sapm_spectral_loss\n temp_model: sapm_temp\n losses_model: no_extra_losses'
412415

413-
assert mc.__repr__() == ('ModelChain for: PVSystem with tilt:32.2 and '+
414-
'azimuth: 180 with Module: None and Inverter: None '+
415-
'orientation_strategy: south_at_latitude_tilt clearsky_model: '+
416-
'ineichen transposition_model: haydavies solar_position_method: '+
417-
'nrel_numpy airmass_model: kastenyoung1989')
416+
assert mc.__repr__() == expected
418417

419418

420419
@requires_scipy

pvlib/test/test_pvsystem.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -672,19 +672,21 @@ def test_PVSystem_localize_with_latlon():
672672

673673

674674
def test_PVSystem___repr__():
675-
system = pvsystem.PVSystem(module='blah', inverter='blarg')
675+
system = pvsystem.PVSystem(module='blah', inverter='blarg', name='pv ftw')
676+
677+
expected = 'PVSystem: \n name: pv ftw\n surface_tilt: 0\n surface_azimuth: 180\n module: blah\n inverter: blarg\n albedo: 0.25\n racking_model: open_rack_cell_glassback'
676678

677-
assert system.__repr__()==('PVSystem with tilt:0 and azimuth:'+
678-
' 180 with Module: blah and Inverter: blarg')
679+
assert system.__repr__() == expected
679680

680681

681682
def test_PVSystem_localize___repr__():
682-
system = pvsystem.PVSystem(module='blah', inverter='blarg')
683+
system = pvsystem.PVSystem(module='blah', inverter='blarg', name='pv ftw')
683684
localized_system = system.localize(latitude=32, longitude=-111)
684685

685-
assert localized_system.__repr__()==('LocalizedPVSystem with tilt:0 and'+
686-
' azimuth: 180 with Module: blah and Inverter: blarg at '+
687-
'Latitude: 32 and Longitude: -111')
686+
expected = 'LocalizedPVSystem: \n name: None\n latitude: 32\n longitude: -111\n altitude: 0\n tz: UTC\n surface_tilt: 0\n surface_azimuth: 180\n module: blah\n inverter: blarg\n albedo: 0.25\n racking_model: open_rack_cell_glassback'
687+
688+
assert localized_system.__repr__() == expected
689+
688690

689691
# we could retest each of the models tested above
690692
# when they are attached to LocalizedPVSystem, but
@@ -707,11 +709,12 @@ def test_LocalizedPVSystem___repr__():
707709
localized_system = pvsystem.LocalizedPVSystem(latitude=32,
708710
longitude=-111,
709711
module='blah',
710-
inverter='blarg')
712+
inverter='blarg',
713+
name='my name')
714+
715+
expected = 'LocalizedPVSystem: \n name: None\n latitude: 32\n longitude: -111\n altitude: 0\n tz: UTC\n surface_tilt: 0\n surface_azimuth: 180\n module: blah\n inverter: blarg\n albedo: 0.25\n racking_model: open_rack_cell_glassback'
711716

712-
assert localized_system.__repr__()==('LocalizedPVSystem with tilt:0 and'+
713-
' azimuth: 180 with Module: blah and Inverter: blarg at Latitude: 32 ' +
714-
'and Longitude: -111')
717+
assert localized_system.__repr__() == expected
715718

716719

717720
def test_pvwatts_dc_scalars():

pvlib/test/test_tracking.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,19 +284,18 @@ def test_get_irradiance():
284284
def test_SingleAxisTracker___repr__():
285285
system = tracking.SingleAxisTracker(max_angle=45, gcr=.25,
286286
module='blah', inverter='blarg')
287-
288-
assert system.__repr__() == 'SingleAxisTracker with max_angle: 45'
287+
expected = 'SingleAxisTracker: \n axis_tilt: 0\n axis_azimuth: 0\n max_angle: 45\n backtrack: True\n gcr: 0.25\n name: None\n surface_tilt: 0\n surface_azimuth: 180\n module: blah\n inverter: blarg\n albedo: 0.25\n racking_model: open_rack_cell_glassback'
288+
assert system.__repr__() == expected
289289

290290

291291
def test_LocalizedSingleAxisTracker___repr__():
292292
localized_system = tracking.LocalizedSingleAxisTracker(latitude=32,
293293
longitude=-111,
294294
module='blah',
295-
inverter='blarg')
295+
inverter='blarg',
296+
gcr=0.25)
296297

298+
expected = 'LocalizedSingleAxisTracker: \n axis_tilt: 0\n axis_azimuth: 0\n max_angle: 90\n backtrack: True\n gcr: 0.25\n name: None\n surface_tilt: 0\n surface_azimuth: 180\n module: blah\n inverter: blarg\n albedo: 0.25\n racking_model: open_rack_cell_glassback\n latitude: 32\n longitude: -111\n altitude: 0\n tz: UTC'
297299

298-
assert localized_system.__repr__() == ('LocalizedSingleAxisTracker with '+
299-
'max_angle: 90 at Location: None: '+
300-
'latitude=32, longitude=-111, ' +
301-
'tz=UTC, altitude=0')
300+
assert localized_system.__repr__() == expected
302301

pvlib/tracking.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,15 @@ def __init__(self, axis_tilt=0, axis_azimuth=0,
2929
super(SingleAxisTracker, self).__init__(**kwargs)
3030

3131
def __repr__(self):
32-
return ('SingleAxisTracker with max_angle: ' +
33-
str(self.max_angle))
32+
attrs = ['axis_tilt', 'axis_azimuth', 'max_angle', 'backtrack', 'gcr']
33+
sat_repr = ('SingleAxisTracker: \n ' + '\n '.join(
34+
(attr + ': ' + str(getattr(self, attr)) for attr in attrs)))
35+
# get the parent PVSystem info
36+
pvsystem_repr = super(SingleAxisTracker, self).__repr__()
37+
# remove the first line (contains 'PVSystem: \n')
38+
pvsystem_repr = '\n'.join(pvsystem_repr.split('\n')[1:])
39+
return sat_repr + '\n' + pvsystem_repr
40+
3441

3542
def singleaxis(self, apparent_zenith, apparent_azimuth):
3643
tracking_data = singleaxis(apparent_zenith, apparent_azimuth,
@@ -158,12 +165,11 @@ def __init__(self, pvsystem=None, location=None, **kwargs):
158165
super(LocalizedSingleAxisTracker, self).__init__(**new_kwargs)
159166

160167
def __repr__(self):
168+
attrs = ['latitude', 'longitude', 'altitude', 'tz']
161169
return ('Localized' +
162-
super(LocalizedSingleAxisTracker, self).__repr__() +
163-
' at Location: ' +
164-
('{}: latitude={}, longitude={}, tz={}, altitude={}'
165-
.format(self.name, self.latitude, self.longitude,
166-
self.tz, self.altitude)))
170+
super(LocalizedSingleAxisTracker, self).__repr__() + '\n ' +
171+
'\n '.join(
172+
(attr + ': ' + str(getattr(self, attr)) for attr in attrs)))
167173

168174

169175
def singleaxis(apparent_zenith, apparent_azimuth,

0 commit comments

Comments
 (0)