Skip to content

Commit

Permalink
Merge pull request #3465 from architecture-building-systems/3463-add-…
Browse files Browse the repository at this point in the history
…linter-test

Add linting workflow
  • Loading branch information
reyery authored Jan 21, 2024
2 parents cea1188 + 8f1c60e commit ad5624e
Show file tree
Hide file tree
Showing 115 changed files with 292 additions and 363 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Ruff
on:
pull_request:
push:
branches: [ master ]

jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: chartboost/ruff-action@v1
with:
args: check --ignore E741,F841
2 changes: 1 addition & 1 deletion bin/ceajenkins.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def SvcDoRun(self):
servicemanager.LogInfoMsg('ceajenkins before main')
try:
self.main()
except:
except Exception:
servicemanager.LogErrorMsg(traceback.format_exc())
sys.exit(-1)
servicemanager.LogInfoMsg('normal exit')
Expand Down
2 changes: 1 addition & 1 deletion bin/create-changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def read_version(commit_id):
if not match:
return "0.1"
return match.group(1)
except:
except Exception:
return "<unversioned>"


Expand Down
4 changes: 2 additions & 2 deletions bin/scenariocompare.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@


def main(s1, s2):
print(f"FILE, FIELD, RMSE, ERROR")
print("FILE, FIELD, RMSE, ERROR")
after_root = pathlib.Path(s2)
for before in pathlib.Path(s1).rglob("*.csv"):
if r"building-properties\schedules" in str(before):
Expand Down Expand Up @@ -41,7 +41,7 @@ def main(s1, s2):

float_fields = [f for f in before_df.dtypes.index if before_df.dtypes[f] == "float64"]
for f in float_fields:
if after_df is None or not f in after_df:
if after_df is None or f not in after_df:
error = "left only"
rmse = np.nan
diff_df[f] = np.nan
Expand Down
4 changes: 2 additions & 2 deletions bin/test_substation_calc_hex_cooling.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
This file tests to make sure the refactored version of calc_HEX_cooling calculates the same values as
the old calc_HEX_cooling.
"""
from cea.technologies.substation import *
from cea.technologies.substation import calc_plate_HEX, calc_HEX_cooling


def main():
Expand Down Expand Up @@ -38,7 +38,7 @@ def calc_HEX_cooling_orig(Q, UA, thi, tho, tci, ch):
Flag = False
tol = 0.00000001
while abs((eff[0] - eff[1]) / eff[0]) > tol:
if Flag == True:
if Flag:
eff[0] = eff[1]
else:
cmin = ch * (thi - tho) / ((thi - tci) * eff[0])
Expand Down
4 changes: 2 additions & 2 deletions bin/test_substation_calc_hex_heating.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
This file tests to make sure the refactored version of calc_HEX_heating calculates the same values as
the old calc_HEX_heating.
"""
from cea.technologies.substation import *
from cea.technologies.substation import calc_shell_HEX, calc_HEX_heating


def main():
Expand Down Expand Up @@ -36,7 +36,7 @@ def calc_HEX_heating_orig(Q, UA, thi, tco, tci, cc):
Flag = False
tol = 0.00000001
while abs((eff[0] - eff[1]) / eff[0]) > tol:
if Flag == True:
if Flag:
eff[0] = eff[1]
else:
cmin = cc * (dT_primary) / ((thi - tci) * eff[0])
Expand Down
3 changes: 0 additions & 3 deletions cea/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,3 @@ def __getattribute__(self, item):


register_scripts()

if __name__ == '__main__':
print(demand.__doc__)
14 changes: 7 additions & 7 deletions cea/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def __getattr__(self, item):
"""Return the value of the parameter with that name."""
cid = config_identifier(item)
if cid in self.parameters:
if self.config.restricted_to is not None and not self.parameters[cid].fqname in self.config.restricted_to:
if self.config.restricted_to is not None and self.parameters[cid].fqname not in self.config.restricted_to:
raise AttributeError(
f"Parameter not configured to work with this script: {self.parameters[cid].fqname}")
return self.parameters[cid].get()
Expand All @@ -325,7 +325,7 @@ def __setattr__(self, key, value):

