Skip to content

Commit

Permalink
__str__ to __repr__ (materialsproject#3274)
Browse files Browse the repository at this point in the history
* use self-documenting f-string in reprs

* TestLibxcFunc add test_repr

* use python behavior that __str__ falls back to  __repr__ if not defined

but not vice versa

* improve ConversionElectrode.__repr__ and add test

* fix test_energy_adjustment_repr
  • Loading branch information
janosh authored Aug 26, 2023
1 parent 538106b commit c8d41e6
Show file tree
Hide file tree
Showing 16 changed files with 72 additions and 139 deletions.
13 changes: 8 additions & 5 deletions pymatgen/apps/battery/conversion_battery.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,15 @@ def __hash__(self) -> int:
return 7

def __repr__(self):
cls_name, formula, n_steps = type(self).__name__, self.initial_comp.reduced_formula, self.num_steps
avg_voltage, min_voltage, max_voltage = self.get_average_voltage(), self.min_voltage, self.max_voltage
output = [
f"Conversion electrode with formula {self.initial_comp.reduced_formula} and nsteps {self.num_steps}",
f"Avg voltage {self.get_average_voltage()} V, min voltage {self.min_voltage} V, "
f"max voltage {self.max_voltage} V",
f"Capacity (grav.) {self.get_capacity_grav()} mAh/g, capacity (vol.) {self.get_capacity_vol()} Ah/l",
f"Specific energy {self.get_specific_energy()} Wh/kg, energy density {self.get_energy_density()} Wh/l",
f"{cls_name} with {formula=} and {n_steps=}, {avg_voltage=:.3f} V, "
f"{min_voltage=:.3f} V, {max_voltage=:.3f} V",
f"Capacity (grav.) {self.get_capacity_grav():.3f} mAh/g, capacity (vol.) "
f"{self.get_capacity_vol():.3f} Ah/l",
f"Specific energy {self.get_specific_energy():.3f} Wh/kg, energy density "
f"{self.get_energy_density():.3f} Wh/l",
]
return "\n".join(output)

Expand Down
9 changes: 5 additions & 4 deletions pymatgen/core/libxcfunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,11 +409,12 @@ def __init__(self, _num):
num: Number for the xc.
"""
info = _all_xcfuncs[self.value]
self.kind = info["Kind"]
self.family = info["Family"]
self.kind = info["Kind"] # type: ignore
self.family = info["Family"] # type: ignore

def __str__(self):
return f"name={self.name}, kind={self.kind}, family={self.family}"
def __repr__(self):
name, kind, family = self.name, self.kind, self.family
return f"{type(self).__name__}({name=}, {kind=}, {family=})"

@staticmethod
def all_families():
Expand Down
6 changes: 4 additions & 2 deletions pymatgen/core/periodic_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,8 @@ def __str__(self):
if self.oxi_state is not None:
output += f"{formula_double_format(abs(self.oxi_state))}{'+' if self.oxi_state >= 0 else '-'}"
if self._spin is not None:
output += f",spin={self._spin}"
spin = self._spin
output += f",{spin=}"
return output

def to_pretty_string(self) -> str:
Expand Down Expand Up @@ -1453,7 +1454,8 @@ def __str__(self):
if self.oxi_state is not None:
output += f"{formula_double_format(abs(self.oxi_state))}{'+' if self.oxi_state >= 0 else '-'}"
if self._spin is not None:
output += f",spin={self._spin}"
spin = self._spin
output += f",{spin=}"
return output


Expand Down
3 changes: 0 additions & 3 deletions pymatgen/electronic_structure/cohp.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ def __init__(self, efermi, energies, cohp, are_coops=False, are_cobis=False, ico
self.icohp = icohp

def __repr__(self):
return str(self)

def __str__(self):
"""Returns a string that can be easily plotted (e.g. using gnuplot)."""
if self.are_coops:
cohpstring = "COOP"
Expand Down
7 changes: 2 additions & 5 deletions pymatgen/entries/computed_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,12 @@ def explain(self):
"""Return an explanation of how the energy adjustment is calculated."""

def __repr__(self):
name, value, uncertainty = self.name, float(self.value), self.uncertainty
name, value, uncertainty, description = self.name, float(self.value), self.uncertainty, self.description
# self.cls might not be a dict if monty decoding is enabled in the new MPRester
# which hydrates all dicts with @class and @module keys into classes in which case
# we expect a Compatibility subclass
generated_by = self.cls.get("@class", "unknown") if isinstance(self.cls, dict) else type(self.cls).__name__
return (
f"{type(self).__name__}({name=}, {value=:.3}, {uncertainty=:.3}, "
f"description={self.description}, {generated_by=})"
)
return f"{type(self).__name__}({name=}, {value=:.3}, {uncertainty=:.3}, {description=}, {generated_by=})"


class ConstantEnergyAdjustment(EnergyAdjustment):
Expand Down
8 changes: 3 additions & 5 deletions pymatgen/io/abinit/abitimer.py
Original file line number Diff line number Diff line change
Expand Up @@ -650,11 +650,9 @@ def __init__(self, sections, info, cpu_time, wall_time):
self.mpi_rank = info["mpi_rank"].strip()
self.fname = info["fname"].strip()

def __str__(self):
return (
f"file={self.fname}, wall_time={self.wall_time:.1f}, "
f"mpi_nprocs={self.mpi_nprocs}, omp_nthreads={self.omp_nthreads}"
)
def __repr__(self):
file, wall_time, mpi_nprocs, omp_nthreads = self.fname, self.wall_time, self.mpi_nprocs, self.omp_nthreads
return f"{type(self).__name__}({file=}, {wall_time=:.3}, {mpi_nprocs=}, {omp_nthreads=})"

@property
def ncpus(self):
Expand Down
3 changes: 0 additions & 3 deletions pymatgen/io/vasp/inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1493,9 +1493,6 @@ def write_file(self, filename):
f.write(str(self))

def __repr__(self):
return str(self)

def __str__(self):
lines = [self.comment, str(self.num_kpts), self.style.name]
style = self.style.name.lower()[0]
if style == "l":
Expand Down
6 changes: 2 additions & 4 deletions pymatgen/io/wannier90.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,8 @@ def write_file(self, filename: str) -> None:
f.write_record(self.data[ib].flatten("F"))

def __repr__(self) -> str:
return (
f"<UNK ik={self.ik} nbnd={self.nbnd} ncl={self.is_noncollinear}"
f" ngx={self.ng[0]} ngy={self.ng[1]} ngz={self.ng[2]}>"
)
ik, nbnd, ncl, ngx, ngy, ngz = self.ik, self.nbnd, self.is_noncollinear, *self.ng
return f"{(type(self).__name__)}({ik=}, {nbnd=}, {ncl=}, {ngx=}, {ngy=}, {ngz=})"

def __eq__(self, other: object) -> bool:
if not isinstance(other, Unk):
Expand Down
8 changes: 3 additions & 5 deletions pymatgen/symmetry/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,10 @@ def _get_symmetry(self):
"""
d = spglib.get_symmetry(self._cell, symprec=self._symprec, angle_tolerance=self._angle_tol)
if d is None:
symprec = self._symprec
raise ValueError(
f"Symmetry detection failed for structure with formula {self._structure.formula}. "
f"Try setting symprec={self._symprec} to a different value."
f"Try setting {symprec=} to a different value."
)
# Sometimes spglib returns small translation vectors, e.g.
# [1e-4, 2e-4, 1e-4]
Expand Down Expand Up @@ -1686,8 +1687,5 @@ def __init__(self, sch_symbol, operations, tol: float = 0.1):
self.sch_symbol = sch_symbol
super().__init__(generate_full_symmops(operations, tol))

def __str__(self):
return self.sch_symbol

def __repr__(self):
return str(self)
return self.sch_symbol
30 changes: 6 additions & 24 deletions pymatgen/transformations/advanced_transformations.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,8 @@ def apply_transformation(self, structure: Structure):
trans = SubstitutionTransformation({self.charge_balance_sp: {self.charge_balance_sp: 1 - removal_fraction}})
return trans.apply_transformation(structure)

def __str__(self):
return f"Charge Balance Transformation : Species to remove = {self.charge_balance_sp}"

def __repr__(self):
return str(self)
return f"Charge Balance Transformation : Species to remove = {self.charge_balance_sp}"

@property
def inverse(self):
Expand Down Expand Up @@ -142,11 +139,8 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool |
structures.append({"transformation": t, "structure": t.apply_transformation(structure)})
return structures

def __str__(self):
return f"Super Transformation : Transformations = {' '.join(map(str, self._transformations))}"

def __repr__(self):
return str(self)
return f"Super Transformation : Transformations = {' '.join(map(str, self._transformations))}"

@property
def inverse(self):
Expand Down Expand Up @@ -246,11 +240,8 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool |
outputs.append({"structure": new_structure})
return outputs

def __str__(self):
return f"Multiple Substitution Transformation : Substitution on {self.sp_to_replace}"

def __repr__(self):
return str(self)
return f"Multiple Substitution Transformation : Substitution on {self.sp_to_replace}"

@property
def inverse(self):
Expand Down Expand Up @@ -489,11 +480,8 @@ def sort_func(s):
return self._all_structures[0:num_to_return]
return self._all_structures[0]["structure"]

def __str__(self):
return "EnumerateStructureTransformation"

def __repr__(self):
return str(self)
return "EnumerateStructureTransformation"

@property
def inverse(self):
Expand Down Expand Up @@ -557,11 +545,8 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool |
outputs.append(output)
return outputs

def __str__(self):
return "SubstitutionPredictorTransformation"

def __repr__(self):
return str(self)
return "SubstitutionPredictorTransformation"

@property
def inverse(self):
Expand Down Expand Up @@ -2199,11 +2184,8 @@ def apply_transformation(self, structure: Structure) -> Structure:
coords_are_cartesian=True,
)

