tidypptsdm 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. tidypptsdm-1.1.0/.gitignore +10 -0
  2. tidypptsdm-1.1.0/LICENSE +21 -0
  3. tidypptsdm-1.1.0/PKG-INFO +77 -0
  4. tidypptsdm-1.1.0/README.md +44 -0
  5. tidypptsdm-1.1.0/pyproject.toml +59 -0
  6. tidypptsdm-1.1.0/src/tidypptsdm/__init__.py +28 -0
  7. tidypptsdm-1.1.0/src/tidypptsdm/__main__.py +5 -0
  8. tidypptsdm-1.1.0/src/tidypptsdm/_messages.py +82 -0
  9. tidypptsdm-1.1.0/src/tidypptsdm/_monitor.py +765 -0
  10. tidypptsdm-1.1.0/src/tidypptsdm/_plots.py +392 -0
  11. tidypptsdm-1.1.0/src/tidypptsdm/_prep.py +251 -0
  12. tidypptsdm-1.1.0/src/tidypptsdm/_report.py +274 -0
  13. tidypptsdm-1.1.0/src/tidypptsdm/_schedule.py +156 -0
  14. tidypptsdm-1.1.0/src/tidypptsdm/_station.py +493 -0
  15. tidypptsdm-1.1.0/src/tidypptsdm/_tables.py +142 -0
  16. tidypptsdm-1.1.0/src/tidypptsdm/_version.py +1 -0
  17. tidypptsdm-1.1.0/src/tidypptsdm/cli.py +131 -0
  18. tidypptsdm-1.1.0/src/tidypptsdm/data/fire.csv.gz +0 -0
  19. tidypptsdm-1.1.0/src/tidypptsdm/data/nedap.csv.gz +0 -0
  20. tidypptsdm-1.1.0/src/tidypptsdm/datasets.py +48 -0
  21. tidypptsdm-1.1.0/src/tidypptsdm/gui.py +346 -0
  22. tidypptsdm-1.1.0/src/tidypptsdm/templates/report.html +172 -0
  23. tidypptsdm-1.1.0/tests/fixtures/fire_d21_alerts.csv +1 -0
  24. tidypptsdm-1.1.0/tests/fixtures/fire_d21_hours.csv +49 -0
  25. tidypptsdm-1.1.0/tests/fixtures/fire_d21_houses.csv +22 -0
  26. tidypptsdm-1.1.0/tests/fixtures/fire_d21_pig_summary.csv +26 -0
  27. tidypptsdm-1.1.0/tests/fixtures/fire_d21_pigs.csv +526 -0
  28. tidypptsdm-1.1.0/tests/fixtures/fire_d21_stations.csv +43 -0
  29. tidypptsdm-1.1.0/tests/fixtures/fire_d7_alerts.csv +8 -0
  30. tidypptsdm-1.1.0/tests/fixtures/fire_d7_hours.csv +49 -0
  31. tidypptsdm-1.1.0/tests/fixtures/fire_d7_houses.csv +8 -0
  32. tidypptsdm-1.1.0/tests/fixtures/fire_d7_pig_summary.csv +26 -0
  33. tidypptsdm-1.1.0/tests/fixtures/fire_d7_pigs.csv +176 -0
  34. tidypptsdm-1.1.0/tests/fixtures/fire_d7_stations.csv +15 -0
  35. tidypptsdm-1.1.0/tests/fixtures/fire_visits.csv.gz +0 -0
  36. tidypptsdm-1.1.0/tests/fixtures/nedap_d21_alerts.csv +2 -0
  37. tidypptsdm-1.1.0/tests/fixtures/nedap_d21_hours.csv +49 -0
  38. tidypptsdm-1.1.0/tests/fixtures/nedap_d21_houses.csv +22 -0
  39. tidypptsdm-1.1.0/tests/fixtures/nedap_d21_pig_summary.csv +30 -0
  40. tidypptsdm-1.1.0/tests/fixtures/nedap_d21_pigs.csv +610 -0
  41. tidypptsdm-1.1.0/tests/fixtures/nedap_d21_stations.csv +43 -0
  42. tidypptsdm-1.1.0/tests/fixtures/nedap_d7_alerts.csv +1 -0
  43. tidypptsdm-1.1.0/tests/fixtures/nedap_d7_hours.csv +49 -0
  44. tidypptsdm-1.1.0/tests/fixtures/nedap_d7_houses.csv +8 -0
  45. tidypptsdm-1.1.0/tests/fixtures/nedap_d7_pig_summary.csv +29 -0
  46. tidypptsdm-1.1.0/tests/fixtures/nedap_d7_pigs.csv +197 -0
  47. tidypptsdm-1.1.0/tests/fixtures/nedap_d7_stations.csv +15 -0
  48. tidypptsdm-1.1.0/tests/fixtures/nedap_d7_wide_feed.csv +3 -0
  49. tidypptsdm-1.1.0/tests/fixtures/nedap_d7_wide_pigfeed.csv +29 -0
  50. tidypptsdm-1.1.0/tests/fixtures/nedap_visits.csv.gz +0 -0
  51. tidypptsdm-1.1.0/tests/fixtures/spoiled_alerts.csv +3 -0
  52. tidypptsdm-1.1.0/tests/fixtures/spoiled_pig.txt +1 -0
  53. tidypptsdm-1.1.0/tests/fixtures/spoiled_stations.csv +15 -0
  54. tidypptsdm-1.1.0/tests/make_fixtures.R +38 -0
  55. tidypptsdm-1.1.0/tests/test_api.py +191 -0
  56. tidypptsdm-1.1.0/tests/test_parity.py +98 -0
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .venv/
5
+ venv/
6
+ build/
7
+ dist/
8
+ site/
9
+ .pytest_cache/
10
+ *.spec.bak
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Meng Guo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,77 @@
1
+ Metadata-Version: 2.5
2
+ Name: tidypptsdm
3
+ Version: 1.1.0
4
+ Summary: Daily monitoring of pig performance testing stations (NEDAP and FIRE)
5
+ Project-URL: Homepage, https://tony2015116.github.io/tidypptsdm-py/
6
+ Project-URL: Source, https://github.com/tony2015116/tidypptsdm-py
7
+ Project-URL: Issues, https://github.com/tony2015116/tidypptsdm-py/issues
8
+ Project-URL: R package, https://github.com/tony2015116/tidypptsdm
9
+ Author-email: Meng Guo <tony2015116@163.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: FIRE,NEDAP,feeding station,livestock,monitoring,performance test,pig
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Natural Language :: Chinese (Simplified)
16
+ Classifier: Natural Language :: English
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: matplotlib>=3.7
22
+ Requires-Dist: numpy>=1.24
23
+ Requires-Dist: openpyxl>=3.1
24
+ Requires-Dist: pandas>=2.0
25
+ Provides-Extra: docs
26
+ Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
27
+ Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
28
+ Provides-Extra: exe
29
+ Requires-Dist: pyinstaller>=6.0; extra == 'exe'
30
+ Provides-Extra: test
31
+ Requires-Dist: pytest>=7; extra == 'test'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # tidypptsdm (Python) <img src="docs/assets/logo.svg" align="right" height="120" alt="logo" />
35
+
36
+ [![tests](https://github.com/tony2015116/tidypptsdm-py/actions/workflows/tests.yml/badge.svg)](https://github.com/tony2015116/tidypptsdm-py/actions/workflows/tests.yml)
37
+ [![docs](https://github.com/tony2015116/tidypptsdm-py/actions/workflows/docs.yml/badge.svg)](https://tony2015116.github.io/tidypptsdm-py/)
38
+
39
+ **种猪性能测定站日常监控**:读取 NEDAP 或 FIRE 测定站的导出文件,按测定站、栋、猪和小时汇总最近几天的数据,列出最后一天的警报(测定站停机、耳标读不到、采食量骤降、猪不来吃料或吃得太少),并生成可以逐站翻页浏览的 HTML 报告和带色阶的 Excel 工作簿。
40
+
41
+ Daily monitoring of automatic pig feeding stations (NEDAP and FIRE): daily
42
+ tables per station, house, pig and hour, alerts of the last day, an offline
43
+ HTML report and an Excel workbook.
44
+
45
+ 这是 R 包 [tidypptsdm](https://github.com/tony2015116/tidypptsdm) 的 Python 版本,**计算结果与 R 版逐表一致**(测试中用两份示例数据对比)。
46
+
47
+ 文档:<https://tony2015116.github.io/tidypptsdm-py/>
48
+
49
+ ## 三种用法
50
+
51
+ ### 1. 桌面程序(Windows,不需要安装 Python)
52
+
53
+ 从 [Releases](https://github.com/tony2015116/tidypptsdm-py/releases) 下载 `tidypptsdm-windows.zip`,解压后双击 `tidypptsdm.exe`:选择导出文件夹和结果文件夹,点“运行监控”,报告自动在浏览器中打开;点“设为每天定时”即可每天自动生成报告。
54
+
55
+ ### 2. 命令行
56
+
57
+ ```bash
58
+ pip install tidypptsdm
59
+ tidypptsdm run D:/nedap/exports --out D:/nedap/monitor --days 7
60
+ tidypptsdm schedule D:/nedap/exports --out D:/nedap/monitor --time 07:30
61
+ ```
62
+
63
+ ### 3. Python
64
+
65
+ ```python
66
+ import tidypptsdm as tp
67
+
68
+ mon = tp.run_monitor("D:/nedap/exports", days=7) # or tp.load_example("nedap")
69
+ mon.alerts
70
+ tp.wide_table(mon.stations, "feed_kg")
71
+ tp.write_monitor_report(mon, "monitor/2024-05-25", open=True)
72
+ tp.write_monitor_tables(mon, "monitor/2024-05-25")
73
+ ```
74
+
75
+ ## 依赖
76
+
77
+ pandas、numpy、matplotlib、openpyxl。图形界面用 Python 自带的 tkinter。
@@ -0,0 +1,44 @@
1
+ # tidypptsdm (Python) <img src="docs/assets/logo.svg" align="right" height="120" alt="logo" />
2
+
3
+ [![tests](https://github.com/tony2015116/tidypptsdm-py/actions/workflows/tests.yml/badge.svg)](https://github.com/tony2015116/tidypptsdm-py/actions/workflows/tests.yml)
4
+ [![docs](https://github.com/tony2015116/tidypptsdm-py/actions/workflows/docs.yml/badge.svg)](https://tony2015116.github.io/tidypptsdm-py/)
5
+
6
+ **种猪性能测定站日常监控**:读取 NEDAP 或 FIRE 测定站的导出文件,按测定站、栋、猪和小时汇总最近几天的数据,列出最后一天的警报(测定站停机、耳标读不到、采食量骤降、猪不来吃料或吃得太少),并生成可以逐站翻页浏览的 HTML 报告和带色阶的 Excel 工作簿。
7
+
8
+ Daily monitoring of automatic pig feeding stations (NEDAP and FIRE): daily
9
+ tables per station, house, pig and hour, alerts of the last day, an offline
10
+ HTML report and an Excel workbook.
11
+
12
+ 这是 R 包 [tidypptsdm](https://github.com/tony2015116/tidypptsdm) 的 Python 版本,**计算结果与 R 版逐表一致**(测试中用两份示例数据对比)。
13
+
14
+ 文档:<https://tony2015116.github.io/tidypptsdm-py/>
15
+
16
+ ## 三种用法
17
+
18
+ ### 1. 桌面程序(Windows,不需要安装 Python)
19
+
20
+ 从 [Releases](https://github.com/tony2015116/tidypptsdm-py/releases) 下载 `tidypptsdm-windows.zip`,解压后双击 `tidypptsdm.exe`:选择导出文件夹和结果文件夹,点“运行监控”,报告自动在浏览器中打开;点“设为每天定时”即可每天自动生成报告。
21
+
22
+ ### 2. 命令行
23
+
24
+ ```bash
25
+ pip install tidypptsdm
26
+ tidypptsdm run D:/nedap/exports --out D:/nedap/monitor --days 7
27
+ tidypptsdm schedule D:/nedap/exports --out D:/nedap/monitor --time 07:30
28
+ ```
29
+
30
+ ### 3. Python
31
+
32
+ ```python
33
+ import tidypptsdm as tp
34
+
35
+ mon = tp.run_monitor("D:/nedap/exports", days=7) # or tp.load_example("nedap")
36
+ mon.alerts
37
+ tp.wide_table(mon.stations, "feed_kg")
38
+ tp.write_monitor_report(mon, "monitor/2024-05-25", open=True)
39
+ tp.write_monitor_tables(mon, "monitor/2024-05-25")
40
+ ```
41
+
42
+ ## 依赖
43
+
44
+ pandas、numpy、matplotlib、openpyxl。图形界面用 Python 自带的 tkinter。
@@ -0,0 +1,59 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.24"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "tidypptsdm"
7
+ dynamic = ["version"]
8
+ description = "Daily monitoring of pig performance testing stations (NEDAP and FIRE)"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [{ name = "Meng Guo", email = "tony2015116@163.com" }]
13
+ requires-python = ">=3.10"
14
+ keywords = ["pig", "performance test", "feeding station", "NEDAP", "FIRE", "livestock", "monitoring"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Science/Research",
18
+ "Natural Language :: Chinese (Simplified)",
19
+ "Natural Language :: English",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Topic :: Scientific/Engineering :: Information Analysis",
23
+ ]
24
+ dependencies = [
25
+ "pandas>=2.0",
26
+ "numpy>=1.24",
27
+ "matplotlib>=3.7",
28
+ "openpyxl>=3.1",
29
+ ]
30
+
31
+ [project.optional-dependencies]
32
+ test = ["pytest>=7"]
33
+ docs = ["mkdocs-material>=9.5", "mkdocstrings[python]>=0.25"]
34
+ exe = ["pyinstaller>=6.0"]
35
+
36
+ [project.scripts]
37
+ tidypptsdm = "tidypptsdm.cli:main"
38
+
39
+ [project.gui-scripts]
40
+ tidypptsdm-gui = "tidypptsdm.gui:main"
41
+
42
+ [project.urls]
43
+ Homepage = "https://tony2015116.github.io/tidypptsdm-py/"
44
+ Source = "https://github.com/tony2015116/tidypptsdm-py"
45
+ Issues = "https://github.com/tony2015116/tidypptsdm-py/issues"
46
+ "R package" = "https://github.com/tony2015116/tidypptsdm"
47
+
48
+ [tool.hatch.version]
49
+ path = "src/tidypptsdm/_version.py"
50
+
51
+ [tool.hatch.build.targets.wheel]
52
+ packages = ["src/tidypptsdm"]
53
+
54
+ [tool.hatch.build.targets.sdist]
55
+ include = ["src", "tests", "README.md", "LICENSE", "pyproject.toml"]
56
+
57
+ [tool.pytest.ini_options]
58
+ testpaths = ["tests"]
59
+ filterwarnings = ["error::FutureWarning"]
@@ -0,0 +1,28 @@
1
+ """tidypptsdm: daily monitoring of pig performance testing stations.
2
+
3
+ The Python version of the R package tidypptsdm: read NEDAP or FIRE exports,
4
+ compute the daily tables per station, house, pig and hour, list the alerts
5
+ of the last day, and write an HTML report and an Excel workbook.
6
+ """
7
+
8
+ from ._messages import Abort
9
+ from ._monitor import (Monitor, monitor_hours, monitor_houses, monitor_pigs,
10
+ monitor_stations, run_monitor, wide_table)
11
+ from ._plots import StationPlot, plot_monitor, save_monitor_plots
12
+ from ._prep import prep_visits
13
+ from ._report import write_monitor_report
14
+ from ._schedule import monitor_to_folder, schedule_monitor, unschedule_monitor
15
+ from ._station import read_station, station_format
16
+ from ._tables import write_monitor_tables
17
+ from .datasets import load_example, write_example
18
+
19
+ from ._version import __version__
20
+
21
+ __all__ = [
22
+ "Abort", "Monitor", "StationPlot", "load_example", "monitor_hours",
23
+ "monitor_houses", "monitor_pigs", "monitor_stations", "monitor_to_folder",
24
+ "plot_monitor", "prep_visits", "read_station", "run_monitor",
25
+ "save_monitor_plots", "schedule_monitor", "station_format",
26
+ "unschedule_monitor", "wide_table", "write_example",
27
+ "write_monitor_report", "write_monitor_tables",
28
+ ]
@@ -0,0 +1,5 @@
1
+ import sys
2
+
3
+ from .cli import main
4
+
5
+ sys.exit(main())
@@ -0,0 +1,82 @@
1
+ """Console messages with three verbosity levels, as in the R packages.
2
+
3
+ 0: silent, 1: summary (default), 2: details. Messages go to stderr so that
4
+ the standard output stays free for data.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import contextlib
10
+ import sys
11
+ from typing import Iterator
12
+
13
+ _state = {"verbose": 1}
14
+
15
+ _SYMBOLS = {
16
+ "info": "i",
17
+ "success": "v",
18
+ "warning": "!",
19
+ "danger": "x",
20
+ }
21
+
22
+
23
+ class Abort(ValueError):
24
+ """Error raised for bad input, with a message meant for the user."""
25
+
26
+
27
+ def check_verbose(verbose: int) -> int:
28
+ if verbose not in (0, 1, 2) or isinstance(verbose, bool):
29
+ raise Abort("`verbose` must be 0 (silent), 1 (summary) or 2 (details).")
30
+ return int(verbose)
31
+
32
+
33
+ @contextlib.contextmanager
34
+ def local_verbose(verbose: int) -> Iterator[int]:
35
+ """Set the verbosity until the block exits."""
36
+ verbose = check_verbose(verbose)
37
+ old = _state["verbose"]
38
+ _state["verbose"] = verbose
39
+ try:
40
+ yield verbose
41
+ finally:
42
+ _state["verbose"] = old
43
+
44
+
45
+ def current_verbose() -> int:
46
+ return _state["verbose"]
47
+
48
+
49
+ def _write(text: str) -> None:
50
+ stream = sys.stderr
51
+ if stream is None: # a windowed exe without console and without a log file
52
+ return
53
+ try:
54
+ stream.write(text + "\n")
55
+ except UnicodeEncodeError: # e.g. a Windows console in a legacy code page
56
+ enc = getattr(stream, "encoding", None) or "ascii"
57
+ stream.write(text.encode(enc, "replace").decode(enc) + "\n")
58
+ stream.flush()
59
+
60
+
61
+ def msg(text: str, kind: str = "info", level: int = 1) -> None:
62
+ """Print a message if the verbosity is at least `level`."""
63
+ if _state["verbose"] < level:
64
+ return
65
+ if kind == "h1":
66
+ line = "-" * max(0, 72 - len(text) - 4)
67
+ _write(f"\n-- {text} {line}")
68
+ else:
69
+ _write(f"{_SYMBOLS.get(kind, 'i')} {text}")
70
+
71
+
72
+ def bullets(lines: list[tuple[str, str]], level: int = 1) -> None:
73
+ """Print indented lines, each with a kind ("danger", "warning", ...)."""
74
+ if _state["verbose"] < level:
75
+ return
76
+ for kind, text in lines:
77
+ _write(f" {_SYMBOLS.get(kind, '*')} {text}")
78
+
79
+
80
+ def plural(n: int, word: str, plural_word: str | None = None) -> str:
81
+ """`3 pigs`, `1 pig`."""
82
+ return f"{n:,} {word if n == 1 else (plural_word or word + 's')}"