cid = config_identifier(key)
if cid in self.parameters:
if self.config.restricted_to is not None and not self.parameters[cid].fqname in self.config.restricted_to:
if self.config.restricted_to is not None and self.parameters[cid].fqname not in self.config.restricted_to:
raise AttributeError(
f"Parameter not configured to work with this script: {self.parameters[cid].fqname}")
return self.parameters[cid].set(value)
Expand Down Expand Up @@ -470,7 +470,7 @@ def initialize(self, parser):
self._extensions = parser.get(self.section.name, f"{self.name}.extensions").split()
try:
self._direction = parser.get(self.section.name, f"{self.name}.direction")
if not self._direction in {'input', 'output'}:
if self._direction not in {'input', 'output'}:
self._direction = 'input'
except configparser.NoOptionError:
self._direction = 'input'
Expand Down Expand Up @@ -813,7 +813,7 @@ def is_valid_template(self, path):
default_file_path = os.path.join(default_template, folder, file)
if not os.path.isfile(default_file_path):
continue
if not os.path.splitext(default_file_path)[1] in {'.xls', '.xlsx'}:
if os.path.splitext(default_file_path)[1] not in {'.xls', '.xlsx'}:
# we're only interested in the excel files
continue
template_file_path = os.path.join(path, folder, file)
Expand Down Expand Up @@ -964,7 +964,7 @@ def _choices(self):
return building_names

def encode(self, value):
if not str(value) in self._choices:
if str(value) not in self._choices:
return self._choices[0]
return str(value)

Expand All @@ -986,7 +986,7 @@ def _choices(self):
return thermal_storage_names

def encode(self, value):
if not str(value) in self._choices:
if str(value) not in self._choices:
return self._choices[0]
return str(value)

Expand Down Expand Up @@ -1053,7 +1053,7 @@ def _choices(self):
return unique_systems_scenario_list

def encode(self, value):
if not str(value) in self._choices:
if str(value) not in self._choices:
if len(self._choices) > 1:
return self._choices[1]
return self._choices[0]
Expand Down
3 changes: 0 additions & 3 deletions cea/datamanagement/archetypes_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@



import warnings

import numpy as np
import pandas as pd

from typing import List, Tuple
import cea.config
import cea.inputlocator
from cea import InvalidOccupancyNameException
from cea.datamanagement.schedule_helper import calc_mixed_schedule, get_list_of_uses_in_case_study, get_lists_of_var_names_and_var_values
from cea.utilities.dbf import dbf_to_dataframe, dataframe_to_dbf

Expand Down
14 changes: 11 additions & 3 deletions cea/datamanagement/data_migrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@


import os
from functools import cmp_to_key

import cea
import pandas as pd
import collections
Expand Down Expand Up @@ -70,7 +72,13 @@ def lookup_standard(year, standards_df):
def convert_occupancy(name, occupancy_dbf):
row = occupancy_dbf[occupancy_dbf.Name == name].iloc[0]
uses = set(row.to_dict().keys()) - {"Name", "REFERENCE"}
uses = sorted(uses, cmp=lambda a, b: cmp(float(row[a]), float(row[b])), reverse=True)

def cmp(a, b):
_a = float(row[a])
_b = float(row[b])
return (_a > _b) - (_a < _b)