def __str__(self):
return f"{__name__} : rattle_std = {self.rattle_std}"

def __repr__(self):
return str(self)
return f"{__name__} : rattle_std = {self.rattle_std}"

@property
def inverse(self):
Expand Down
25 changes: 5 additions & 20 deletions pymatgen/transformations/site_transformations.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,8 @@ def apply_transformation(self, structure: Structure):
)
return struct.get_sorted_structure()

def __str__(self):
return f"InsertSiteTransformation : species {self.species}, coords {self.coords}"

def __repr__(self):
return str(self)
return f"InsertSiteTransformation : species {self.species}, coords {self.coords}"

@property
def inverse(self):
Expand Down Expand Up @@ -114,14 +111,11 @@ def apply_transformation(self, structure: Structure):
struct[int(i)] = sp
return struct

def __str__(self):
def __repr__(self):
return "ReplaceSiteSpeciesTransformation :" + ", ".join(
[f"{k}->{v}" + v for k, v in self.indices_species_map.items()]
)

def __repr__(self):
return str(self)

@property
def inverse(self):
"""Return: None."""
Expand Down Expand Up @@ -157,11 +151,8 @@ def apply_transformation(self, structure: Structure):
struct.remove_sites(self.indices_to_remove)
return struct

def __str__(self):
return "RemoveSitesTransformation :" + ", ".join(map(str, self.indices_to_remove))

