Skip to content

Commit 30eaaa4

Browse files
Merge pull request #99 from CITCOM-project/linting
Linting Updates
2 parents d8c21dc + 6ee7e35 commit 30eaaa4

File tree

9 files changed

+45
-31
lines changed

9 files changed

+45
-31
lines changed

.pylintrc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ disable=raw-checker-failed,
151151
suppressed-message,
152152
useless-suppression,
153153
deprecated-pragma,
154-
use-symbolic-message-instead
154+
use-symbolic-message-instead,
155155

156156
# Enable the message, report, category or checker with the given id(s). You can
157157
# either give multiple identifier separated by comma (,) or put this option
@@ -168,7 +168,7 @@ argument-naming-style=snake_case
168168
# Regular expression matching correct argument names. Overrides argument-
169169
# naming-style. If left empty, argument names will be checked with the set
170170
# naming style.
171-
#argument-rgx=
171+
argument-rgx=^[a-z][a-z0-9]*((_[a-z0-9]+)*)?$
172172

173173
# Naming style matching correct attribute names.
174174
attr-naming-style=snake_case
@@ -196,7 +196,7 @@ class-attribute-naming-style=any
196196
# Regular expression matching correct class attribute names. Overrides class-
197197
# attribute-naming-style. If left empty, class attribute names will be checked
198198
# with the set naming style.
199-
#class-attribute-rgx=
199+
class-attribute-rgx=^[a-z][a-z0-9]*((_[a-z0-9]+)*)?$
200200

201201
# Naming style matching correct class constant names.
202202
class-const-naming-style=UPPER_CASE
@@ -234,6 +234,7 @@ function-naming-style=snake_case
234234
#function-rgx=
235235

236236
# Good variable names which should always be accepted, separated by a comma.
237+
237238
good-names=i,
238239
j,
239240
k,
@@ -243,7 +244,7 @@ good-names=i,
243244

244245
# Good variable names regexes, separated by a comma. If names match any regex,
245246
# they will always be accepted
246-
good-names-rgxs=
247+
variable-rgx=^[a-z][a-z0-9]*((_[a-z0-9]+)*)?$
247248

248249
# Include a hint for the correct naming format with invalid-name.
249250
include-naming-hint=no

causal_testing/data_collection/data_collector.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ def collect_data(self, **kwargs) -> pd.DataFrame:
2121
Populate the dataframe with execution data.
2222
:return df: A pandas dataframe containing execution data for the system-under-test.
2323
"""
24-
pass
2524

2625
def filter_valid_data(self, data: pd.DataFrame, check_pos: bool = True) -> pd.DataFrame:
2726
"""Check is execution data is valid for the scenario-under-test.
@@ -45,7 +44,7 @@ def filter_valid_data(self, data: pd.DataFrame, check_pos: bool = True) -> pd.Da
4544
solver = z3.Solver()
4645
for c in self.scenario.constraints:
4746
solver.assert_and_track(c, f"background: {c}")
48-
sat = list()
47+
sat = []
4948
unsat_core = None
5049
for _, row in data.iterrows():
5150
solver.push()
@@ -73,7 +72,10 @@ def filter_valid_data(self, data: pd.DataFrame, check_pos: bool = True) -> pd.Da
7372
size_diff = len(data) - len(satisfying_data)
7473
if size_diff > 0:
7574
logger.warning(
76-
f"Discarded {size_diff}/{len(data)} values due to constraint violations.\n" f"For example{unsat_core}"
75+
"Discarded %s/%s values due to constraint violations.\n" "For example%s",
76+
size_diff,
77+
len(data),
78+
unsat_core,
7779
)
7880
return satisfying_data
7981

@@ -116,8 +118,6 @@ def run_system_with_input_configuration(self, input_configuration: dict) -> pd.D
116118
:return: A pandas dataframe containing execution data obtained by executing the system-under-test with the
117119
specified input configuration.
118120
"""
119-
pass
120-
121121

122122
class ObservationalDataCollector(DataCollector):
123123
"""A data collector that extracts data that is relevant to the specified scenario from a csv of execution data."""

causal_testing/generation/abstract_causal_test_case.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,9 @@ def _generate_concrete_tests(
103103
optimizer.add_soft([self.scenario.variables[v].z3 == row[v] for v in run_columns])
104104
if optimizer.check() == z3.unsat:
105105
logger.warning(
106-
"Satisfiability of test case was unsat.\n"
107-
+ f"Constraints\n{optimizer}\nUnsat core {optimizer.unsat_core()}"
106+
"Satisfiability of test case was unsat.\n" "Constraints \n %s \n Unsat core %s",
107+
optimizer,
108+
optimizer.unsat_core(),
108109
)
109110
model = optimizer.model()
110111

@@ -187,13 +188,16 @@ def generate_concrete_tests(
187188
for var in control_configs.columns
188189
}
189190
# Putting treatment and control values in messes it up because the two are not independent...
190-
# This is potentially problematic as constraints might mean we don't get good coverage if we use control values alone
191-
# We might then need to carefully craft our _control value_ generating distributions so that we can get good coverage
191+
# This is potentially problematic as constraints might mean we don't get good coverage if we use control
192+
# values alone
193+
# We might then need to carefully craft our _control value_ generating distributions so that we can get
194+
# good coverage
192195
# without the generated treatment values violating any constraints.
193196

194197
# treatment_configs = pd.DataFrame([test.treatment_input_configuration for test in concrete_tests])
195198
# both_configs = pd.concat([control_configs, treatment_configs])
196-
# ks_stats = {var: stats.kstest(both_configs[var], var.distribution.cdf).statistic for var in both_configs.columns}
199+
# ks_stats = {var: stats.kstest(both_configs[var], var.distribution.cdf).statistic for var in
200+
# both_configs.columns}
197201
effect_modifier_configs = pd.DataFrame([test.effect_modifier_configuration for test in concrete_tests])
198202
ks_stats.update(
199203
{

causal_testing/json_front/json_class.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,7 @@ def generate_tests(self, effects: dict, mutates: dict, estimators: dict, f_flag:
124124
logger.info([(v.name, v.distribution) for v in abstract_test.treatment_variables])
125125
logger.info("Number of concrete tests for test case: %s", str(len(concrete_tests)))
126126
failures = self._execute_tests(concrete_tests, estimators, test, f_flag)
127-
128-
logger.info(f"{failures}/{len(concrete_tests)} failed")
127+
logger.info("%s/%s failed", failures, len(concrete_tests))
129128

130129
def _execute_tests(self, concrete_tests, estimators, test, f_flag):
131130
failures = 0

causal_testing/specification/causal_dag.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,10 @@ def adjustment_set_is_minimal(self, treatments: list[str], outcomes: list[str],
349349
proper_backdoor_graph, treatments, outcomes, smaller_adjustment_set
350350
):
351351
logger.info(
352-
f"Z={adjustment_set} is not minimal because Z'=Z\\{{'{variable}'}}="
353-
f"{smaller_adjustment_set} is also a valid adjustment set."
352+
"Z=%s is not minimal because Z'=Z\\{{'%s'}}=" "%s is also a valid adjustment set.",
353+
adjustment_set,
354+
variable,
355+
smaller_adjustment_set,
354356
)
355357
return False
356358

@@ -393,16 +395,22 @@ def constructive_backdoor_criterion(
393395

394396
if not set(covariates).issubset(set(self.graph.nodes).difference(descendents_of_proper_casual_paths)):
395397
logger.info(
396-
f"Failed Condition 1: Z={covariates} **is** a descendent of some variable on a proper causal "
397-
f"path between X={treatments} and Y={outcomes}."
398+
"Failed Condition 1: Z=%s **is** a descendent of some variable on a proper causal "
399+
"path between X=%s and Y=%s.",
400+
covariates,
401+
treatments,
402+
outcomes,
398403
)
399404
return False
400405

401406
# Condition (2)
402407
if not nx.d_separated(proper_backdoor_graph.graph, set(treatments), set(outcomes), set(covariates)):
403408
logger.info(
404-
f"Failed Condition 2: Z={covariates} **does not** d-separate X={treatments} and Y={outcomes} in"
405-
f" the proper back-door graph relative to X and Y."
409+
"Failed Condition 2: Z=%s **does not** d-separate X=%s and Y=%s in"
410+
" the proper back-door graph relative to X and Y.",
411+
covariates,
412+
treatments,
413+
outcomes,
406414
)
407415
return False
408416

causal_testing/specification/causal_specification.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111

1212
class CausalSpecification(ABC):
13+
"""
14+
Abstract Class for the Causal Specification (combination of Scenario and Causal Dag)
15+
"""
16+
1317
def __init__(self, scenario: Scenario, causal_dag: CausalDAG):
1418
self.scenario = scenario
1519
self.causal_dag = causal_dag

causal_testing/testing/causal_test_engine.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,11 @@ def _check_positivity_violation(self, variables_list):
210210
if not set(variables_list).issubset(self.scenario_execution_data_df.columns):
211211
missing_variables = set(variables_list) - set(self.scenario_execution_data_df.columns)
212212
logger.warning(
213-
f"Positivity violation: missing data for variables {missing_variables}.\n"
214-
f"Causal inference is only valid if a well-specified parametric model is used.\n"
215-
f"Alternatively, consider restricting analysis to executions without the variables:"
216-
f" {missing_variables}."
213+
"Positivity violation: missing data for variables {missing_variables}.\n"
214+
"Causal inference is only valid if a well-specified parametric model is used.\n"
215+
"Alternatively, consider restricting analysis to executions without the variables:"
216+
" %s.",
217+
missing_variables,
217218
)
218219
return True
219220
else:

causal_testing/testing/causal_test_outcome.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def __init__(
3636
if effect_modifier_configuration is not None:
3737
self.effect_modifier_configuration = effect_modifier_configuration
3838
else:
39-
self.effect_modifier_configuration = dict()
39+
self.effect_modifier_configuration = {}
4040

4141
def __str__(self):
4242
base_str = (

causal_testing/testing/estimators.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def __init__(
4848
self.outcome = outcome
4949
self.df = df
5050
if effect_modifiers is None:
51-
self.effect_modifiers = dict()
51+
self.effect_modifiers = {}
5252
elif isinstance(effect_modifiers, set) or isinstance(effect_modifiers, list):
5353
self.effect_modifiers = {k.name for k in effect_modifiers}
5454
elif isinstance(effect_modifiers, dict):
@@ -64,7 +64,6 @@ def add_modelling_assumptions(self):
6464
Add modelling assumptions to the estimator. This is a list of strings which list the modelling assumptions that
6565
must hold if the resulting causal inference is to be considered valid.
6666
"""
67-
pass
6867

6968
@abstractmethod
7069
def estimate_ate(self) -> float:
@@ -73,15 +72,13 @@ def estimate_ate(self) -> float:
7372
in the linear regression equation.
7473
:return: The intercept and coefficient of the linear regression equation
7574
"""
76-
pass
7775

7876
def compute_confidence_intervals(self) -> list[float, float]:
7977
"""
8078
Estimate the 95% Wald confidence intervals for the effect of changing the treatment from control values to
8179
treatment values on the outcome.
8280
:return: 95% Wald confidence intervals.
8381
"""
84-
pass
8582

8683

8784
class LogisticRegressionEstimator(Estimator):

0 commit comments

Comments
 (0)