-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #172 from pledge4future/parametervalidation
Validation of user parameters for all emission types
- Loading branch information
Showing
10 changed files
with
479 additions
and
386 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
"""Data handler class to handle and validate emission factors from csv file""" | ||
|
||
from pathlib import Path | ||
import pandas as pd | ||
from .exceptions import EmissionFactorNotFound, ConversionFactorNotFound | ||
|
||
script_path = str(Path(__file__).parent) | ||
|
||
|
||
class EmissionFactors: | ||
def __init__(self): | ||
"""Init""" | ||
self.emission_factors = pd.read_csv( | ||
f"{script_path}/../data/emission_factors.csv" | ||
) | ||
self.column_names = self.emission_factors.columns | ||
|
||
def get(self, parameters: dict): | ||
""" | ||
Returns factors from the database | ||
:param parameters: | ||
:type parameters: | ||
:return: | ||
:rtype: | ||
""" | ||
selected_factors = self.emission_factors | ||
|
||
for k, v in parameters.items(): | ||
# TODO: shortterm hack to make it work until occupancy is removed from emission factors | ||
if not isinstance(v, int): | ||
v = str(v.value) | ||
if v is None or k not in self.column_names: | ||
continue | ||
|
||
selected_factors_new = selected_factors[selected_factors[k] == v] | ||
selected_factors = selected_factors_new | ||
if selected_factors_new.empty: | ||
raise EmissionFactorNotFound( | ||
"No suitable emission factor found in database. Please adapt your query." | ||
) | ||
|
||
if len(selected_factors) > 1: | ||
raise EmissionFactorNotFound( | ||
f"{len(selected_factors)} emission factors found. Please provide more specific selection criteria." | ||
) | ||
else: | ||
return selected_factors["co2e"].values[0] | ||
|
||
|
||
class Airports: | ||
def __init__(self): | ||
"""Init""" | ||
self.airports = pd.read_csv( | ||
"https://davidmegginson.github.io/ourairports-data/airports.csv" | ||
) | ||
|
||
|
||
class DetourFactors: | ||
def __init__(self): | ||
"""Init""" | ||
self.detour_factors = pd.read_csv(f"{script_path}/../data/detour.csv") | ||
|
||
|
||
class ConversionFactors: | ||
def __init__(self): | ||
"""Init""" | ||
self.conversion_factors = pd.read_csv( | ||
f"{script_path}/../data/conversion_factors_heating.csv" | ||
) | ||
|
||
def get(self, fuel_type, unit): | ||
""" | ||
Returns factors from the database | ||
:param parameters: | ||
:type parameters: | ||
:return: | ||
:rtype: | ||
""" | ||
selected_factors = self.conversion_factors.query( | ||
f'fuel_type=="{fuel_type}" & unit=="{unit}"' | ||
) | ||
if selected_factors.empty: | ||
raise ConversionFactorNotFound( | ||
"No suitable conversion factor found in database. Please adapt your query." | ||
) | ||
else: | ||
return selected_factors["conversion_value"].values[0] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
"""Exceptions for the co2calculator package""" | ||
|
||
|
||
class EmissionFactorNotFound(Exception): | ||
def __init__(self, message): | ||
"""Init""" | ||
self.message = message | ||
|
||
|
||
class ConversionFactorNotFound(Exception): | ||
def __init__(self, message): | ||
"""Init""" | ||
self.message = message |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
"""Base classes to handle and validate parameters for emission calculations""" | ||
|
||
from pydantic import BaseModel, validator | ||
from .constants import ( | ||
TransportationMode, | ||
Size, | ||
CarFuel, | ||
BusFuel, | ||
TrainFuel, | ||
BusTrainRange, | ||
FlightRange, | ||
FlightClass, | ||
FerryClass, | ||
ElectricityFuel, | ||
HeatingFuel, | ||
Unit, | ||
) | ||
from typing import Union | ||
|
||
|
||
class TrainEmissionParameters(BaseModel): | ||
|
||
subcategory: TransportationMode = TransportationMode.TRAIN | ||
fuel_type: Union[TrainFuel, str] = TrainFuel.AVERAGE | ||
range: Union[BusTrainRange, str] = BusTrainRange.LONG_DISTANCE | ||
size: Union[Size, str] = Size.AVERAGE | ||
|
||
@validator("fuel_type", allow_reuse=True) | ||
def check_fueltype(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in TrainFuel) | ||
v = v.lower() | ||
return TrainFuel(v) | ||
|
||
@validator("range", allow_reuse=True) | ||
def check_range(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in BusTrainRange) | ||
v = v.lower() | ||
return BusTrainRange(v) | ||
|
||
@validator("size", allow_reuse=True) | ||
def check_size(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in Size) | ||
v = v.lower() | ||
return Size(v) | ||
|
||
|
||
class TramEmissionParameters(BaseModel): | ||
|
||
subcategory: TransportationMode = TransportationMode.TRAM | ||
size: Union[Size, str] = Size.AVERAGE | ||
|
||
@validator("size", allow_reuse=True) | ||
def check_size(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in Size) | ||
v = v.lower() | ||
return Size(v) | ||
|
||
|
||
class CarEmissionParameters(BaseModel): | ||
|
||
subcategory: TransportationMode = TransportationMode.CAR | ||
fuel_type: Union[CarFuel, str] = CarFuel.AVERAGE | ||
size: Union[Size, str] = Size.AVERAGE | ||
passengers: int = 1 | ||
|
||
@validator("fuel_type", allow_reuse=True) | ||
def check_fueltype(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in CarFuel) | ||
v = v.lower() | ||
return CarFuel(v) | ||
|
||
@validator("size", allow_reuse=True) | ||
def check_size(cls, v, values): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in Size) | ||
v = v.lower() | ||
return Size(v) | ||
|
||
|
||
class PlaneEmissionParameters(BaseModel): | ||
|
||
subcategory: TransportationMode = TransportationMode.PLANE | ||
seating: Union[FlightClass, str] = FlightClass.AVERAGE | ||
range: Union[FlightRange, str] | ||
|
||
@validator("range") | ||
def check_range(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in FlightRange) | ||
v = v.lower() | ||
return FlightRange(v) | ||
|
||
@validator("seating") | ||
def check_seating(cls, v): | ||
if isinstance(v, str): | ||
# Check if v is a valid value of enum FlightClass | ||
assert v.lower() in (item.value for item in FlightClass) | ||
v = v.lower() | ||
return FlightClass(v) | ||
|
||
|
||
class FerryEmissionParameters(BaseModel): | ||
|
||
subcategory: TransportationMode = TransportationMode.FERRY | ||
seating: Union[FerryClass, str] = FerryClass.AVERAGE | ||
|
||
@validator("seating") | ||
def check_seating(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in FerryClass) | ||
v = v.lower() | ||
return FerryClass(v) | ||
|
||
|
||
class BusEmissionParameters(BaseModel): | ||
|
||
subcategory: TransportationMode = TransportationMode.BUS | ||
fuel_type: Union[BusFuel, str] = BusFuel.DIESEL | ||
size: Union[Size, str] = Size.AVERAGE | ||
occupancy: int = 50 | ||
range: Union[BusTrainRange, str] = BusTrainRange.LONG_DISTANCE | ||
|
||
@validator("fuel_type", allow_reuse=True) | ||
def check_fueltype(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in BusFuel) | ||
v = v.lower() | ||
return BusFuel(v) | ||
|
||
@validator("size", allow_reuse=True) | ||
def check_size(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in Size) | ||
v = v.lower() | ||
return Size(v) | ||
|
||
@validator("range", allow_reuse=True) | ||
def check_range(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in BusTrainRange) | ||
v = v.lower() | ||
return BusTrainRange(v) | ||
|
||
|
||
class MotorbikeEmissionParameters(BaseModel): | ||
|
||
subcategory: TransportationMode = TransportationMode.MOTORBIKE | ||
size: Union[Size, str] = Size.AVERAGE | ||
|
||
@validator("size", allow_reuse=True) | ||
def check_size(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in Size) | ||
v = v.lower() | ||
return Size(v) | ||
|
||
|
||
class ElectricityEmissionParameters(BaseModel): | ||
|
||
fuel_type: Union[Size, str] = ElectricityFuel.GERMAN_ENERGY_MIX | ||
|
||
@validator("fuel_type", allow_reuse=True) | ||
def check_fueltype(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in ElectricityFuel) | ||
v = v.lower() | ||
return ElectricityFuel(v) | ||
|
||
|
||
class HeatingEmissionParameters(BaseModel): | ||
|
||
fuel_type: Union[Size, str] = HeatingFuel.GAS | ||
|
||
@validator("fuel_type", allow_reuse=True) | ||
def check_fueltype(cls, v): | ||
if isinstance(v, str): | ||
assert v.lower() in (item.value for item in HeatingFuel) | ||
v = v.lower() | ||
return HeatingFuel(v) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
,fuel,unit,conversion_value | ||
,fuel_type,unit,conversion_value | ||
0,oil,l,10.6 | ||
1,liquid_gas,kg,14.1 | ||
2,coal,kg,6.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.