uses = sorted(uses, key=cmp_to_key(cmp), reverse=True)
result = {
"1ST_USE": uses[0],
"1ST_USE_R": float(row[uses[0]]),
Expand Down Expand Up @@ -158,15 +166,15 @@ def is_3_22(scenario):
def indoor_comfort_is_3_22(scenario):
indoor_comfort = dbf_to_dataframe(os.path.join(scenario, "inputs", "building-properties", "indoor_comfort.dbf"))

if not 'Ve_lpspax' in indoor_comfort.columns:
if 'Ve_lpspax' not in indoor_comfort.columns:
return False
return True


def internal_loads_is_3_22(scenario):
internal_loads = dbf_to_dataframe(os.path.join(scenario, "inputs", "building-properties", "internal_loads.dbf"))

if not 'Occ_m2pax' in internal_loads.columns:
if 'Occ_m2pax' not in internal_loads.columns:
return False
return True

Expand Down
10 changes: 5 additions & 5 deletions cea/datamanagement/databases_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

def assert_columns_names(zone_df, columns):
try:
zone_test = zone_df[columns]
zone_df[columns]
except ValueError:
print(
"one or more columns in the Zone or Surroundings input files is not compatible with CEA, please ensure the column" +
Expand Down Expand Up @@ -119,7 +119,7 @@ def verify_input_typology(typology_df):

def verify_input_terrain(terrain_raster):
# Verification 1. verify that we can create the geometry
if terrain_raster == None:
if terrain_raster is None:
raise Exception("Your input terrain file is corrupted. Please verify that you have a non-null raster,"
"and that the grid of it be at least 5 X 5 meters, smaller grid sizes will drastically"
"make the solar radiation engine slow")
Expand All @@ -129,7 +129,7 @@ class InputFileValidator(object):
def __init__(self, input_locator=None, plugins=None):
# Need locator to read other files if lookup choice values
self.locator = input_locator
self.plugins = plugins if not plugins is None else []
self.plugins = plugins if plugins is not None else []

def validate(self, data, data_schema):
"""
Expand Down Expand Up @@ -314,7 +314,7 @@ def __init__(self, schema):
super(IntegerTypeValidator, self).__init__(schema)

def validate(self, value):
if not type(value) is int:
if not isinstance(value, int):
return 'value must be of type integer: got {}'.format(value)
return super(IntegerTypeValidator, self).validate(value)

Expand All @@ -324,7 +324,7 @@ def __init__(self, schema):
super(FloatTypeValidator, self).__init__(schema)

def validate(self, value):
if not type(value) is float:
if not isinstance(value, float):
return 'value must be of type float: got {}'.format(value)
return super(FloatTypeValidator, self).validate(value)

Expand Down
1 change: 0 additions & 1 deletion cea/datamanagement/streets_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import osmnx
import osmnx.utils_graph
import pandas as pd
from geopandas import GeoDataFrame as Gdf

import cea.config
import cea.inputlocator
Expand Down
3 changes: 1 addition & 2 deletions cea/datamanagement/zone_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def calculate_typology_file(locator, zone_df, year_construction, occupancy_type,
def parse_year(year: Union[str, int]) -> int:
import re
# `start-date` formats can be found here https://wiki.openstreetmap.org/wiki/Key:start_date#Formatting
if type(year) == str:
if isinstance(year, str):
# For year in "century" format e.g. `C19`
century_year = re.search(r'C(\d{2})', year)
if century_year:
Expand Down Expand Up @@ -569,7 +569,6 @@ def flatten_geometries(gdf):
:return:
"""
from shapely.ops import unary_union
import string
DISCARDED_GEOMETRY_TYPES = ['Point', 'LineString']

# Explode MultiPolygons and GeometryCollections
Expand Down
1 change: 0 additions & 1 deletion cea/demand/building_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from cea.resources.radiation.geometry_generator import calc_floor_to_floor_height
from cea.utilities.dbf import dbf_to_dataframe
from cea.technologies import blinds
from typing import List

__author__ = "Gabriel Happle"
__copyright__ = "Copyright 2017, Architecture and Building Systems - ETH Zurich"
Expand Down
1 change: 0 additions & 1 deletion cea/demand/datacenter_loads.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@


import numpy as np
import pandas as pd
from cea.technologies import heatpumps
from cea.constants import HOURS_IN_YEAR
from cea.demand.constants import T_C_DATA_SUP_0, T_C_DATA_RE_0
Expand Down
2 changes: 1 addition & 1 deletion cea/demand/electrical_loads.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import numpy as np

from cea.constants import *
from cea.constants import HEAT_CAPACITY_OF_WATER_JPERKGK
from cea.constants import HOURS_IN_YEAR, P_WATER_KGPERM3
from cea.demand import control_heating_cooling_systems, constants
from cea.utilities import physics
Expand Down
12 changes: 6 additions & 6 deletions cea/demand/hotwater_loads.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
Hotwater load (it also calculates fresh water needs)
"""

from cea.constants import *
import math

import numpy as np
import scipy
import math
from math import pi

from cea.constants import HEAT_CAPACITY_OF_WATER_JPERKGK, P_WATER_KGPERM3
from cea.constants import HOURS_IN_YEAR
from cea.demand import constants
from cea.technologies import storage_tank as storage_tank
import pandas as pd
from cea.constants import HOURS_IN_YEAR

__author__ = "Jimeno A. Fonseca"
__copyright__ = "Copyright 2016, Architecture and Building Systems - ETH Zurich"
Expand Down Expand Up @@ -98,7 +98,7 @@ def calc_Qww_sys(bpr, tsd):
Qww_nom_W = tsd['Qww'].max()

# distribution and circulation losses
V_dist_pipes_m3 = Lsww_dis * ((D / 1000) / 2) ** 2 * pi # m3, volume inside distribution pipe
V_dist_pipes_m3 = Lsww_dis * ((D / 1000) / 2) ** 2 * math.pi # m3, volume inside distribution pipe
Qww_dis_ls_r_W = np.vectorize(calc_Qww_dis_ls_r)(T_int_C, tsd['Qww'].copy(), Lsww_dis, Lcww_dis, Y[1], Qww_nom_W,
V_dist_pipes_m3,Tww_sup_0_C)
Qww_dis_ls_nr_W = np.vectorize(calc_Qww_dis_ls_nr)(T_int_C, tsd['Qww'].copy(), Lvww_dis, Lvww_c, Y[0], Qww_nom_W,
Expand Down
10 changes: 2 additions & 8 deletions cea/demand/latent_loads.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
# -*- coding: utf-8 -*-




import numpy as np
import math
from cea.demand import constants

__author__ = "Gabriel Happle"
__copyright__ = "Copyright 2016, Architecture and Building Systems - ETH Zurich"
Expand Down Expand Up @@ -191,9 +184,9 @@ def calc_required_moisture_mech_vent_hu(tsd, t):
# (78) in ISO 52016-1:2017

x_a_e = tsd['x_ve_mech'][t] # external air moisture content (after possible HEX)
g_hu_ld = tsd['g_hu_ld'][t]
m_ve_mech = tsd['m_ve_mech'][t]


x_a_sup_hu_req = x_a_e + g_hu_ld / m_ve_mech

return x_a_sup_hu_req
Expand All @@ -203,6 +196,7 @@ def calc_required_moisture_mech_vent_dhu(tsd, t):
# (79) in ISO 52016-1:2017

x_a_e = tsd['x_ve_mech'][t] # external air moisture content (after possible HEX)
g_dhu_ld = tsd['g_dhu_ld'][t]
m_ve_mech = tsd['m_ve_mech'][t]

x_a_sup_dhu_req = x_a_e - g_dhu_ld / m_ve_mech
Expand Down
1 change: 0 additions & 1 deletion cea/demand/refrigeration_loads.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@


import numpy as np
import pandas as pd
from cea.technologies import heatpumps
from cea.constants import HOURS_IN_YEAR
from cea.demand.constants import T_C_REF_SUP_0, T_C_REF_RE_0
Expand Down
3 changes: 1 addition & 2 deletions cea/demand/schedule_maker/schedule_maker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import pandas as pd
from geopandas import GeoDataFrame as Gdf

import warnings
from itertools import repeat

import cea.config
Expand Down Expand Up @@ -42,7 +41,7 @@ def schedule_maker_main(locator, config, building=None):
else:
raise ValueError("Invalid schedule model: {schedule_model}".format(**locals()))

if building != None:
if building is not None:
buildings = [building] # this is to run the tests

# get variables of indoor comfort and internal loads
Expand Down
Loading

0 comments on commit ad5624e

Please sign in to comment.