Skip to content

Commit

Permalink
More static typing
Browse files Browse the repository at this point in the history
  • Loading branch information
speleo3 committed Feb 2, 2024
1 parent c8d93f6 commit 25ed65e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 28 deletions.
56 changes: 32 additions & 24 deletions propka/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"""
import logging
from dataclasses import dataclass, field
from typing import Dict, List
from typing import Callable, Dict, List, Sequence, Tuple, TypeVar, Union

try:
# New in version 3.10, deprecated since version 3.12
Expand All @@ -39,6 +39,8 @@ def __set__(self, instance, value: float):
setattr(instance, self._name_not_squared, value**0.5)


T = TypeVar("T")

_T_MATRIX: TypeAlias = "InteractionMatrix"
_T_PAIR_WISE_MATRIX: TypeAlias = "PairwiseMatrix"
_T_NUMBER_DICTIONARY = Dict[str, float]
Expand Down Expand Up @@ -155,8 +157,10 @@ def parse_line(self, line):
self.parse_to_matrix(words)
elif typeannotation is _T_STRING_DICTIONARY:
self.parse_to_string_dictionary(words)
elif typeannotation is int or typeannotation is _T_BOOL:
self.parse_parameter(words, int)
else:
self.parse_parameter(words)
self.parse_parameter(words, float)

def parse_to_number_dictionary(self, words):
"""Parse field to number dictionary.
Expand Down Expand Up @@ -219,14 +223,14 @@ def parse_to_matrix(self, words):
value = tuple(words[1:])
matrix.add(value)

def parse_parameter(self, words):
def parse_parameter(self, words, typefunc: Callable[[str], T]):
"""Parse field to parameters.
Args:
words: strings to parse
"""
assert len(words) == 2, words
value = float(words[1])
value = typefunc(words[1])
setattr(self, words[0], value)

def parse_string(self, words):
Expand Down Expand Up @@ -448,37 +452,40 @@ def print_interactions_latex(self):
class InteractionMatrix:
"""Interaction matrix class."""

def __init__(self, name):
def __init__(self, name: str):
"""Initialize with name of matrix.
Args:
name: name of interaction matrix
"""
self.name = name
self.value = None
self.ordered_keys = []
self.dictionary = {}
self.ordered_keys: List[str] = []
self.dictionary: Dict[str, Dict[str, Union[str, float]]] = {}

def add(self, words):
def add(self, words: Sequence[str]):
"""Add values to matrix.
Args:
words: values to add
"""
len_expected = len(self.ordered_keys) + 2
if len(words) != len_expected:
raise ValueError(f"Expected {len_expected} arguments, got {words!r}")

Check warning on line 473 in propka/parameters.py

View check run for this annotation

Codecov / codecov/patch

propka/parameters.py#L473

Added line #L473 was not covered by tests
new_group = words[0]
self.ordered_keys.append(new_group)
if new_group not in self.dictionary.keys():
self.dictionary[new_group] = {}
for i, group in enumerate(self.ordered_keys):
if len(words) > i+1:
value: Union[str, float]
try:
self.value = float(words[i+1])
value = float(words[i+1])
except ValueError:
self.value = words[i+1]
self.dictionary[group][new_group] = self.value
self.dictionary[new_group][group] = self.value
value = words[i+1]
self.dictionary[group][new_group] = value
self.dictionary[new_group][group] = value

def get_value(self, item1, item2):
def get_value(self, item1: str, item2: str) -> Union[str, float, None]:
"""Get specific matrix value.
Args:
Expand All @@ -492,7 +499,7 @@ def get_value(self, item1, item2):
except KeyError:
return None

def __getitem__(self, group):
def __getitem__(self, group: str):
"""Get specific group from matrix.
Args:
Expand Down Expand Up @@ -528,17 +535,17 @@ def __str__(self):
class PairwiseMatrix:
"""Pairwise interaction matrix class."""