def __repr__(self):
return str(self)
return "RemoveSitesTransformation :" + ", ".join(map(str, self.indices_to_remove))

@property
def inverse(self):
Expand Down Expand Up @@ -211,16 +202,13 @@ def apply_transformation(self, structure: Structure):
struct.translate_sites(self.indices_to_move, self.translation_vector, self.vector_in_frac_coords)
return struct

def __str__(self):
def __repr__(self):
return (
f"TranslateSitesTransformation for indices {self.indices_to_move}, "
f"vect {self.translation_vector} and "
f"vect_in_frac_coords = {self.vector_in_frac_coords}"
)

def __repr__(self):
return str(self)

@property
def inverse(self):
"""
Expand Down Expand Up @@ -502,11 +490,8 @@ def apply_transformation(self, structure: Structure, return_ranked_list: bool |
opt_s = all_structures[0]["structure"]
return opt_s if not return_ranked_list else all_structures[0:num_to_return]

def __str__(self):
return f"PartialRemoveSitesTransformation : Indices and fraction to remove = {self.indices}, ALGO = {self.algo}"

def __repr__(self):
return str(self)
return f"PartialRemoveSitesTransformation : Indices and fraction to remove = {self.indices}, ALGO = {self.algo}"

@property
def inverse(self):
Expand Down
Loading

0 comments on commit c8d41e6

Please sign in to comment.