diff --git a/city_model_structure/surface.py b/city_model_structure/surface.py index 0776461d..6486c762 100644 --- a/city_model_structure/surface.py +++ b/city_model_structure/surface.py @@ -7,7 +7,7 @@ from __future__ import annotations from typing import Union import numpy as np import pyny3d.geoms as pn -from helpers.geometry import Geometry +from helpers.geometry_helper import GeometryHelper class Surface: @@ -21,7 +21,7 @@ class Surface: self._swr = swr self._remove_last = remove_last self._is_projected = is_projected - self._geometry = Geometry() + self._geometry_helper = GeometryHelper() self._polygon = None self._ground_polygon = None self._area = None @@ -89,7 +89,7 @@ class Surface: """ if self._points is None: self._points = np.fromstring(self._coordinates, dtype=float, sep=' ') - self._points = Geometry.to_points_matrix(self._points, self._remove_last) + self._points = GeometryHelper.to_points_matrix(self._points, self._remove_last) return self._points def _min_coord(self, axis): @@ -153,7 +153,7 @@ class Surface: coordinates = coordinates + ' ' coordinates = coordinates + str(x) + ' ' + str(y) + ' ' + str(z) self._ground_points = np.fromstring(coordinates, dtype=float, sep=' ') - self._ground_points = Geometry.to_points_matrix(self._ground_points, False) + self._ground_points = GeometryHelper.to_points_matrix(self._ground_points, False) return self._ground_points @property @@ -309,7 +309,7 @@ class Surface: """ if self.type != 'Wall' or surface.type != 'Wall': return - if self._geometry.is_almost_same_surface(self, surface): + if self._geometry_helper.is_almost_same_surface(self, surface): intersection_area = self.intersect(surface).area self.add_shared(surface, intersection_area) surface.add_shared(self, intersection_area) diff --git a/city_model_structure/thermal_boundary.py b/city_model_structure/thermal_boundary.py index 88048198..01bb6181 100644 --- a/city_model_structure/thermal_boundary.py +++ b/city_model_structure/thermal_boundary.py @@ -7,7 +7,7 @@ from typing import List from city_model_structure.thermal_opening import ThermalOpening from city_model_structure.thermal_zone import ThermalZone from city_model_structure.layer import Layer -from helpers.configuration import Configuration +from helpers.configuration_helper import ConfigurationHelper class ThermalBoundary: @@ -20,7 +20,7 @@ class ThermalBoundary: # ToDo: up to at least LOD2 will be just one thermal opening per Thermal boundary, review for LOD3 and LOD4 self._thermal_openings = [ThermalOpening()] self._layers = None - self._outside_solar_absorptance = Configuration().outside_solar_absorptance + self._outside_solar_absorptance = ConfigurationHelper().outside_solar_absorptance self._outside_thermal_absorptance = None self._outside_visible_absorptance = None self._window_ratio = None @@ -208,8 +208,8 @@ class ThermalBoundary: :return: float """ if self._u_value is None: - h_i = Configuration().h_i - h_e = Configuration().h_e + h_i = ConfigurationHelper().h_i + h_e = ConfigurationHelper().h_e r_value = 1.0/h_i + 1.0/h_e try: for layer in self.layers: diff --git a/city_model_structure/thermal_opening.py b/city_model_structure/thermal_opening.py index 4623be31..f5ab59a9 100644 --- a/city_model_structure/thermal_opening.py +++ b/city_model_structure/thermal_opening.py @@ -3,7 +3,7 @@ ThermalOpening module SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca """ -from helpers.configuration import Configuration +from helpers.configuration_helper import ConfigurationHelper class ThermalOpening: @@ -13,7 +13,7 @@ class ThermalOpening: def __init__(self): self._openable_ratio = None self._conductivity = None - self._frame_ratio = Configuration().frame_ratio + self._frame_ratio = ConfigurationHelper().frame_ratio self._g_value = None self._thickness = None self._front_side_solar_transmittance_at_normal_incidence = None @@ -56,8 +56,8 @@ class ThermalOpening: # This ensures a more robust code that returns the overall_u_value regardless the order the parameters are read. self._conductivity = value if self._overall_u_value is None and self.thickness is not None: - h_i = Configuration().h_i - h_e = Configuration().h_e + h_i = ConfigurationHelper().h_i + h_e = ConfigurationHelper().h_e r_value = 1 / h_i + 1 / h_e + float(self.conductivity) / float(self.thickness) self._overall_u_value = 1 / r_value @@ -114,8 +114,8 @@ class ThermalOpening: # This ensures a more robust code that returns the overall_u_value regardless the order the parameters are read. self._thickness = value if self._overall_u_value is None and self.conductivity is not None: - h_i = Configuration().h_i - h_e = Configuration().h_e + h_i = ConfigurationHelper().h_i + h_e = ConfigurationHelper().h_e r_value = 1 / h_i + 1 / h_e + float(self.conductivity) / float(self.thickness) self._overall_u_value = 1 / r_value @@ -156,7 +156,7 @@ class ThermalOpening: @property def overall_u_value(self): """ - Get thermal opening overall u value + Get thermal opening overall u value in W/m2K :return: float """ return self._overall_u_value @@ -164,7 +164,7 @@ class ThermalOpening: @overall_u_value.setter def overall_u_value(self, value): """ - Get thermal opening overall u value + Get thermal opening overall u value in W/m2K :param value: float :return: None """ diff --git a/city_model_structure/thermal_zone.py b/city_model_structure/thermal_zone.py index 60c5a0d3..5c3638c9 100644 --- a/city_model_structure/thermal_zone.py +++ b/city_model_structure/thermal_zone.py @@ -6,7 +6,7 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc from typing import List, TypeVar from city_model_structure.usage_zone import UsageZone from city_model_structure.surface import Surface -from helpers.configuration import Configuration +from helpers.configuration_helper import ConfigurationHelper ThermalBoundary = TypeVar('ThermalBoundary') @@ -19,12 +19,12 @@ class ThermalZone: self._surfaces = surfaces self._floor_area = None self._bounded = None - self._heated = Configuration().heated - self._cooled = Configuration().cooled - self._additional_thermal_bridge_u_value = Configuration().additional_thermal_bridge_u_value + self._heated = ConfigurationHelper().heated + self._cooled = ConfigurationHelper().cooled + self._additional_thermal_bridge_u_value = ConfigurationHelper().additional_thermal_bridge_u_value self._effective_thermal_capacity = None - self._indirectly_heated_area_ratio = Configuration().indirectly_heated_area_ratio - self._infiltration_rate_system_on = Configuration().infiltration_rate_system_on + self._indirectly_heated_area_ratio = ConfigurationHelper().indirectly_heated_area_ratio + self._infiltration_rate_system_on = ConfigurationHelper().infiltration_rate_system_on self._infiltration_rate_system_off = None self._usage_zones = None @@ -85,7 +85,7 @@ class ThermalZone: @property def additional_thermal_bridge_u_value(self): """ - Get thermal zone additional thermal bridge u value + Get thermal zone additional thermal bridge u value W/m2K :return: float """ return self._additional_thermal_bridge_u_value @@ -93,7 +93,7 @@ class ThermalZone: @additional_thermal_bridge_u_value.setter def additional_thermal_bridge_u_value(self, value): """ - Set thermal zone additional thermal bridge u value + Set thermal zone additional thermal bridge u value W/m2K :param value: float :return: None """ diff --git a/helpers/configuration.py b/helpers/configuration.py deleted file mode 100644 index 803266f1..00000000 --- a/helpers/configuration.py +++ /dev/null @@ -1,91 +0,0 @@ -""" -Configuration helper -SPDX - License - Identifier: LGPL - 3.0 - or -later -Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca -""" -import configparser -from pathlib import Path - - -class Configuration: - """ - Configuration class - """ - def __init__(self): - base_path = Path().resolve().parent - config_file = Path(base_path / 'libs/config/configuration.ini').resolve() - self._config = configparser.ConfigParser() - self._config.read(config_file) - - @property - def h_i(self): - """ - Configured internal convective coefficient in W/m2K - :return: float - """ - return self._config.getfloat('convective_fluxes', 'h_i') - - @property - def h_e(self): - """ - Configured external convective coefficient in W/m2K - :return: float - """ - return self._config.getfloat('convective_fluxes', 'h_e') - - @property - def frame_ratio(self): - """ - Configured frame ratio - :return: float - """ - return self._config.getfloat('windows', 'frame_ratio') - - @property - def heated(self): - """ - Configured heated flag - :return: Boolean - """ - return self._config.getboolean('thermal_zones', 'heated') - - @property - def cooled(self): - """ - Configured cooled flag - :return: Boolean - """ - return self._config.getboolean('thermal_zones', 'cooled') - - @property - def additional_thermal_bridge_u_value(self): - """ - Configured additional thermal bridge u value W/m2K - :return: - """ - return self._config.getfloat('thermal_zones', 'additional_thermal_bridge_u_value') - - @property - def indirectly_heated_area_ratio(self): - """ - Configured indirectly heated area ratio - :return: float - """ - - return self._config.getfloat('thermal_zones', 'indirectly_heated_area_ratio') - - @property - def infiltration_rate_system_on(self): - """ - Configured infiltration rate system on in air change per hour - :return: float - """ - return self._config.getfloat('thermal_zones', 'infiltration_rate_system_on') - - @property - def outside_solar_absorptance(self): - """ - Configured infiltration rate system off in air change per hour - :return: float - """ - return self._config.getfloat('thermal_zones', 'outside_solar_absorptance') diff --git a/helpers/geometry.py b/helpers/geometry.py deleted file mode 100644 index 09689f26..00000000 --- a/helpers/geometry.py +++ /dev/null @@ -1,165 +0,0 @@ -""" -Geometry helper -SPDX - License - Identifier: LGPL - 3.0 - or -later -Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca -""" -import math -import numpy as np -from trimesh import Trimesh -from trimesh import intersections -import open3d as o3d - - -class Geometry: - """ - Geometry helper class - """ - def __init__(self, delta=0.5): - self._delta = delta - - def almost_equal(self, v1, v2): - """ - Compare two points and decides if they are almost equal (quadratic error under delta) - :param v1: [x,y,z] - :param v2: [x,y,z] - :return: Boolean - """ - delta = math.sqrt(pow((v1[0] - v2[0]), 2) + pow((v1[1] - v2[1]), 2) + pow((v1[2] - v2[2]), 2)) - return delta <= self._delta - - def is_almost_same_surface(self, s1, s2): - """ - Compare two surfaces and decides if they are almost equal (quadratic error under delta) - :param s1: Surface - :param s2: Surface - :return: Boolean - """ - # delta is grads an need to be converted into radians - delta = np.rad2deg(self._delta) - difference = (s1.inclination - s2.inclination) % math.pi - if abs(difference) > delta: - return False - # s1 and s2 are at least almost parallel surfaces - # calculate distance point to plane using all the vertex - # select surface1 value for the point (X,Y,Z) where two of the values are 0 - minimum_distance = self._delta + 1 - parametric = s2.polygon.get_parametric() - n2 = s2.normal - for point in s1.points: - distance = abs( - (point[0] * parametric[0]) + (point[1] * parametric[1]) + (point[2] * parametric[2]) + parametric[3]) - normal_module = math.sqrt(pow(n2[0], 2) + pow(n2[1], 2) + pow(n2[2], 2)) - - if normal_module == 0: - continue - distance = distance / normal_module - if distance < minimum_distance: - minimum_distance = distance - if minimum_distance <= self._delta: - break - if minimum_distance > self._delta or s1.intersect(s2) is None: - return False - else: - return True - - @staticmethod - def to_points_matrix(points, remove_last=False): - """ - Transform a point vector into a point matrix - :param points: [x, y, z, x, y, z ...] - :param remove_last: Boolean - :return: [[x,y,z],[x,y,z]...] - """ - rows = points.size // 3 - points = points.reshape(rows, 3) - if remove_last: - points = np.delete(points, rows - 1, 0) - return points - - @staticmethod - def _segment_list_to_point_cloud(segment_list): - point_list = np.asarray(segment_list[0]) - for segment in segment_list: - for new_point in segment: - found = False - for point in point_list: - same_point = np.allclose(new_point, point) - if same_point: - found = True - break - if not found: - point_list = np.concatenate((point_list, [new_point])) - return point_list - - @staticmethod - def _point_cloud_to_mesh(point_list, normal_list): - # Return a mesh composed only by triangles - pcd = o3d.geometry.PointCloud() - pcd.points = o3d.utility.Vector3dVector(point_list) - pcd.normals = o3d.utility.Vector3dVector(normal_list) - distances = pcd.compute_nearest_neighbor_distance() - avg_dist = np.mean(distances) - radius = 3 * avg_dist - bpa_mesh = o3d.geometry.TriangleMesh().create_from_point_cloud_ball_pivoting( - pcd, o3d.utility.DoubleVector([radius, radius * 2])) - mesh_result = Trimesh(vertices=np.asarray(bpa_mesh.vertices), faces=np.asarray(bpa_mesh.triangles)) - return mesh_result - - @staticmethod - def _merge_meshes(mesh1, mesh2): - v_1 = mesh1.vertices - f_1 = mesh1.faces - v_2 = mesh2.vertices - f_2 = mesh2.faces - length = len(v_1) - v_merge = np.concatenate((v_1, v_2)) - f_merge = np.asarray(f_1) - - for item in f_2: - point1 = item.item(0) + length - point2 = item.item(1) + length - point3 = item.item(2) + length - surface = np.asarray([point1, point2, point3]) - f_merge = np.concatenate((f_merge, [surface])) - - mesh_merge = Trimesh(vertices=v_merge, faces=f_merge) - - return mesh_merge - - @staticmethod - def divide_mesh_by_plane(mesh, normal_plane, point_plane): - """ - Divide a mesh by a plane - :param mesh: Trimesh - :param normal_plane: [x, y, z] - :param point_plane: [x, y, z] - :return: [Trimesh] - """ - # The first mesh returns the positive side of the plane and the second the negative side. - # If the plane does not divide the mesh (i.e. it does not touch it or it is coplanar with one or more faces), - # then it returns only the original mesh. - normal_plane_opp = [None] * len(normal_plane) - for i in range(0, len(normal_plane)): - normal_plane_opp[i] = - normal_plane[i] - - normal = [normal_plane, normal_plane_opp] - normal_opp = [normal_plane_opp, normal_plane] - mesh_final = [] - for i in range(0, 2): - mesh_1 = intersections.slice_mesh_plane(mesh, normal[i], point_plane) - mesh_1_segments = intersections.mesh_plane(mesh, normal[i], point_plane) - boo = mesh.difference(mesh_1, engine='blender') - print(boo) - quit() - if len(mesh_1_segments) <= 0 or len(mesh_1.faces) == len(mesh.faces): - mesh_final.append(mesh) - break - else: - points = Geometry._segment_list_to_point_cloud(mesh_1_segments) - points_normals = [[None] * 3] * len(points) - for j in range(0, len(points_normals)): - points_normals[j] = normal_opp[i] - mesh_2 = Geometry._point_cloud_to_mesh(points, points_normals) - mesh_final.append(Geometry._merge_meshes(mesh_1, mesh_2)) - - return mesh_final diff --git a/physics/physics_feeders/us_base_physics_parameters.py b/physics/physics_feeders/us_base_physics_parameters.py index b52b62b1..7b4a750f 100644 --- a/physics/physics_feeders/us_base_physics_parameters.py +++ b/physics/physics_feeders/us_base_physics_parameters.py @@ -35,7 +35,7 @@ class UsBasePhysicsParameters: archetype = self._search_archetype(building_type, UsToLibraryTypes.yoc_to_standard(city_object.year_of_construction), self._climate_zone) - # ToDo:remove this in the future + # ToDo: remove this in the future # ToDo: Raise WrongArchetype if not all the surface types are defined for the given city_object if archetype is None: print(building_type, UsToLibraryTypes.yoc_to_standard(city_object.year_of_construction), diff --git a/tests/test_geometry_factory.py b/tests/test_geometry_factory.py index 9fdcb4fa..7d763035 100644 --- a/tests/test_geometry_factory.py +++ b/tests/test_geometry_factory.py @@ -4,9 +4,9 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca """ from unittest import TestCase +import os from pathlib import Path from geometry.geometry_factory import GeometryFactory -import os class TestGeometryFactory(TestCase): @@ -21,11 +21,7 @@ class TestGeometryFactory(TestCase): self._city_gml = None self._example_path = (Path(__file__).parent.parent / 'tests_data').resolve() - def get_citygml(self): - """ - Retrieve the test city gml - :return: City - """ + def _get_citygml(self): if self._city_gml is None: file_path = (self._example_path / 'buildings.gml').resolve() self._city_gml = GeometryFactory('citygml', file_path).city @@ -37,7 +33,7 @@ class TestGeometryFactory(TestCase): Test the City parsing :return: None """ - city = self.get_citygml() + city = self._get_citygml() self.assertIsNotNone(city.city_objects, 'city_objects is none') for city_object in city.city_objects: self.assertIsNotNone(city.city_object(city_object.name), 'city_object return none') @@ -52,7 +48,7 @@ class TestGeometryFactory(TestCase): Test city objects in the city :return: None """ - city = self.get_citygml() + city = self._get_citygml() for city_object in city.city_objects: self.assertIsNotNone(city_object.name, 'city_object name is none') self.assertIsNotNone(city_object.lod, 'city_object lod is none') @@ -80,7 +76,7 @@ class TestGeometryFactory(TestCase): Test surfaces in city objects :return: None """ - city = self.get_citygml() + city = self._get_citygml() for city_object in city.city_objects: for surface in city_object.surfaces: self.assertIsNotNone(surface.name, 'surface name is none') @@ -111,7 +107,7 @@ class TestGeometryFactory(TestCase): Test thermal zones in city objects :return: None """ - city = self.get_citygml() + city = self._get_citygml() for city_object in city.city_objects: for thermal_zone in city_object.thermal_zones: self.assertIsNotNone(thermal_zone.surfaces, 'thermal_zone surfaces is none') @@ -137,7 +133,7 @@ class TestGeometryFactory(TestCase): Test thermal boundaries in thermal zones :return: None """ - city = self.get_citygml() + city = self._get_citygml() for city_object in city.city_objects: for thermal_zone in city_object.thermal_zones: for thermal_boundary in thermal_zone.bounded: @@ -167,7 +163,7 @@ class TestGeometryFactory(TestCase): Test thermal openings in thermal zones :return: None """ - city = self.get_citygml() + city = self._get_citygml() for city_object in city.city_objects: for thermal_zone in city_object.thermal_zones: for thermal_boundary in thermal_zone.bounded: diff --git a/tests/test_physics_factory.py b/tests/test_physics_factory.py index 355a07a5..cfe848b9 100644 --- a/tests/test_physics_factory.py +++ b/tests/test_physics_factory.py @@ -13,26 +13,34 @@ class TestPhysicsFactory(TestCase): """ TestPhysicsFactory TestCase """ - def setup(self) -> None: + def setUp(self) -> None: + """ + Configure test environment + :return: + """ self._city_gml = None self._nyc_with_physics = None self._example_path = (Path(__file__).parent.parent / 'tests_data').resolve() - def get_citygml(self): + def _get_citygml(self): if self._city_gml is None: file_path = (self._example_path / 'buildings.gml').resolve() self._city_gml = GeometryFactory('citygml', file_path).city self.assertIsNotNone(self._city_gml, 'city is none') return self._city_gml - def get_city_with_physics(self): + def _get_city_with_physics(self): if self._nyc_with_physics is None: - self._nyc_with_physics = self.get_citygml() + self._nyc_with_physics = self._get_citygml() PhysicsFactory('us_new_york_city', self._nyc_with_physics, base_path=self._example_path) return self._nyc_with_physics def test_city_with_physics(self): - city = self.get_city_with_physics() + """ + Enrich the city with the physic information and verify ot + :return: None + """ + city = self._get_city_with_physics() for city_object in city.city_objects: self.assertIsNotNone(city_object.average_storey_height, 'average_storey_height is none') self.assertIsNotNone(city_object.storeys_above_ground, 'storeys_above_ground is none') diff --git a/usage/usage_factory.py b/usage/usage_factory.py index 7fb0d7af..ae84f8e9 100644 --- a/usage/usage_factory.py +++ b/usage/usage_factory.py @@ -8,22 +8,29 @@ from usage.usage_feeders.us_new_york_city_usage_parameters import UsNewYorkCityU class UsageFactory: + """ + UsageFactory class + """ def __init__(self, handler, city): - self._handler = handler.lower().replace(' ', '_') + self._handler = '_' + handler.lower().replace(' ', '_') self._city = city self.factory() - def us_new_york_city(self): + def _us_new_york_city(self): UsNewYorkCityUsageParameters(self._city) - def ca(self): + def _ca(self): raise Exception('Not implemented') - def de(self): + def _de(self): DeUsageParameters(self._city) - def es(self): + def _es(self): raise Exception('Not implemented') def factory(self): + """ + Enrich the city with the usage information + :return: None + """ getattr(self, self._handler, lambda: None)() diff --git a/usage/usage_feeders/de_usage_parameters.py b/usage/usage_feeders/de_usage_parameters.py index 48ebd174..7d0fae39 100644 --- a/usage/usage_feeders/de_usage_parameters.py +++ b/usage/usage_feeders/de_usage_parameters.py @@ -3,12 +3,15 @@ DeUsageParameters model the usage properties for a German building SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca """ -import xmltodict from pathlib import Path +import xmltodict from usage.usage_feeders.helpers.us_function_to_usage import UsFunctionToUsage class DeUsageParameters: + """ + DeUsageParameters + """ def __init__(self, city_objects): self._city_objects = city_objects @@ -17,4 +20,4 @@ class DeUsageParameters: with open(path) as xml: self._library = xmltodict.parse(xml.read()) for city_object in city_objects: - UsFunctionToUsage.function_to_usage(city_object.function) + UsFunctionToUsage.usage(city_object.function) diff --git a/usage/usage_feeders/us_base_usage_parameters.py b/usage/usage_feeders/us_base_usage_parameters.py index df65e610..9444444b 100644 --- a/usage/usage_feeders/us_base_usage_parameters.py +++ b/usage/usage_feeders/us_base_usage_parameters.py @@ -3,13 +3,16 @@ UsBaseUsageParameters base class to model the usage properties for a building in SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca """ -import xmltodict from pathlib import Path +import xmltodict from city_model_structure.usage_zone import UsageZone from city_model_structure.internal_gains import InternalGains class UsBaseUsageParameters: + """ + UsBaseUsageParameters class + """ def __init__(self, city, function_to_usage): self._city = city # ToDo: this is using the german library as a temporary approach, need to use/define a library for US @@ -17,7 +20,7 @@ class UsBaseUsageParameters: with open(path) as xml: self._library = xmltodict.parse(xml.read(), force_list='zoneUsageVariant') for city_object in self._city.city_objects: - #ToDo: Right now is just one usage zone but will be multiple in the future + # ToDo: Right now is just one usage zone but will be multiple in the future usage_zone = UsageZone() usage_zone.usage = function_to_usage(city_object.function) for zone_usage_type in self._library['buildingUsageLibrary']['zoneUsageType']: @@ -31,14 +34,12 @@ class UsBaseUsageParameters: city_object.usage_zone = [usage_zone] break continue - else: - city_object.usage_zones = [UsBaseUsageParameters._parse_zone_usage_type(zone_usage_type, usage_zone)] - break + city_object.usage_zones = [UsBaseUsageParameters._parse_zone_usage_type(zone_usage_type, usage_zone)] + break if city_object.usage_zones is None: print(city_object.function) raise Exception('Usage not found for building function') - @staticmethod def _parse_zone_usage_type(zone_usage_type, usage_zone): usage_zone.hours_day = zone_usage_type['occupancy']['usageHoursPerDay'] diff --git a/usage/usage_feeders/us_new_york_city_usage_parameters.py b/usage/usage_feeders/us_new_york_city_usage_parameters.py index d3a5a516..4d71a634 100644 --- a/usage/usage_feeders/us_new_york_city_usage_parameters.py +++ b/usage/usage_feeders/us_new_york_city_usage_parameters.py @@ -8,6 +8,9 @@ from usage.usage_feeders.helpers.us_pluto_to_usage import UsPlutoToUsage as Pu class UsNewYorkCityUsageParameters(UsBaseUsageParameters): + """ + UsNewYorkCityUsageParameters class + """ def __init__(self, city): self._city = city super().__init__(self._city, Pu.usage) diff --git a/usage/usage_feeders/us_usage_parameters.py b/usage/usage_feeders/us_usage_parameters.py index b24085d6..33fa8e7b 100644 --- a/usage/usage_feeders/us_usage_parameters.py +++ b/usage/usage_feeders/us_usage_parameters.py @@ -8,5 +8,8 @@ from usage.usage_feeders.helpers.us_function_to_usage import UsFunctionToUsage class UsUsageParameters(UsBaseUsageParameters): + """ + UsUsageParameters class + """ def __init__(self, city): super().__init__(city, UsFunctionToUsage.usage)