physicsLab 1.4.5__tar.gz → 1.4.6__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 (39) hide show
  1. {physicsLab-1.4.5 → physicsLab-1.4.6}/PKG-INFO +1 -1
  2. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/__init__.py +20 -0
  3. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/_colorUtils.py +2 -2
  4. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/circuit/elements/_elementBase.py +3 -3
  5. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/circuit/elements/basicCircuit.py +37 -1
  6. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/circuit/elements/logicCircuit.py +17 -1
  7. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/circuit/elements/otherCircuit.py +2 -5
  8. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/circuit/wire.py +2 -0
  9. physicsLab-1.4.6/physicsLab/elementBase.py +2 -0
  10. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/music/music.py +31 -25
  11. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/unit/__init__.py +1 -1
  12. physicsLab-1.4.5/physicsLab/unit/unionLogic.py → physicsLab-1.4.6/physicsLab/unit/logic.py +1 -1
  13. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab.egg-info/PKG-INFO +1 -1
  14. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab.egg-info/SOURCES.txt +2 -1
  15. {physicsLab-1.4.5 → physicsLab-1.4.6}/setup.py +1 -1
  16. {physicsLab-1.4.5 → physicsLab-1.4.6}/LICENSE +0 -0
  17. {physicsLab-1.4.5 → physicsLab-1.4.6}/README.md +0 -0
  18. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/_tools.py +0 -0
  19. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/celestial/__init__.py +0 -0
  20. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/celestial/elementsClass.py +0 -0
  21. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/circuit/__init__.py +0 -0
  22. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/circuit/elementXYZ.py +0 -0
  23. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/circuit/elements/__init__.py +0 -0
  24. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/circuit/elements/artificialCircuit.py +0 -0
  25. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/electromagnetism/__init__.py +0 -0
  26. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/electromagnetism/elements.py +0 -0
  27. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/element.py +0 -0
  28. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/errors.py +0 -0
  29. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/experiment.py +0 -0
  30. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/experimentType.py +0 -0
  31. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/music/__init__.py +0 -0
  32. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/savTemplate.py +0 -0
  33. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/typehint.py +0 -0
  34. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/unit/_unionClassHead.py +0 -0
  35. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab/unit/wires.py +0 -0
  36. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab.egg-info/dependency_links.txt +0 -0
  37. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab.egg-info/requires.txt +0 -0
  38. {physicsLab-1.4.5 → physicsLab-1.4.6}/physicsLab.egg-info/top_level.txt +0 -0
  39. {physicsLab-1.4.5 → physicsLab-1.4.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: physicsLab
3
- Version: 1.4.5
3
+ Version: 1.4.6
4
4
  Summary: Python API for Physics-Lab-AR
5
5
  Home-page: https://gitee.com/script2000/physicsLab
6
6
  Author: Goodenough
@@ -32,6 +32,26 @@ else:
32
32
  if not os.path.exists("physicsLabSav"):
33
33
  os.mkdir("physicsLabSav")
34
34
 
35
+ # 获取 Physics-Lab-AR 版本
36
+ def get_Physics_Lab_AR_version() -> Optional[str]:
37
+ if platform.system() == "Windows":
38
+ from getpass import getuser
39
+ version_file = f"C:/Users/{getuser()}/AppData/LocalLow/CIVITAS/Quantum Physics/Unity/" \
40
+ f"30fdf88e-c67c-4ae8-a0f5-83bb57b9a5c3/Analytics/values"
41
+ if os.path.exists(version_file):
42
+ import json
43
+ with open(version_file) as f:
44
+ version = json.load(f)["app_ver"]
45
+ return version
46
+
47
+ return None
48
+
49
+ plAR_version = get_Physics_Lab_AR_version()
50
+ if plAR_version is not None:
51
+ _, mid, small = eval(f"({plAR_version.replace('.', ',')})")
52
+ if mid < 4 or mid == 4 and small < 7:
53
+ warning("the version of Physics-Lab-AR is less than v2.4.7")
54
+
35
55
  __all__ = [
36
56
  # _colorUtils.py
37
57
  "close_color_print",
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- import sys
2
+ import platform
3
3
  from enum import Enum, unique
4
4
 
5
5
  @unique
@@ -17,7 +17,7 @@ class COLOR(Enum):
17
17
  # 打印write_Experiment的信息时是否使用彩色字
18
18
  colorSupport = True
19
19
 
20
- if colorSupport and sys.platform == "win32":
20
+ if colorSupport and platform.system == "Windows":
21
21
  try:
22
22
  # https://stackoverflow.com/questions/36760127/...
23
23
  # how-to-use-the-new-support-for-ansi-escape-sequences-in-the-windows-10-console
@@ -3,12 +3,13 @@ import inspect
3
3
 
4
4
  from physicsLab import errors
5
5
  from physicsLab.circuit import wire
6
+ from physicsLab.elementBase import ElementBase
6
7
  import physicsLab.circuit.elementXYZ as _elementXYZ
7
8
 
8
9
  from physicsLab.experimentType import experimentType
10
+ from physicsLab.typehint import Optional, Self, numType
9
11
  from physicsLab._tools import roundData, randString, position
10
12
  from physicsLab.experiment import Experiment, stack_Experiment
11
- from physicsLab.typehint import Optional, NoReturn, Self, numType
12
13
 
13
14
  # electricity class's metaClass
14
15
  class CircuitMeta(type):
@@ -67,9 +68,8 @@ class CircuitMeta(type):
67
68
  CircuitMeta.__index += 1
68
69
  return self
69
70
 
70
-
71
71
  # 所有电学元件的父类
72
- class CircuitBase(metaclass=CircuitMeta):
72
+ class CircuitBase(ElementBase, metaclass=CircuitMeta):
73
73
  def __repr__(self) -> str:
74
74
  #TODO Simple_Instrument 的__repr__方法参数更多
75
75
  return f"{self.__class__.__name__}" \
@@ -9,7 +9,7 @@ from ._elementBase import CircuitBase, TwoPinMixIn
9
9
  # 开关基类
10
10
  class _switch_Base(CircuitBase):
11
11
  def __init__(self, x: numType = 0, y: numType = 0, z: numType = 0, elementXYZ: Optional[bool] = None):
12
- self._arguments = {"ModelID": "", "Identifier": Generate, "IsBroken": False,
12
+ self._arguments = {"ModelID": Generate, "Identifier": Generate, "IsBroken": False,
13
13
  "IsLocked": False, "Properties": {"开关": 0, "锁定": 1.0},
14
14
  "Statistics": {}, "Position": Generate,
15
15
  "Rotation": Generate, "DiagramCached": False,
@@ -26,6 +26,14 @@ class Simple_Switch(_switch_Base, TwoPinMixIn):
26
26
  super(Simple_Switch, self).__init__(x, y, z, elementXYZ)
27
27
  self._arguments["ModelID"] = "Simple Switch"
28
28
 
29
+ def __repr__(self) -> str:
30
+ res = f"Simple_Switch({self._position.x}, {self._position.y}, {self._position.z}, " \
31
+ f"elementXYZ={self.is_elementXYZ})"
32
+
33
+ if self._arguments["Properties"]["开关"] == 1:
34
+ res += ".turn_on_switch()"
35
+ return res
36
+
29
37
  # 闭合开关
30
38
  def turn_on_switch(self) -> Self:
31
39
  self._arguments["Properties"]["开关"] = 1
@@ -37,6 +45,16 @@ class SPDT_Switch(_switch_Base):
37
45
  super(SPDT_Switch, self).__init__(x, y, z, elementXYZ)
38
46
  self._arguments["ModelID"] = "SPDT Switch"
39
47
 
48
+ def __repr__(self) -> str:
49
+ res = f"SPDT_Switch({self._position.x}, {self._position.y}, {self._position.z}, " \
50
+ f"elementXYZ={self.is_elementXYZ})"
51
+
52
+ if self._arguments["Properties"]["开关"] == 1:
53
+ res += ".left_turn_on_switch()"
54
+ elif self._arguments["Properties"]["开关"] == 2:
55
+ res += ".right_turn_on_switch()"
56
+ return res
57
+
40
58
  # 向左闭合开关
41
59
  def left_turn_on_switch(self) -> Self:
42
60
  self._arguments["Properties"]["开关"] = 1
@@ -65,6 +83,16 @@ class DPDT_Switch(_switch_Base):
65
83
  super(DPDT_Switch, self).__init__(x, y, z, elementXYZ)
66
84
  self._arguments["ModelID"] = "DPDT Switch"
67
85
 
86
+ def __repr__(self) -> str:
87
+ res = f"DPDT_Switch({self._position.x}, {self._position.y}, {self._position.z}, " \
88
+ f"elementXYZ={self.is_elementXYZ})"
89
+
90
+ if self._arguments["Properties"]["开关"] == 1:
91
+ res += ".left_turn_on_switch()"
92
+ elif self._arguments["Properties"]["开关"] == 2:
93
+ res += ".right_turn_on_switch()"
94
+ return res
95
+
68
96
  # 向左闭合开关
69
97
  def left_turn_on_switch(self) -> Self:
70
98
  self._arguments["Properties"]["开关"] = 1
@@ -119,6 +147,14 @@ class Air_Switch(TwoPinMixIn):
119
147
  "Position": Generate, "Rotation": Generate, "DiagramCached": False,
120
148
  "DiagramPosition": {"X": 0, "Y": 0, "Magnitude": 0.0}, "DiagramRotation": 0}
121
149
 
150
+ def __repr__(self) -> str:
151
+ res = f"Air_Switch({self._position.x}, {self._position.y}, {self._position.z}, " \
152
+ f"elementXYZ={self.is_elementXYZ})"
153
+
154
+ if self._arguments["Properties"]["开关"] == 1:
155
+ res += ".turn_on_switch()"
156
+ return res
157
+
122
158
  # 断开开关
123
159
  def turn_off_switch(self) -> Self:
124
160
  self._arguments["Properties"]["开关"] = 0
@@ -45,9 +45,17 @@ class Logic_Input(_logicBase):
45
45
  "DiagramPosition": {"X": 0, "Y": 0, "Magnitude": 0.0},
46
46
  "DiagramRotation": 0}
47
47
 
48
+ def __repr__(self) -> str:
49
+ res = f"Logic_Input({self._position.x}, {self._position.y}, {self._position.z}, " \
50
+ f"elementXYZ={self.is_elementXYZ})"
51
+
52
+ if self._arguments["Properties"]["开关"] == 1.0:
53
+ res += ".set_highLevel()"
54
+ return res
55
+
48
56
  # 将逻辑输入的状态设置为1
49
57
  def set_highLevel(self) -> "Logic_Input":
50
- self._arguments["Properties"][u"开关"] = 1.0
58
+ self._arguments["Properties"]["开关"] = 1.0
51
59
  return self
52
60
 
53
61
  @property
@@ -405,6 +413,14 @@ class eight_bit_Input(_logicBase):
405
413
  "Position": Generate, "Rotation": Generate, "DiagramCached": False,
406
414
  "DiagramPosition": {"X": 0, "Y": 0, "Magnitude": 0.0}, "DiagramRotation": 0}
407
415
 
416
+ def __repr__(self) -> str:
417
+ res = f"eight_bit_Input({self._position.x}, {self._position.y}, {self._position.z}, " \
418
+ f"elementXYZ={self.is_elementXYZ})"
419
+
420
+ if self._arguments["Properties"]["十进制"] != 0:
421
+ res += f".set_num({self._arguments['Properties']['十进制']})"
422
+ return res
423
+
408
424
  def set_num(self, num : int):
409
425
  if 0 <= num <= 255:
410
426
  self._arguments["Properties"]["十进制"] = num
@@ -205,7 +205,6 @@ class Simple_Instrument(TwoPinMixIn):
205
205
  rated_oltage: numType = 3.0, # 额定电压
206
206
  is_ideal_model: bool = False, # 是否为理想模式
207
207
  is_single: bool = True, # 简单乐器是否只响一次
208
- other_chord_notes: list = [], # 其他和弦音
209
208
  ) -> None:
210
209
  if not (
211
210
  (isinstance(instrument, int) and 0 <= instrument <= 128) and
@@ -228,8 +227,6 @@ class Simple_Instrument(TwoPinMixIn):
228
227
 
229
228
  self.set_Tonality(pitch)
230
229
  self.notes: List[int] = [self._arguments["Properties"]["音高"]] # 仅用于记录self已有的音符
231
- for a_note in other_chord_notes:
232
- self.add_note(a_note)
233
230
 
234
231
  @property
235
232
  def i(self) -> Pin:
@@ -246,8 +243,8 @@ class Simple_Instrument(TwoPinMixIn):
246
243
  f"velocity={self._arguments['Properties']['音量']}, " \
247
244
  f"rated_oltage={self._arguments['Properties']['额定电压']}, " \
248
245
  f"is_ideal_model={self._arguments['Properties']['理想模式']}, " \
249
- f"is_single={bool(self._arguments['Properties']['脉冲'])}, " \
250
- f"other_chord_notes={self.notes})"
246
+ f"is_single={bool(self._arguments['Properties']['脉冲'])}" \
247
+ f").add_note({str(self.notes)[1:-2]})"
251
248
 
252
249
  # 物实v2.4.7新功能: 简单乐器同时播放多个音符
253
250
  def add_note(self, *pitchs: int) -> Self:
@@ -68,6 +68,8 @@ class Wire:
68
68
  def __hash__(self) -> int:
69
69
  return hash(
70
70
  (self.Source.element_self, self.Source.pinLabel, self.Target.element_self, self.Target.pinLabel)
71
+ ) + hash(
72
+ (self.Target.element_self, self.Target.pinLabel, self.Source.element_self, self.Source.pinLabel)
71
73
  )
72
74
 
73
75
  def __eq__(self, other: "Wire") -> bool:
@@ -0,0 +1,2 @@
1
+ class ElementBase:
2
+ pass
@@ -48,10 +48,35 @@ class Midi:
48
48
  program: midi音色
49
49
  tempo: 播放速度
50
50
  '''
51
+ def read_midopy(plpath: str = "temp.mido.py") -> Self:
52
+ self.midifile = "temp.mid"
53
+
54
+ context = None
55
+ with open(plpath, encoding="utf-8") as f:
56
+ context = f.read()
57
+
58
+ import re
59
+ from mido import MidiFile, MidiTrack, Message, MetaMessage
60
+ # 正则匹配内容: MidiTrack([Message(...), ...])
61
+ re_context = re.search(r"MidiTrack\(\[[^\]]+\]\)", context, re.M)
62
+ if re_context is None:
63
+ raise SyntaxError(f"error context in {plpath}")
64
+ self.messages = eval(re_context.group()) # 用到mido import出的内容
65
+
66
+ return self
67
+
51
68
  if not isinstance(midifile, str):
52
69
  raise TypeError
53
70
 
54
- self.midifile: str = midifile
71
+ from os import path
72
+ if not path.exists(midifile):
73
+ raise FileNotFoundError
74
+
75
+ if midifile.endswith(".mido.py"):
76
+ read_midopy(midifile)
77
+ else:
78
+ self.midifile: str = midifile
79
+
55
80
  self.channels: List[int] = [0] * 16
56
81
  self.tempo: int = 500_000
57
82
  self.messages: mido.MidiTrack = self.__get_midi_messages()
@@ -196,7 +221,7 @@ class Midi:
196
221
  return res
197
222
 
198
223
  # 转换为physicsLab的piece类
199
- def translate_to_piece(self, div_time: numType = 100, max_notes: Optional[int] = 800) -> "Piece":
224
+ def to_piece(self, div_time: numType = 100, max_notes: Optional[int] = 800) -> "Piece":
200
225
  return Piece(self._get_notes_list(div_time, max_notes))
201
226
 
202
227
  ''' *.pl.py文件:
@@ -210,27 +235,6 @@ class Midi:
210
235
  为了修改方便, 默认使用 str(mido.MidiTrack) 的方式导出
211
236
  而且是个Py文件, 大家想要自己修改也是很方便的
212
237
  '''
213
- def read_midopy(self, plpath: str = "temp.mido.py") -> Self:
214
- def _read_midopy(plpath):
215
- context = None
216
- with open(plpath, encoding="utf-8") as f:
217
- context = f.read()
218
-
219
- import re
220
- from mido import MidiFile, MidiTrack, Message, MetaMessage
221
- # 正则匹配内容: MidiTrack([Message(...), ...])
222
- re_context = re.search(r"MidiTrack\(\[[^\]]+\]\)", context, re.M)
223
- if re_context is None:
224
- raise SyntaxError(f"error context in {plpath}")
225
- self.messages = eval(re_context.group()) # 用到mido import出的内容
226
-
227
- from os import path
228
- if not path.exists(plpath):
229
- raise FileNotFoundError
230
-
231
- self.midifile = "temp.mid"
232
- _read_midopy(plpath)
233
- return self
234
238
 
235
239
  # 导出一个 .mido.py 文件
236
240
  def write_midopy(self, path: str="temp.mido.py") -> Self:
@@ -238,7 +242,9 @@ class Midi:
238
242
  path += ".mido.py"
239
243
 
240
244
  with open(path, "w", encoding="utf-8") as f:
241
- f.write(f"from mido import MidiFile, MidiTrack, MetaMessage, Message\n"
245
+ f.write(f"import os\n"
246
+ f"os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = '1'\n"
247
+ f"from mido import MidiFile, MidiTrack, MetaMessage, Message\n"
242
248
  f"mid = MidiFile()\n"
243
249
  f"track = {str(self.messages)}\n"
244
250
  f"mid.tracks.append(track)\n"
@@ -533,7 +539,7 @@ class Piece:
533
539
  return self
534
540
 
535
541
  # 将Piece类转换为Midi
536
- def translate_to_midi(self, filepath="temp.mid") -> Midi:
542
+ def to_midi(self, filepath="temp.mid") -> Midi:
537
543
  self.write_midi(filepath)
538
544
  return Midi(filepath)
539
545
 
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
- from .unionLogic import *
2
+ from .logic import *
3
3
  # 模块化电路引脚连接
4
4
  from .wires import *
@@ -41,7 +41,7 @@ class Union_LogicBase(UnionBase):
41
41
  element.set_LowLeaveValue(num)
42
42
  return self
43
43
 
44
- # 只读非门,若没有则创建一个只读非门,若已存在则不会创建新的元件,该类为单例模式
44
+ # 只读非门,若没有则创建一个只读非门,若已存在则不会创建新的元件
45
45
  class Const_NoGate:
46
46
  __singleton: "Const_NoGate" = None # type: ignore
47
47
  __singleton_NoGate: No_Gate = None # type: ignore
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: physicsLab
3
- Version: 1.4.5
3
+ Version: 1.4.6
4
4
  Summary: Python API for Physics-Lab-AR
5
5
  Home-page: https://gitee.com/script2000/physicsLab
6
6
  Author: Goodenough
@@ -5,6 +5,7 @@ physicsLab/__init__.py
5
5
  physicsLab/_colorUtils.py
6
6
  physicsLab/_tools.py
7
7
  physicsLab/element.py
8
+ physicsLab/elementBase.py
8
9
  physicsLab/errors.py
9
10
  physicsLab/experiment.py
10
11
  physicsLab/experimentType.py
@@ -32,5 +33,5 @@ physicsLab/music/__init__.py
32
33
  physicsLab/music/music.py
33
34
  physicsLab/unit/__init__.py
34
35
  physicsLab/unit/_unionClassHead.py
35
- physicsLab/unit/unionLogic.py
36
+ physicsLab/unit/logic.py
36
37
  physicsLab/unit/wires.py
@@ -3,7 +3,7 @@ import setuptools
3
3
 
4
4
  setuptools.setup(
5
5
  name="physicsLab",
6
- version="1.4.5",
6
+ version="1.4.6",
7
7
  license="MIT",
8
8
  author="Goodenough",
9
9
  author_email="2381642961@qq.com",
File without changes
File without changes
File without changes