def __init__(self, name):
def __init__(self, name: str):
"""Initialize pairwise matrix.
Args:
name: name of pairwise interaction
"""
self.name = name
self.dictionary = {}
self.default = [0.0, 0.0]
self.dictionary: Dict[str, Dict[str, Tuple[float, float]]] = {}
self.default = (0.0, 0.0)

def add(self, words):
def add(self, words: Sequence[str]):
"""Add information to the matrix.
TODO - this function unnecessarily bundles arguments into a tuple
Expand All @@ -548,16 +555,17 @@ def add(self, words):
"""
# assign the default value
if len(words) == 3 and words[0] == 'default':
self.default = [float(words[1]), float(words[2])]
self.default = (float(words[1]), float(words[2]))
return
# assign non-default values
assert len(words) == 4
group1 = words[0]
group2 = words[1]
value = [float(words[2]), float(words[3])]
value = (float(words[2]), float(words[3]))
self.insert(group1, group2, value)
self.insert(group2, group1, value)

def insert(self, key1, key2, value):
def insert(self, key1: str, key2: str, value: Tuple[float, float]):
"""Insert value into matrix.
Args:
Expand All @@ -575,7 +583,7 @@ def insert(self, key1, key2, value):
self.dictionary[key1] = {}
self.dictionary[key1][key2] = value

def get_value(self, item1, item2):
def get_value(self, item1: str, item2: str) -> Tuple[float, float]:
"""Get specified value from matrix.
Args:
Expand All @@ -589,7 +597,7 @@ def get_value(self, item1, item2):
except KeyError:
return self.default

def __getitem__(self, group):
def __getitem__(self, group: str):
"""Get item from matrix corresponding to specific group.
Args:
Expand Down
10 changes: 6 additions & 4 deletions propka/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
TODO - this module unnecessarily confuses the code. Can we eliminate it?
"""
import logging
from typing import Sequence, Tuple
from propka.atom import Atom
from propka.hydrogens import setup_bonding_and_protonation, setup_bonding
from propka.hydrogens import setup_bonding_and_protonation_30_style
Expand All @@ -15,14 +16,15 @@
from propka.energy import electrostatic_interaction, check_coulomb_pair
from propka.energy import coulomb_energy, check_exceptions
from propka.energy import backbone_reorganization
from propka.parameters import Parameters


_LOGGER = logging.getLogger(__name__)


class Version:
"""Store version-specific methods and parameters."""
def __init__(self, parameters):
def __init__(self, parameters: Parameters):
self.parameters = parameters
self.desolvation_model = self.empty_function
self.weight_pair_method = self.empty_function
Expand Down Expand Up @@ -99,7 +101,7 @@ def setup_bonding(self, molecular_container):
"""Setup bonding using assigned model."""
return self.prepare_bonds(self.parameters, molecular_container)

def get_hydrogen_bond_parameters(self, atom1: Atom, atom2: Atom) -> tuple:
def get_hydrogen_bond_parameters(self, atom1: Atom, atom2: Atom) -> Tuple[float, Sequence[float]]:
"""Get hydrogen bond parameters for two atoms."""
raise NotImplementedError("abstract method")

Expand Down Expand Up @@ -136,7 +138,7 @@ def get_hydrogen_bond_parameters(self, atom1, atom2):
dpka_max = self.parameters.sidechain_interaction
cutoff = self.parameters.sidechain_cutoffs.get_value(
atom1.group_type, atom2.group_type)
return [dpka_max, cutoff]
return dpka_max, cutoff

def get_backbone_hydrogen_bond_parameters(self, backbone_atom, atom):
"""Get hydrogen bond parameters between backbone atom and other atom.
Expand Down Expand Up @@ -311,4 +313,4 @@ def get_hydrogen_bond_parameters(self, atom1, atom2):
atom1.group_type, atom2.group_type)
cutoff = self.parameters.sidechain_cutoffs.get_value(
atom1.group_type, atom2.group_type)
return [dpka_max, cutoff]
return dpka_max, cutoff

Check warning on line 316 in propka/version.py

View check run for this annotation

Codecov / codecov/patch

propka/version.py#L316

Added line #L316 was not covered by tests

0 comments on commit 25ed65e

Please sign in to comment.