• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

maurergroup / dfttoolkit / 15077298886

16 May 2025 08:57PM UTC coverage: 28.848% (+7.1%) from 21.747%
15077298886

Pull #59

github

b0d5e4
web-flow
Merge 473bfe91e into e895278a4
Pull Request #59: Vibrations refactor

1162 of 4028 relevant lines covered (28.85%)

0.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

48.0
dfttoolkit/utils/file_utils.py
1
from collections.abc import Iterator, MutableMapping
1✔
2
from pathlib import Path
1✔
3
from typing import Any
1✔
4

5
from click import edit
1✔
6

7

8
class MultiDict(MutableMapping):
1✔
9
    """
10
    Dictionary that can assign 'multiple values' to a single key.
11

12
    Very basic implementation that works by having each value as a list, and appending
13
    new values to the list
14
    """
15

16
    def __init__(self, *args: tuple[str, Any]):
1✔
17
        self._dict = {}
1✔
18

19
        for key, val in args:
1✔
20
            if key in self._dict:
1✔
21
                self._dict[key].append(val)
×
22

23
            else:
24
                self._dict[key] = val
1✔
25

26
    def __setitem__(self, key: Any, val: Any):
1✔
27
        if key in self._dict:
1✔
28
            self._dict[key].append(val)
1✔
29
        else:
30
            self._dict[key] = [val]
1✔
31

32
    def __repr__(self):
1✔
33
        return f"{self.__class__.__name__}({self._dict})"
×
34

35
    def __str__(self):
1✔
36
        return str(self._dict)
×
37

38
    def __getitem__(self, key: Any):
1✔
39
        return self._dict[key]
1✔
40

41
    def __delitem__(self, key: Any):
1✔
42
        del self._dict[key]
×
43

44
    def __iter__(self):
1✔
45
        return iter(self._dict)
1✔
46

47
    def __len__(self):
1✔
48
        return len(self._dict.keys())
×
49

50
    def reversed_items(self) -> Iterator[tuple[str, Any]]:
1✔
51
        """Yield (key, value) pairs in reverse key order and reversed values."""
52
        for key in reversed(list(self._dict.keys())):
×
53
            for val in reversed(self._dict[key]):
×
54
                yield key, val
×
55

56

57

58
def aims_bin_path_prompt(change_bin: bool | str, save_dir: Path) -> str:
1✔
59
    """
60
    Prompt the user to enter the path to the FHI-aims binary.
61

62
    If it is found in .aims_bin_loc.txt, the path will be read from there, unless
63
    change_bin is True, in which case the user will be prompted to enter the path again.
64

65
    Parameters
66
    ----------
67
    change_bin : Union[bool, str]
68
        whether the user wants to change the binary path. If str == "change_bin", the
69
        user will be prompted to enter the path to the binary again.
70
    save_dir : str
71
        the directory to save or look for the .aims_bin_loc.txt file
72

73
    Returns
74
    -------
75
    binary : str
76
        path to the location of the FHI-aims binary
77
    """
78
    marker = (
×
79
        "\n# Enter the path to the FHI-aims binary above this line\n"
80
        "# Ensure that the full absolute path is provided"
81
    )
82

83
    def write_bin() -> str:
×
84
        binary = edit(marker)
×
85
        binary = str(binary).split()[0]
×
86

87
        if binary is not None:
×
88
            if Path(binary).is_file():
×
89
                with open(f"{save_dir}/.aims_bin_loc.txt", "w+") as f:
×
90
                    f.write(binary)
×
91

92
            else:
93
                raise FileNotFoundError(
×
94
                    "the path to the FHI-aims binary does not exist"
95
                )
96

97
        else:
98
            raise FileNotFoundError(
×
99
                "the path to the FHI-aims binary could not be found"
100
            )
101

102
        return binary
×
103

104
    if (
×
105
        not Path(f"{save_dir}/.aims_bin_loc.txt").is_file()
106
        or change_bin == "change_bin"
107
    ):
108
        binary = write_bin()
×
109

110
    else:
111
        # Parse the binary path from .aims_bin_loc.txt
112
        with open(f"{save_dir}/.aims_bin_loc.txt") as f:
×
113
            binary = f.readlines()[0]
×
114

115
        # Check if the binary path exists and is a file
116
        if not Path(binary).is_file():
×
117
            binary = write_bin()
×
118

119
    return binary
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc