Pythonã§å®åæã³ãã¼ã®è£å©ãã¼ã«ãä½ã£ã
æè¿ãè¿ã
ãªã¡ã¤ã¯çã¨æ°ä½ãåºãã¨ãåºãªãã¨ãã®ææç«ã¯ã©ãããµãã¤ãã«ãªã²ã¼ã ã楽ããã§ããã
ããããã®ã²ã¼ã ããã°ãªã®ãä»æ§ãªã®ãå®æçã«ã»ã¼ããã¼ã¿ãçç ´ããã¦ãã¾ããã¨ã«æ©ã¾ããã¦ããã
ã¯ããã®ãã¡ã¯åºç¤ã®ç·å¼µæãåã³ã¨ã楽ããã§ããã®ã ãããã¾ãã«é »çºããã®ã§ãã¼ãã³ãã³ãã®ãããªãã®ã«æãåºããã¨ã決æããã
ãã®ã²ã¼ã ã§ã¯å¹¸ãã欲ããã¢ã¤ãã ããã£ã©ãå
¥æã§ãããã空ä¸æµ®éãããæããè¡ããããã«ãããªã©ãå¤ãã®ãã¨ãã§ããã·ã¹ãã ãæè¼ããã¦ããã
ã½ããã¼ã«ã«ãªã®ã§ä¸åº¦ä½¿ãã¨æ¯æ¢ããå©ããªããªãæãã¯ãã£ãããã»ã¼ãçç ´ã§å¿æãããããã¯ãã·ã¨å²ãåããã¨ã«ããã(ãããã便å©ç³»MODãå
¥ãã¦ããã§ã¬ããè¨å®ã§ã¯ãã£ãã)
ã¿ã¤ãã«è¦ã¦ãã®ãã¼ã¸ãéãã¦ããã人ã¯ãªãã®ãã£ã¡ãããã¨ãæããããããªãã
帰ãåã«ããæ°è¡èªãã§ã»ããã
ãã®ã²ã¼ã ã®å
¥æç³»ã³ãã³ãã¯ãããé·ãã®ã§ããï¼
å½ç¶ééããã¨ä½ãèµ·ãããªãã
ã¤ã¾ããã³ã¼ããç»é²ãã¦ä½åº¦ã使ãã¾ãããã¢ããªã±ã¼ã·ã§ã³ã欲ãããªã£ã...ã®ã§ä½ã£ãã¨ããçµç·¯èª¬æããããã£ãã®ã ã
ã¨ããããã§æ¬é¡...ãªã®ã ãå®ã¯æ¢ã«å
¬éãã¦ããã
çããReadme
ã¾ã§ç¨æãã¦ãã...ã®ã§ããã§æ¸ããã¨ã¯ã»ã¼ãªãã
ã®ã ãããã£ãããªã®ã§ç´¹ä»ãããã
Table.json
ã¨ãããã¡ã¤ã«ãç·¨éãããã¨ã§ã³ãã¼ããæååãç»é²ãããã¨ãã§ããã
ä¾ãã°ã以ä¸ã®ãããªãã¡ã¤ã«æ§é ã«ããã¨
{ "ä¹ å «åç·": "ä¹ å «åç·", "èªã¿": "Otsu Hachio", "æ§å¥": "ç·", "å¹´é½¢": "28" }
ãã®ãããªGUIã表示ã§ããããã«ãªãã
é¸æããã¯ã¹ã«åæ ããããã¼ãé¸ãã§ã³ãã¼ãã¿ã³ãã¯ãªãã¯ããã¨ã対å¿ããå¤ãã¯ãªãããã¼ãã«ã»ãããããã¨ããã·ã³ãã«ãªä»çµã¿ã§ããã
ã¤ã¾ãèªã¿
ãé¸æããç¶æ
ã§ã³ãã¼ããã¨Otsu Hachio
ãã»ãããããã
ããã«ä»¥ä¸ã®ãããªãã¡ã¤ã«æ§é ã«ãããã¨ãã§ããã
{ "ä¹ å «åç·": { "åå": "ä¹ å «åç·", "èªã¿": "Otsu Hachio", "æ§å¥": "ç·", "å¹´é½¢": "28" }, "ä¹å¥³ å «å代": { "åå": "ä¹å¥³ å «å代", "èªã¿": "Otome Yachiyo", "æ§å¥": "女", "å¹´é½¢": "25", "趣å³": "é³æ¥½" } }
ä¸ã®é¸æããã¯ã¹ã§äººç©ãé¸ã³ãä¸ã®é¸æããã¯ã¹ã§ãã¼ã«å¯¾å¿ããæ å ±ãã³ãã¼ã§ããã
æå¾ã«ä»¥ä¸ã®ãããªæ§é ã«ãããã¨ãã§ããã
{ "ä¹ å «åç·": { "ã½ã·ã£ã²1": { "id": "sg_id1", "password": "sg_password1" }, "ã½ã·ã£ã²2": { "id": "sg_id2", "password": "sg_password2" } }, "ä¹å¥³ å «å代": { "ããªã": { "id": "frema_id", "password": "frema_password" } } }
人ç©ã¿ããé¸ã³ãåé¡ãé¸ã³ããã¼ã«å¯¾å¿ããå¤ãã³ãã¼ãããã¨ãã§ããã
ã¡ãªã¿ã«ä½æè
èªèº«ã¯æå¾ã®æ§é ãå©ç¨ãã¦
ããã©|MOD_A|MOD_B|...
ã®ãããªã¿ããä½ããããã«
建æå
¥æç³»|ãã£ã©å
¥æç³»|ãã®ä»
ã®ãããªåé¡ãä½ã£ã¦ã³ãã³ããç»é²ãã¦ããã
ããèå³ãæã£ããGithub - OtsuTableClipperã§è¡¨ç¤ºããã¦ããæé ãè¦ã¦ä½¿ã£ã¦ã¿ã¦ã»ããã
Readmeã®ãããããããã¨ããã£ããæãã¦ããããã¨å¤§å¤ããããããã«ãã¯ã«ã¤ã¼ã³ã¹ã«...ã¨ãªã¢ã¦ã¨ã¦ããã¬ã¹ã«ã
é·ããwithæãåéããã¦ããããã
ä¹
ã
ã®æ´æ°ã
ããªãã®withæ
ã¯ã©ãããï¼ ç§ã¯open()
ããã
ãã®æç¹ã§å¯ããããã ããwithæã§çæããã¤ã³ã¹ã¿ã³ã¹ã¯ä½¿ãæ¨ã¦ã ã¨æã£ã¦ããã¨ããã ãã®è©±ã
ã§ã¯ããªãåéãããã¦ããã®ãã¨ããè¨ã訳ããã
ãã£ãã以ä¸ã®ã³ã¼ããè¦ã¦ã»ããã
# shop.txtã¯å¾ã æ¸ãã³ã¼ãã§ã®åºåçµæã io = open("shop.txt", "r", encoding="utf-8") for i in range(2): with io: for s in io: print(s.strip())
io
ã¨ããTextIOWrapper
ã¤ã³ã¹ã¿ã³ã¹ãçæãã¦2åwithæ
ã§å
容ãåºåãããã¨ãã¦ããã ãã®ã³ã¼ãã§ããã
ããããããã ããã ãããï¼
åºåãã覧ããã ããã
--- Xæ1æ¥ --- éåº: OtsuShop å ¥åº: C(22) å ¥åº: C(29) å ¥åº: C(19) å ¥åº: A(23) éåº: A(23) éåº: C(29) éåº: C(22) éåº: C(19) éåº: OtsuShop B(27)ã¯å¶æ¥æéå¤ã®ããå ¥åºã§ãã¾ããã§ããã --- Xæ2æ¥ --- éåº: OtsuShop å ¥åº: A(27) å ¥åº: A(29) å ¥åº: C(20) å ¥åº: C(22) éåº: C(20) éåº: A(27) éåº: C(22) éåº: A(29) éåº: OtsuShop C(29)ã¯å¶æ¥æéå¤ã®ããå ¥åºã§ãã¾ããã§ããã Traceback (most recent call last): File ..., line 107, in <module> with io: ValueError: I/O operation on closed file.
2åç®ã®withæ
ã使ããã¨ããã¨ã¨ã©ã¼ã«ãªãã®ã§ããã
ããã¯TextIOWrapper
ãä¸è¦ªåãªã®ã趣å³ã§æ¸ãã¦ãç¨åº¦ã®ééã«ã¯ããããªãä»æ¹ãªãäºæ
ããã£ã¦ã®ãã¨ãªã®ãå®ãã§ã¯ãªãããwithãããã¯çµäºæã«å¼ã³åºããã__exit__
ã¡ã½ããã§ãã¡ã¤ã«ãéããå¦çï¼ã¯ãã¦ããããã®ã®__enter__
ã¡ã½ããã§ãã¡ã¤ã«ãéãå¦çï¼ã¯ãã¦ãããªãã¨ããã ãã®ãã¨ãããã
__enter__
, __exit__
ã¯èªä½ã¯ã©ã¹ã§ãå®è£
ãããã¨ã¯ãããã®ã®ãTextIOWrapper
ãããã__enter__
ã§ã¯selfãè¿ãã ãã§ãªã«ãè¡ããã__exit__
ã§çµäºå¦çãå®è£
ããã ãã®ãã®ã°ããã§ãã£ãã®ã§ãä»ã¾ã§æ°ã¥ããã¨ããªãã£ãã
ã§ã¯ãªãæ°ä»ããã®ãã¨ããã¨ãthreading
ã®æä»å¶å¾¡Lock
ã«ã¤ãã¦èª¿ã¹ã¦ããæã«with lock:
ã®ãããªã¤ã³ã¹ã¿ã³ã¹ã§withãããã¯ã«å
¥ããããªã³ã¼ããè¦ãããããã§ããã
å·éã«èããã¨ãã¤ã³ã¹ã¿ã³ã¹çæ -> __enter__å¼ã³åºã
ã¨ããæµããªã®ã§å½ããåãªã®ã ããç²ç¹ã§ãã£ãã
ããããLock
ãç¹æ®ãªã®ã§ã¯ï¼ã¨çå¿æ鬼ã«ãªã£ã¦ããã®ã§ä»¥ä¸ã®ã³ã¼ãã§è©¦ãã¦ã¿ããã¨ã«ããã
import random as rnd from typing import Iterator, Self class Human: ID = {} __name: str __age: int def __new__(cls, name: str, age: int) -> Self: data = (name, age) if data in cls.ID: return cls.ID[data] self = super().__new__(cls) self.__name = name self.__age = age cls.ID[data] = self return self def __str__(self) -> str: return f"{self.__name}({self.__age})" class Shop(list[Human]): def __init__(self, name: str) -> None: self.__name = name self.__is_open = False super().__init__() def __enter__(self) -> Self: self.open() return self def __exit__(self, *ex) -> None: self.close() def __str__(self) -> str: return f"{self.__name}" def append(self, human: Human) -> None: if human in self: return if not self.__is_open: print(f"{human}ã¯å¶æ¥æéå¤ã®ããå ¥åºã§ãã¾ããã§ããã") return print(f"å ¥åº: {human}") super().append(human) def remove(self, human: Human) -> None: if human not in self: return print(f"éåº: {human}") super().remove(human) def close(self) -> None: while self: human = rnd.choice(self) self.remove(human) self.__is_open = False print(f"éåº: {self}") def open(self) -> None: self.__is_open = True print(f"éåº: {self}") def create_human() -> Iterator[Human]: names = tuple( chr(x) for x in range( ord("A"), ord("D"), ) ) ages = tuple(range(18, 30)) while True: yield Human(rnd.choice(names), rnd.choice(ages)) def main() -> None: shop = Shop("OtsuShop") gen_customer = iter(create_human()) for day in range(2): print(f"--- Xæ{day+1}æ¥ ---") with shop: while len(shop) < 4: shop.append(next(gen_customer)) shop.append(next(gen_customer)) print() if __name__ == "__main__": main()
Shop
ã¯ã©ã¹ã¯éåº
, éåº
ã¨ããç¶æ
ãæã¡ãéåºä¸ã¯append
ã§ããªããªã¹ãã®æ¡å¼µã¯ã©ã¹ã
__enter__
å¼ã³åºãã§éåºãã__exit__
å¼ã³åºãã§ä»ãã客ãå
¨å¡éåºããéåºããã
ãã¨ã¯å
ã»ã©ã¨åãããã«with shop:
ãï¼åçºçããããã«foræãåãã¦ããã
withãããã¯ä¸ã«shopã«å®¢ã4人å
¥ããããã«withãããã¯å¤ã§shopã«å®¢ã1人å
¥ãã¦ããã
--- Xæ1æ¥ --- éåº: OtsuShop å ¥åº: C(22) å ¥åº: C(29) å ¥åº: C(19) å ¥åº: A(23) éåº: A(23) éåº: C(29) éåº: C(22) éåº: C(19) éåº: OtsuShop B(27)ã¯å¶æ¥æéå¤ã®ããå ¥åºã§ãã¾ããã§ããã --- Xæ2æ¥ --- éåº: OtsuShop å ¥åº: A(27) å ¥åº: A(29) å ¥åº: C(20) å ¥åº: C(22) éåº: C(20) éåº: A(27) éåº: C(22) éåº: A(29) éåº: OtsuShop C(29)ã¯å¶æ¥æéå¤ã®ããå ¥åºã§ãã¾ããã§ããã
withãããã¯å
¥ãã§éåº: OtsuShop
ãåºåããã4人å
¥åºããæç¹ã§withãããã¯ãæããã¨éåºãã°ãç¶ããå¾éåº: OtsuShop
ã¨åºåãããã
ãã®å¾å
¥åºãããã¨ãã客ã«å¯¾ãã¦ã¯å
¥åºãã§ãã¦ããªããã¨ãåããã
ããããããä¸åº¦withãããã¯ã«å
¥ãã¨åã³å®¢ãåãå
¥ãããã¨ãã§ããããã«ãªã£ã¦ããã
ãã®ããã«è¤æ°åwithæã使ãããã¯ã¯ã©ã¹ã®å®è£ 次第ã§ããã¨ãããã¨ãç´å¾ã§ããã
Bluetoothå®å ¨ã¯ã¤ã¤ã¬ã¹ã¤ã¤ãã³ããã°ãã使ç¨ã§ããªããªã£ãã¨ãã®è¦æ¸
ããå æ¸æ¾ç½®ããããªã®ã§éè¨æ´æ°ã
å°é家ã§ã¯ãªãã®ã§æ£ãã対å¦ãã©ããã¯ããããªãããã¨ãããã解決ããã®ã§ã¡ã¢ã
æã£åãæ©ãæ¹æ³ã ãè¦ã
çºçç¶æ³
ãã®æ¥ã®æ¡ä»¶
- å¬ã®å¤åº
- ãã¤ãã³ã主æåã®ã³ã¼ãã®ãã¼ãã被ã£ã¦ãã
çç¶
- çªç¶é³æ¥½ãæ¶ãã
- ã¤ã¤ãã³ã®ãã¹ã¦ã®æä½ãä¸å¯è½ã«ãªã
- ãã¶ã¼ãã¨ãããã¤ãºé³ã¿ãããªãã®ãå°ããèããã
- å é»ã±ã¼ã¹ã«æ»ãã¨ãå é»ã±ã¼ã¹ã®å é»ä¸ã示ãã©ã¤ããç¹ç¯ãã
- ãã°ããå¾
ã£ã¦ããå度åãåºãã¦ä½¿ç¨ã試ã¿ã¦ã
2
ã¨3
ã®çç¶ã®ã¾ã¾
ãã®æ¥ã®æ¡ä»¶æç¹ã§åä»ãããããããªãããããããéé»æ°ç±æ¥ã®ä¸å
·åãåå ã ã£ãã¨æãããã1
帯é»ï¼
対å¦
- å é»ã±ã¼ã¹ã«å ¥ããã«ãã°ããã¤ã¤ãã³æ¬ä½ãæ¾ç½®ãã¦ã¿ã
- ãã¶ã¼ãã¨ãããã¤ãºé³ãèãããªããªã£ããååã«å é»ãã
- å度ãã¢ãªã³ã°ãã¾ãã¯æ©å¨ã¸ã®æ¥ç¶
以ä¸ã®æé ã§ä»åã®ãã©ãã«ã¯è§£æ±ºãããã¨ãã§ããã
åæ§ã®çç¶ãã¹ã¦ã«å¹æãããããã§ã¯ãªãã ãããããããä¼¼ãçç¶ã§å°ã£ã¦ããã試ã価å¤ãããã¯ããâ¦â¦ããã
-
ã¡ãªã¿ã«èªåã¯æç·ã¤ã¤ãã³ãä½ã«ãæ¥ç¶ãã¦ããªãå ´åã«ã¯ãã¤ãºé³ããªããç¡é³ã®ãã½ã³ã³ã«æ¥ç¶ããå ´åã«åæ§ã®ãã¤ãºé³ãèãããããæ°ä»ããã↩
Pythonã§ãã©ã«ãã®å¤æ´ãç£è¦ã»é£çªãªãã¼ã ããã©ã¤ãã©ãª
ä½æ¥ãåã«ä½ã£ã¦å
¬éãããæ©ãã§ã奴ã®ç´¹ä»ã
c:
ç´ä¸ã§ãã£ãããããç®ã«ãã£ããªã©ã®è¦æ
ã¯æ¸å¿µããããããã®ããã°é ã«ãã«ãã«è¡¨è¨ãã¦ããæè¨ã¨ããããããã°è¦ã«æ¥ã¦ããã¤ãããªã«ããªããã大ä¸å¤«ãé ¼ãã«å
¬éã«è¸ã¿è¾¼ãã
æ©è½ã¯ã¿ã¤ãã«éããã©ã«ãå
ã®å¤æ´ãç£è¦ã»é£çªãªãã¼ã ãã§ããã
ãã®é£çªãªãã¼ã ãä¸è¨c:
ç´ä¸ãªã©ãã½ãããåããã®ã«å¿
è¦ãªãã¡ã¤ã«ã¾ã§ãªãã¼ã ãã¦ãã¾ãå¯è½æ§ãããã®ã§ã絶対ã«èªåã§å¤æ´å¯¾è±¡ã®ãã¡ã¤ã«ãã©ããªãã®ãªã®ãææ¡ãã¦ãããã©ã«ãã§ã®ã¿ä½¿ç¨ããããã«ã
ä¸å¿ã管çè
権éã®ããç¶æ
ã§å®è¡ã§ããªãããã«ãã¦ããã®ã§c:
ç´ä¸ãªããã ã¨PermissionError
ãã¦ãããã¨æãã試ãåæ°ã¯ãªãï¼
ä¾ãã°ç»åãã¡ã¤ã«ããã¡ã¢æ¸ããªããããå ¥ã£ã¦ããªããã©ã«ãã§ä½¿ããã¨ãæ³å®ãã¦ã®ã©ã¤ãã©ãªã
å®æåã¯æ¢ã«gitã«ä¸ãã£ã¦ããã®ã§ãé§ã足ã§ç´¹ä»ã
å®è£
ã«ã¤ãã¦ãããã§ç¢ºèªãã¦ããããã°ã
ã³ã¼ãã¯å®å
¨ã«Windows
ç¨ã®ãã®ã
æ確ã«Windows
ã§ãã使ããªãã®ã¯ä»¥ä¸ã®æ¨©é確èªé¨åã®ã¿ãªã®ã§ããããæ¶ããå¥OSã®æ¨©é確èªå¦çã«å·®ãæ¿ããã°åãâ¦â¦ããã
ãã¼ã¸ã§ã³2022.8.12
ã«ã¢ãããã¼ããã¾ããã
ãã®æ´æ°ã§ãªãã¼ã å¦çãé«éåããâ¦â¦ã¯ãã
pip install -U git+https://github.com/Otsuhachi/OtsuFolderSerialRenamer.git#egg=otsufolserren
OtsuFolderSerialRenamer â LICENSE â Pipfile â Pipfile.lock â README.md â setup.py â ââotsufolserren â cfg.py â funcs.py â orders.py â __init__.py â ââmonitoring â classes.py â __init__.py â ââserial_renamer classes.py __init__.py
otsufolserren
ç´ä¸ã«ãã__init__.py
ã«ãã以ä¸ã®ã³ã¼ãã権é確èªé¨åã
import ctypes if ctypes.windll.shell32.IsUserAnAdmin() == 1: msg = f'ãã®ã©ã¤ãã©ãªã¯éè¦ãªãã¡ã¤ã«æ§æãç ´å£ããæããããããã管çè 権éã§å®è¡ãããã¨ã¯ã§ãã¾ããã' raise PermissionError(msg) del ctypes
ä½åãããã°GUI
ã§ä½¿ããããããããã¦ããã®ããã°ã§ç´¹ä»ãã¦ããããã
以ä¸åä½ç¢ºèªç¨ã®ã³ã¼ãã®èª¬æã
ããã¹ãã®ä¸èº«ã¨ãã¡ã¤ã«åããã©ãã©1ã®ãã¹ããã©ã«ããå®è¡ãã£ã¬ã¯ããªã¨åããã©ã«ãã«ä½æãããã®ãã©ã«ãã®ãã¡ã¤ã«ãåé¤ã追å ãæ¹åãªã©å¼ã£ã¦ããr
, ro
, c
ãªã©è©¦ãããæä½ãæ¨æºå
¥åãããã¨ã§ç¢ºèªãã§ããã
ä»åã®ãã¹ãã§ã¯.txt
ãã¡ã¤ã«ä»¥å¤ãæ³å®ãã¦ããªãã®ã§ã注æ2ã
e
ã§çµäºã
import random import shutil import time from pathlib import Path from typing import Iterable from otsufolserren import ORDER_CTIME, FolderSerialRenamer, get_fm from otsutil import setup_path from otsuvalidator import VInt ROOT = Path('otsufolserren_test_dir') CACHE = Path('otsufolserren_test_cache') def create_test(sample_number: int = 10) -> None: """ãã¹ããã©ã«ããåæåãã¾ãã Args: sample_number (int, optional): ãã¹ããã©ã«ãå ã«çæãããã¡ã¤ã«æ°ã§ãã """ if ROOT.exists(): for p in ROOT.iterdir(): if p.is_file(): p.unlink() else: shutil.rmtree(p) sample_number = VInt(0).validate(sample_number) digit = len(str(sample_number)) for i, n in enumerate(random.sample(range(1, sample_number + 1), sample_number)): i += 1 if i > 1: time.sleep(0.3) n = f'{n:0{digit}d}' i = f'{i:0{digit}d}' with open(setup_path(ROOT / f'{n}.txt'), 'w', encoding='utf-8') as f: f.write(f'This file is No.{i}.') def remove_test() -> None: """ãã¹ããã©ã«ããé¤å»ãã¾ãã """ if ROOT.exists(): shutil.rmtree(ROOT) if CACHE.exists(): shutil.rmtree(CACHE) def rfiles() -> Iterable[Path]: """ãã¹ããã©ã«ãç´ä¸ã®ãã¡ã¤ã«ãè¿ãã¾ãã Raises: FileNotFoundError: ãã¹ããã©ã«ããåå¨ããªãå ´åã«æãããã¾ãã Returns: filter[Path]: ãã¹ããã©ã«ãç´ä¸ã®ãã¡ã¤ã«ã§ãã """ if not ROOT.exists(): raise FileNotFoundError(ROOT) return filter(Path.is_file, ROOT.iterdir()) def show_files() -> None: """ãã¹ããã©ã«ãå ã®ãã©ã«ããèªã¿è¾¼ã¿ä»¥ä¸ã®å½¢å¼ã§åºåãã¾ãã <ãã¡ã¤ã«å>: <ãã¡ã¤ã«ã®å 容> """ try: for file in rfiles(): try: with open(file, 'r', encoding='utf-8') as f: line = f.read() except: continue print(f'{file.name}: {line}') except: pass def ask_prompt(question: str, *answer: str) -> str: """質åã«å¯¾ãã¦ç¹å®ã®åç以å¤ãªãååçãä¿ããåççµæãè¿ãã¾ãã Args: question (str): 質åã§ãã Raises: ValueError: answerãæå®ããã¦ããªãå ´åã«æãããã¾ãã Returns: str: answerã®ããããã§ãã """ if not answer: msg = '1ã¤ä»¥ä¸answerãæå®ãã¦ãã ããã' raise ValueError(msg) answer_ = set(map(lambda x: x.lower(), answer)) while True: ans = input(question).lower() if ans in answer_: return ans def main(): create_test() fm = get_fm(ROOT, 'f', cache_dir=CACHE) help_str = 'c: æ´æ°ã確èªãã¾ãã\nr: ãªãã¼ã ãå®è¡ãã¾ãã\nro: only_when_changeãFalseã«ãã¦ãªãã¼ã ãå®è¡ãã¾ãã\nntmp: name_templateãå¤æ´ãã¾ãã\nfiles: ãã¡ã¤ã«ã¨ãã®ä¸ã®ããã¹ãã表示ãã¾ãã\nh: ãã®ãã«ããå表示ãã¾ãã\ne: ãã®ã¹ã¯ãªãããçµäºãã¾ãã' with FolderSerialRenamer(fm, 'td-', ORDER_CTIME) as fsr: print(help_str) while True: cmd = ask_prompt('å®è¡ããæä½ãæå®ãã¦ãã ããã> ', 'c', 'r', 'ro', 'ntmp', 'files', 'h', 'e') if cmd == 'c': if fsr: l, diff = fsr.get_difference() print(f'{l}件ã®å¤æ´ãæ¤åºãã¾ããã') if ask_prompt('表示ãã¾ããï¼(y/n)> ', 'y', 'n') == 'y': for d in diff: print(d) elif cmd in ('r', 'ro'): preview = fsr.get_preview() fsr.rename(only_when_change=cmd == 'r', preview=preview) preview = {x: y for x, y in preview.items() if str(x.resolve()) != str(y.resolve())} for b, a in preview.items(): print(b, '-->', a) elif cmd == 'ntmp': ntmp = input('æ°ããname_templateãå ¥åãã¦ãã ããã> ') fsr.name_template = ntmp elif cmd == 'files': show_files() elif cmd == 'h': print(help_str) elif cmd == 'e': break remove_test() if __name__ == "__main__": main()
Pythonã§æååãã¢ã¼ã«ã¹ä¿¡å·ã«å¤æãã -å®è£ ç·¨-
2021-10-13 追è¨
ååã«å¼ãç¶ãæååãã¢ã¼ã«ã¹ä¿¡å·ã«å¤æããã©ã¤ãã©ãªãä½ã£ã¦ã¿ã(å®è£ ç·¨)ã
ç´°ããåãã¦ãã£ã¦æå¾ã«å ¨é¨ã¾ã¨ããã³ã¼ããç´¹ä»ããã®ã§ãå 容ã ãè¦ããå ´åã¯ãããã¯ãªãã¯
ã³ã¼ãã¯Windows
ç¨ã®ãã®ãªã®ã§å¥OSã§ä½¿ãããå ´åã¯ä¸é¨ã³ã¼ããå·®ãæ¿ããã
å
·ä½çã«ã¯ã以ä¸ã®2ç¹ãå¤æ´ããã°ããã
winsound
ãã¤ã³ãã¼ãããæãæ¶å»ãããwinsoud.Beep
ã®ä»£ããã«å¨æ³¢æ°ã¨ããªç§ãæå®ãã¦é³ãé³´ããBeep
é¢æ°ãç¨æããã
ç®æ¬¡
- ã¤ã³ãã¼ã
- å¤æãã¼ãã«ã®ä½æ
- ã¯ã©ã¹å®ç¾©
- å®æã³ã¼ã
- 使ãæ¹
- ã¤ã³ã¹ãã¼ã«
ã¤ã³ãã¼ã
å¿ è¦ãªã©ã¤ãã©ãªãã¤ã³ãã¼ããã¦ããã
使ç¨ããã®ã¯ãtime.sleep
, winsound.Beep
, otsuvalidator
, ããããã³ã¼ãã£ã³ã°ã®è£å©ã§typing.cast
ãã¤ã³ãã¼ããã¦ããã
otsuvalidator
ã¯ã¯ã©ã¹ã®å±æ§ãé©æ£ãã©ããã確èªããã©ã¤ãã©ãªãªã®ã§ãpip[env] install otsuvalidator
çã§ã¤ã³ã¹ãã¼ã«ããããå«ãªãé©å®å±æ§ãã§ãã¯ãè¡ãã¡ã½ãããå®è£
ãã¦å·®ãæ¿ããã¨ããã
typing.cast
ã¯ããªãã¼ã¿ãå
ã®åã¨ãã¦æ±ããã³ã¼ãã£ã³ã°ã®è£å©ç®çãªã®ã§ãä¸è¦ã§ããã°ãã®é¨åãå·®ãæ¿ããã°ããã
Windows以å¤ã®OSã使ç¨ããå ´åã¯ãå¨æ³¢æ°ã¨ããªç§ãæå®ãã¦é³ãé³´ããBeep
é¢æ°ãç¨æãã¦ãããã¨ã
以ä¸ãã¤ã³ãã¼ãé¨åã®ã³ã¼ã
import time from typing import cast from winsound import Beep from otsuvalidator import VInt, VRegex, VString
å¤æãã¼ãã«ã®ä½æ
ãã®ã©ã¤ãã©ãªã®ããæå³æ¬ä½ã¨ããããå¤æãã¼ãã«ã®ä½æããã¦ããã
<å
ã®æå>:<0ã¨1ã®ã¿ã®ã¿ãã«>
ã¨ããå½¢å¼ã®è¾æ¸ã
ããããã復å
ç¨ã®ãã¼ãã«ãä½æããã
ãã¡ãã¯<0ã¨1ã®ã¿ã®ã¿ãã«>:<å
ã®æå>
ã¨ããå½¢å¼ã®è¾æ¸ã
çç¹
ã0
, é·ç¹
ã1
ã¨ãã¦æ±ãã
ä»åã¯ä¸é¨è¨å·ã¨ã¢ã«ãã¡ããããæ°åã®ãã¼ãã«ãä½ã£ãããã¢ã«ãã¡ãããã§ã¯ãªã平仮åãã«ã¿ã«ãã使ã£ããã両æ¹ç¨æãã¦å¾è¿°ã®ã³ã¼ãã«mode
å±æ§ãªãã追å ãã¦åç
§ãããã¼ãã«ã使ãåããã°ãåè±ãåãæ¿ãããã¨ãã§ããããã«ãªãã1
以ä¸ãå¤æãã¼ãã«é¨åã®ã³ã¼ã
# ãã®ä¸ã«ã¤ã³ãã¼ãé¨å C2M_TABLE = { '.': (0, 1, 0, 1, 0, 1), ',': (1, 1, 0, 0, 1, 1), '?': (0, 0, 1, 1, 0, 0), '_': (0, 0, 1, 1, 0, 1), '+': (0, 1, 0, 1, 0), '-': (1, 0, 0, 0, 0, 1), 'Ã': (1, 0, 0, 1), '^': (0, 0, 0, 0, 0, 0), '/': (1, 0, 0, 1, 0), '@': (0, 1, 1, 0, 1, 0), '(': (1, 0, 1, 1, 0), ')': (1, 0, 1, 1, 0, 1), '"': (0, 1, 0, 0, 1, 0), '\'': (0, 1, 1, 1, 1, 0), '=': (1, 0, 0, 0, 1), 'A': (0, 1), 'B': (1, 0, 0, 0), 'C': (1, 0, 1, 0), 'D': (1, 0, 0), 'E': (0, ), 'F': (0, 0, 1, 0), 'G': (1, 1, 0), 'H': (0, 0, 0, 0), 'I': (0, 0), 'J': (0, 1, 1, 1), 'K': (1, 0, 1), 'L': (0, 1, 0, 0), 'M': (1, 1), 'N': (1, 0), 'O': (1, 1, 1), 'P': (0, 1, 1, 0), 'Q': (1, 1, 0, 1), 'R': (0, 1, 0), 'S': (0, 0, 0), 'T': (1, ), 'U': (0, 0, 1), 'V': (0, 0, 0, 1), 'W': (0, 1, 1), 'X': (1, 0, 0, 1), 'Y': (1, 0, 1, 1), 'Z': (1, 1, 0, 0), '1': (0, 1, 1, 1, 1), '2': (0, 0, 1, 1, 1), '3': (0, 0, 0, 1, 1), '4': (0, 0, 0, 0, 1), '5': (0, 0, 0, 0, 0), '6': (1, 0, 0, 0, 0), '7': (1, 1, 0, 0, 0), '8': (1, 1, 1, 0, 0), '9': (1, 1, 1, 1, 0), '0': (1, 1, 1, 1, 1), } M2C_TABLE = {x[1]: x[0] for x in C2M_TABLE.items()}
ç®è¡è¨å·Ã
ã¨ã¢ã«ãã¡ãããX
ã¯(1, 0, 0, 1)
ã¨åãå¤ã«ãªã£ã¦ãã¾ã£ã¦ããã
ã¾ããã¢ã¼ã«ã¹ä¿¡å·ããæåã«å¤æããéã®ãã¼ãã«ã¯C2M_TABLE
ã®ãã¼ã¨å¤ãå転ããããã®ã«ãªã£ã¦ããã
ãã®å ´åããã¼ãéè¤ããå ´åã«å¤ãä¸æ¸ãããã¦ãã¾ãã
ãã®ãããè¨å·ãããå¾ã«ã¢ã«ãã¡ãããã®ç»é²ãè¡ã£ã¦Ã
ã§ã¯ãªãX
ã¨å¯¾å¿ããããã«ãã¦ããã
ã¯ã©ã¹å®ç¾©
ã¢ã¼ã«ã¹ä¿¡å·ã¯ã©ã¹ãä½æãã¦ããã
ãããããä»åã¢ã¼ã«ã¹ä¿¡å·ã«å¤æå¯è½ãªæååã表ãæ£è¦è¡¨ç¾MORSE_CODE_REGEX
ãå®ç¾©ãã¦ããã2
åºç¤
ç®æ¬¡ã«æ»ã
ã¯ã©ã¹å®ç¾©ã®ç®æ¬¡ã«æ»ã
ã¾ãã¯ã¯ã©ã¹å±æ§ã¨__init__()
, __str__()
, __add__()
ã¡ã½ããã
ããããmorse_code
ããããã£ãå®ç¾©ãã¦ããã
以ä¸ã該å½é¨åã®ã³ã¼ãã
# ãã®ä¸ã«ã¤ã³ãã¼ãé¨å # ãã®ä¸ã«å¤æãã¼ãã«é¨å MORSE_CODE_REGEX = '^[A-Z0-9 \\.,\\?_\\+\\-Ã\\^\\/@\\(\\)"\'=]*$' class MorseCode: """ã¢ã¼ã«ã¹ä¿¡å·ã¯ã©ã¹ã§ãã æååã®ã¢ã¼ã«ã¹è¡¨ç¾ãåå¾ããããã¢ã¼ã«ã¹ä¿¡å·é³ãåçãããã¨ãã§ãã¾ãã """ text: str = cast(str, VRegex('^[A-Z0-9 \\.,\\?_\\+\\-Ã\\^\\/@\\(\\)"\'=]*$', 1)) short: str = cast(str, VString(1, 1)) long: str = cast(str, VString(1, 1)) sep: str = cast(str, VString(1, 1)) frequency: int = cast(int, VInt(37, 32767)) minimum_length: int = cast(int, VInt(1)) def __init__(self, text: str, *, short: str = '.', long: str = '-', sep: str = ' ', frequency: int = 440, minimum_length: int = 100): """textã表ç¾ããã¢ã¼ã«ã¹ä¿¡å·ãçæãã¾ãã textã«å«ããã¨ãã§ããæåã¯"A-Z0-9 .,?-@"ã§ãã ã¾ããé£ç¶ãã空ç½ã¯1ã¤ã¨ãã¦æ±ããã¾ãã Args: text (str): å ã¨ãªãæååã§ãã short (str, optional): çç¹ã«ä½¿ç¨ããæåã§ãã long (str, optional): é·ç¹ã«ä½¿ç¨ããæåã§ãã sep (str, optional): æåéã®åºåãã«ä½¿ç¨ããæåã§ãã frequency (int, optional): åçæã®å¨æ³¢æ°Hzã§ãã minimum_length (int, optional): åçæã®çç¹ã®é·ãã§ãã Raises: ValueError: short, long, sepã«éè¤ããæåããã¦ããã¨ã¯ã§ãã¾ããã """ if len({short, long, sep}) != 3: msg = 'short, long, sepã¯ããããéãæåã§ããå¿ è¦ãããã¾ãã' raise ValueError(msg) self.short = short self.long = long self.sep = sep self.frequency = frequency self.minimum_length = minimum_length while ' ' in text: text = text.replace(' ', ' ') self.text = text.upper() ct = C2M_TABLE s = self.short l = self.long res = [] for c in self.text: if c == ' ': res.append(' ') else: res.append(''.join(map(lambda x: l if x else s, ct[c]))) self.__morse_code = self.sep.join(res) def __str__(self) -> str: return self.text def __add__(self, other) -> 'MorseCode': kwargs = { 'short': self.short, 'long': self.long, 'sep': self.sep, 'minimum_length': self.minimum_length, } if type(other) is MorseCode or type(getattr(other, 'text', None)) is str: kwargs['text'] = self.text + other.text else: kwargs['text'] = self.text + other return MorseCode(**kwargs) @property def morse_code(self) -> str: """ã¢ã¼ã«ã¹è¡¨ç¾åããæååãè¿ãã¾ãã Returns: str: ã¢ã¼ã«ã¹è¡¨ç¾ã§ãã """ return self.__morse_code
å±æ§ã¯ããªãã¼ã¿ãæ¬æ¥ã®åã¨ãã¦æ±ãããã«cast
ãã¦ããã®ã§ãä¸è¦ã§ããã°ä»¥ä¸ã®text
å±æ§ã®ä¾ãåèã«ãã¦æ¸ãæããã
åãã³ãããããªãå ´å
text = VRegex(MORSE_CODE_REGEX, 1)
cast
ãã¤ã³ãã¼ãããããªãå ´å3
text: str = VRegex(MORSE_CODE_REGEX, 1) # type: ignore
otsuvalidator
ãã¤ã³ã¹ãã¼ã«ããããªãå ´åã«ã¯property
ã§ã«ãã»ã«åãã¦å±æ§ãä¿è·ããããã¤ã³ã¹ã¿ã³ã¹çææã®å¼æ°ãæ£ãããã©ããå¤å®ããå¦çã追å ãã¦ããã
ã¾ãã以éã«ç´¹ä»ããã³ã¼ããèªèº«ã®é¸æã«å¿ãã¦å¾®ä¿®æ£ããã
__init__()
ã®å¦ç
çç¹
,é·ç¹
,æåé
ã表ãæåãéè¤ãã¦ããªãã確èªãè¡ãshort
,long
,sep
,frequency
,minimum_length
ãå±æ§ã«ä»£å ¥ãã4text
ããé£ç¶ãã空ç½ãåãé¤ããtext.upper()
ãå±æ§ã«ä»£å ¥ãã__morse_code
å±æ§ã«text
ã®ã¢ã¼ã«ã¹è¡¨ç¾ãä»£å ¥ãã
__str__()
ã¯self.text
ãè¿ãããã«ãã¦ãå
ã®æãåå¾ã§ããããã«ããã
morse_code
ããããã£ã¯self.text
ã®ã¢ã¼ã«ã¹ä¿¡å·è¡¨ç¾ãè¿ãã
__add__()
ã®å¦ç
other
ã«å½±é¿ããªãå¼æ°ãè¾æ¸kwargs
ã«ç»é²ãã¦ããother
ãMorseCode
ã¤ã³ã¹ã¿ã³ã¹ãstrå
ã®text
å±æ§ãæã¤ãã©ããkwargs['text']
ã«self
ã¨other
ã®text
å±æ§ã足ãããã®ãä»£å ¥ããkwargs['text']
ã«self
ã®text
å±æ§ã¨other
ã足ãããã®ãä»£å ¥ãã5
kwargs
ãã¢ã³ããã¯ãã¦ãMorseCode
ã¤ã³ã¹ã¿ã³ã¹ãçæããè¿ã
play
ç®æ¬¡ã«æ»ã
ã¯ã©ã¹å®ç¾©ã®ç®æ¬¡ã«æ»ã
ç¶ãã¦ã¢ã¼ã«ã¹ä¿¡å·ãåçããplay
ã¡ã½ãããå®ç¾©ãã¦ããã
以ä¸ã該å½é¨åã®ã³ã¼ãã
# ãã®ä¸ã«ã¤ã³ãã¼ãé¨å # ãã®ä¸ã«å¤æãã¼ãã«é¨å # ãã®ä¸ã«ã¯ã©ã¹ã®åºç¤ def play(self, repeat: int = 1, BT: bool = False, AR: bool = False): """ã¢ã¼ã«ã¹ä¿¡å·é³ãåçãã¾ãã Args: repeat (int, optional): æ¬æã®ç¹°ãè¿ãåçæ°ã§ãã BT (bool, optional): éä¿¡éå§ã®åå³ãåçãããã©ããã§ãã AR (bool, optional): éä¿¡çµäºã®åå³ãåçãããã©ããã§ãã """ n = self.minimum_length ct = C2M_TABLE sep_dot = n / 1000 sep_char = sep_dot * 3 sep_word = sep_dot * 7 fq = self.frequency text = ' '.join([self.text for _ in range(repeat)]) if BT: text = '= ' + text if AR: text += ' +' for i, char in enumerate(text): if char == ' ': time.sleep(sep_word) continue elif i: time.sleep(sep_char) for j, dot in enumerate(ct[char]): if j: time.sleep(sep_dot) if dot: Beep(fq, n * 3) else: Beep(fq, n)
ã¢ã¼ã«ã¹ä¿¡å·ã§ã¯çç¹ã®é·ããæéã®åºæºã¨ãªãã6
çç¹ã1
ã¨ããã¨ãã®é·ãã®é¢ä¿ã¯ä»¥ä¸ã®éãã
ç¹ | é·ã |
---|---|
é·ç¹ | 3 |
ç¹ã®é | 1 |
æåã®é | 3 |
åèªã®é | 7 |
ã¢ã¼ã«ã¹ä¿¡å·ãéä¿¡éå§ããåã¨å¾ã«ç¹å®ã®ä¿¡å·BT
, AR
ããéä¿¡ãããããã®ã§ãå¼æ°BT
, AR
ã§ããã®æç¡ãæå®ãã¦ããã7
ã¾ããæ¬æã®åçåæ°ãæå®ãããã¨ãã§ããã
minimum_length
ã¯ããªç§(1/1000ç§
)ãªã®ã§ãtime.sleep
ããéã«ã¯1/1000
ããå¿
è¦ãããã
ããã§ãããããsep_dot
, sep_char
, sep_word
ã¨ãã¦ä»£å
¥ãã¦ããã
text
ãåçåæ°ãåå¾ä¿¡å·ã®æç¡çã§æ´å½¢ããã®ã¡ãfor
æã§å¦çãè¡ã£ã¦ããã
é³ãé³´ããéã®Beep
ã«é¢ãã¦ã¯ä½åº¦ãæ¸ãã¦ããéãWindows
以å¤ã®OSã¯å¥éç¨æãã¦ãããã¨ã
foræå
ã®å¦ç
text
ã®1æåchar
ã¨ãã®ã¤ã³ããã¯ã¹i
ã®for
æ
char
ã空ç½ãã©ãã
sep_word
å¾
æ©ãã¦continue
i
ã0
ã§ã¯ãªãã
sep_char
å¾
æ©ããchar
ã®ã¢ã¼ã«ã¹è¡¨ç¾dot
ã¨ãã®ã¤ã³ããã¯ã¹j
ã®for
æ
j
ã0
ã§ã¯ãªãã
sep_dot
å¾
æ©ããdot
ãé·ç¹ãã©ãã
n * 3
ããªç§é³´ããn
ããªç§é³´ãã
ã¯ã©ã¹å®ç¾©-parse_morse
ç®æ¬¡ã«æ»ã
ã¯ã©ã¹å®ç¾©ã®ç®æ¬¡ã«æ»ã
ã¢ã¼ã«ã¹è¡¨ç¾ã復å·åããparse_morse
ã¡ã½ãããå®ç¾©ãã¦ããã
ããã¯ã¯ã©ã¹ã¡ã½ãããªã®ã§ãã¤ã³ã¹ã¿ã³ã¹ãçæããã«ä½¿ããã¨ãã§ããã
以ä¸ã該å½é¨åã®ã³ã¼ãã
# ãã®ä¸ã«ã¤ã³ãã¼ãé¨å # ãã®ä¸ã«å¤æãã¼ãã«é¨å # ãã®ä¸ã«ã¯ã©ã¹ã®åºç¤ # ãã®ä¸ã«playã¡ã½ãã @classmethod def parse_morse(cls, code: str, *, short: str = '.', long: str = '-', sep: str = ' ', frequency: int = 440, minimum_length: int = 100) -> 'MorseCode': if len({short, long, sep, ' '}) > 4: msg = '3種é¡ä»¥ä¸ã®æåã使ç¨ãããã¨ã¯ã§ãã¾ããã' raise ValueError(msg) if len({short, long, sep}) != 3: msg = 'short, long, sepã¯ããããéãæåã§ããå¿ è¦ãããã¾ãã' raise ValueError(msg) char = code.split(sep) table = M2C_TABLE text = [] for c in char: if c == '': if text[-1] == ' ': continue text.append(' ') else: pattern = [] for p in c: if p == long: pattern.append(1) elif p == short: pattern.append(0) else: msg = f'"{code}"ãã¢ã¼ã«ã¹ä¿¡å·ã¨ãã¦è§£éã§ãã¾ããã§ããã' raise ValueError(msg) text.append(table[tuple(pattern)]) text = ''.join(text) return MorseCode(text, short=short, long=long, sep=sep, frequency=frequency, minimum_length=minimum_length)
å¼æ°ã¯text
ãcode
ã«ãªã£ã¦ããç¹ä»¥å¤ã¯__init__()
ã¨åãã§ããã
注æç¹ã¨ãã¦ã¯code
ã§ä½¿ç¨ããæåã¨short
, long
, sep
ã対å¿ãã¦ããå¿
è¦ãããã
short='s'
ã¨ãã¦ããå ´åã«code
ä¸ã®çç¹ã'.'
ã§è¡¨ããã¨ã¯ã§ããªãã
å¾è¿°ããforæ以éã®å¦ç
c
ã復å
ããæåãå
¥ãããªã¹ãtext
ãç¨æãã¦ãããcode.split(sep)
ã®1æåc
ã®for
æ
c
ã¯short
, long
ãããªãæååã
c
ã空ç½ãã©ãã
continue
text
ã«ç©ºç½ã追å ãã¦continue
0
ã¾ãã¯1
ã®ã¿ãããªããªã¹ãpattern
ãç¨æããc
ã®1ç¹p
ã®for
æ
p
ãlong
ãªã
pattern
ã«1
ã追å p
ãshort
ãªã
pattern
ã«0
ã追å text
ã«M2C_TABLE[tuple(pattern)]
ã追å ããforæ
ãæããã
text
ã''
ã§é£çµãããtext
ããã®ä»å¼æ°ã使ç¨ãã¦MorseCode
ã¤ã³ã¹ã¿ã³ã¹ãçæããè¿ã
å®æã³ã¼ã
å®æããã³ã¼ãã¯ä»¥ä¸ã®éãã¨ãªãã
import time from typing import cast from winsound import Beep from otsuvalidator import VInt, VRegex, VString C2M_TABLE = { '.': (0, 1, 0, 1, 0, 1), ',': (1, 1, 0, 0, 1, 1), '?': (0, 0, 1, 1, 0, 0), '_': (0, 0, 1, 1, 0, 1), '+': (0, 1, 0, 1, 0), '-': (1, 0, 0, 0, 0, 1), 'Ã': (1, 0, 0, 1), '^': (0, 0, 0, 0, 0, 0), '/': (1, 0, 0, 1, 0), '@': (0, 1, 1, 0, 1, 0), '(': (1, 0, 1, 1, 0), ')': (1, 0, 1, 1, 0, 1), '"': (0, 1, 0, 0, 1, 0), '\'': (0, 1, 1, 1, 1, 0), '=': (1, 0, 0, 0, 1), 'A': (0, 1), 'B': (1, 0, 0, 0), 'C': (1, 0, 1, 0), 'D': (1, 0, 0), 'E': (0, ), 'F': (0, 0, 1, 0), 'G': (1, 1, 0), 'H': (0, 0, 0, 0), 'I': (0, 0), 'J': (0, 1, 1, 1), 'K': (1, 0, 1), 'L': (0, 1, 0, 0), 'M': (1, 1), 'N': (1, 0), 'O': (1, 1, 1), 'P': (0, 1, 1, 0), 'Q': (1, 1, 0, 1), 'R': (0, 1, 0), 'S': (0, 0, 0), 'T': (1, ), 'U': (0, 0, 1), 'V': (0, 0, 0, 1), 'W': (0, 1, 1), 'X': (1, 0, 0, 1), 'Y': (1, 0, 1, 1), 'Z': (1, 1, 0, 0), '1': (0, 1, 1, 1, 1), '2': (0, 0, 1, 1, 1), '3': (0, 0, 0, 1, 1), '4': (0, 0, 0, 0, 1), '5': (0, 0, 0, 0, 0), '6': (1, 0, 0, 0, 0), '7': (1, 1, 0, 0, 0), '8': (1, 1, 1, 0, 0), '9': (1, 1, 1, 1, 0), '0': (1, 1, 1, 1, 1), } M2C_TABLE = {x[1]: x[0] for x in C2M_TABLE.items()} MORSE_CODE_REGEX = '^[A-Z0-9 \\.,\\?_\\+\\-Ã\\^\\/@\\(\\)"\'=]*$' class MorseCode: """ã¢ã¼ã«ã¹ä¿¡å·ã¯ã©ã¹ã§ãã æååã®ã¢ã¼ã«ã¹è¡¨ç¾ãåå¾ããããã¢ã¼ã«ã¹ä¿¡å·é³ãåçãããã¨ãã§ãã¾ãã """ text: str = cast(str, VRegex(MORSE_CODE_REGEX, 1)) short: str = cast(str, VString(1, 1)) long: str = cast(str, VString(1, 1)) sep: str = cast(str, VString(1, 1)) frequency: int = cast(int, VInt(37, 32767)) minimum_length: int = cast(int, VInt(1)) def __init__(self, text: str, *, short: str = '.', long: str = '-', sep: str = ' ', frequency: int = 440, minimum_length: int = 100): """textã表ç¾ããã¢ã¼ã«ã¹ä¿¡å·ãçæãã¾ãã textã«å«ããã¨ãã§ããæåã¯"A-Z0-9 .,?-@"ã§ãã ã¾ããé£ç¶ãã空ç½ã¯1ã¤ã¨ãã¦æ±ããã¾ãã Args: text (str): å ã¨ãªãæååã§ãã short (str, optional): çç¹ã«ä½¿ç¨ããæåã§ãã long (str, optional): é·ç¹ã«ä½¿ç¨ããæåã§ãã sep (str, optional): æåéã®åºåãã«ä½¿ç¨ããæåã§ãã frequency (int, optional): åçæã®å¨æ³¢æ°Hzã§ãã minimum_length (int, optional): åçæã®çç¹ã®é·ãã§ãã Raises: ValueError: short, long, sepã«éè¤ããæåããã¦ããã¨ã¯ã§ãã¾ããã """ if len({short, long, sep}) != 3: msg = 'short, long, sepã¯ããããéãæåã§ããå¿ è¦ãããã¾ãã' raise ValueError(msg) self.short = short self.long = long self.sep = sep self.frequency = frequency self.minimum_length = minimum_length while ' ' in text: text = text.replace(' ', ' ') self.text = text.upper() ct = C2M_TABLE s = self.short l = self.long res = [] for c in self.text: if c == ' ': res.append(' ') else: res.append(''.join(map(lambda x: l if x else s, ct[c]))) self.__morse_code = self.sep.join(res) def __str__(self) -> str: return self.text def __add__(self, other) -> 'MorseCode': kwargs = { 'short': self.short, 'long': self.long, 'sep': self.sep, 'minimum_length': self.minimum_length, } if type(other) is MorseCode or type(getattr(other, 'text', None)) is str: kwargs['text'] = self.text + other.text else: kwargs['text'] = self.text + other return MorseCode(**kwargs) @property def morse_code(self) -> str: """ã¢ã¼ã«ã¹è¡¨ç¾åããæååãè¿ãã¾ãã Returns: str: ã¢ã¼ã«ã¹è¡¨ç¾ã§ãã """ return self.__morse_code def play(self, repeat: int = 1, BT: bool = False, AR: bool = False): """ã¢ã¼ã«ã¹ä¿¡å·é³ãåçãã¾ãã Args: repeat (int, optional): æ¬æã®ç¹°ãè¿ãåçæ°ã§ãã BT (bool, optional): éä¿¡éå§ã®åå³ãåçãããã©ããã§ãã AR (bool, optional): éä¿¡çµäºã®åå³ãåçãããã©ããã§ãã """ n = self.minimum_length ct = C2M_TABLE sep_dot = n / 1000 sep_word = sep_dot * 7 sep_char = sep_dot * 3 fq = self.frequency text = ' '.join([self.text for _ in range(repeat)]) if BT: text = '= ' + text if AR: text += ' +' for i, char in enumerate(text): if char == ' ': time.sleep(sep_word) continue elif i: time.sleep(sep_char) for j, dot in enumerate(ct[char]): if j: time.sleep(sep_dot) if dot: Beep(fq, n * 3) else: Beep(fq, n) @classmethod def parse_morse(cls, code: str, *, short: str = '.', long: str = '-', sep: str = ' ', frequency: int = 440, minimum_length: int = 100) -> 'MorseCode': if len({short, long, sep, ' '}) > 4: msg = '3種é¡ä»¥ä¸ã®æåã使ç¨ãããã¨ã¯ã§ãã¾ããã' raise ValueError(msg) if len({short, long, sep}) != 3: msg = 'short, long, sepã¯ããããéãæåã§ããå¿ è¦ãããã¾ãã' raise ValueError(msg) char = code.split(sep) table = M2C_TABLE text = [] for c in char: if c == '': if text[-1] == ' ': continue text.append(' ') continue pattern = [] for p in c: if p == long: pattern.append(1) elif p == short: pattern.append(0) else: msg = f'"{code}"ãã¢ã¼ã«ã¹ä¿¡å·ã¨ãã¦è§£éã§ãã¾ããã§ããã' raise ValueError(msg) text.append(table[tuple(pattern)]) text = ''.join(text) return MorseCode(text, short=short, long=long, sep=sep, frequency=frequency, minimum_length=minimum_length)
使ãæ¹
ä¸ã®ã³ã¼ããã³ãã¼ãã¦ãå¥ã¢ã¸ã¥ã¼ã«ããã¤ã³ãã¼ããããè¯ããåããã¡ã¤ã«ã«æ¸ãã¦ä½¿ç¨ãããè¯ãã
å¾æ¥github
çµç±ã®ã¤ã³ã¹ãã¼ã«ãããã¯ã§ããããã«ããâ¦â¦ããï¼
ã¤ã³ã¹ãã¼ã«ã§ããããã«ãªã£ãã
ããããã¯ãããgithub
ã®ãªãã¸ããªã¯ããã
from morse_code import MorseCode # åããã©ã«ãå ã®`morse_code.py`ã«ã³ãã¼ããå ´å def show_morse(mc: MorseCode): print(f'"{mc}" "{mc.morse_code}"') # ã¢ã¼ã«ã¹ã¤ã³ã¹ã¿ã³ã¹çæ paris = MorseCode('paris') show_morse(paris) # ã¢ã¼ã«ã¹ + ã¢ã¼ã«ã¹(æåæå®) hello = MorseCode('hello') python = MorseCode('python', short='0', long='1') show_morse(hello + python) # ã¢ã¼ã«ã¹ + ã¢ã¼ã«ã¹(æåæå®) show_morse(python + hello) # ã¢ã¼ã«ã¹ + æåå show_morse(hello + ' otsuhachi') # ã¢ã¼ã«ã¹å¾©å·å m2c = MorseCode.parse_morse('.- .-. . -.-- --- ..- - .... . .-. . ..--..') show_morse(m2c) # åç m2c.play(BT=True, AR=True) # ã¢ã¼ã«ã¹ + æ´æ° (ä¾å¤çºç) # show_morse(hello + 1) """ Traceback (most recent call last): File "~\sandbox.py", line 24, in <module> show_morse(hello + 1) File "~\morse_code.py", line 133, in __add__ kwargs['text'] = self.text + other TypeError: can only concatenate str (not "int") to str """
"PARIS" ".--. .- .-. .. ..." "HELLOPYTHON" ".... . .-.. .-.. --- .--. -.-- - .... --- -." "PYTHONHELLO" "0110 1011 1 0000 111 10 0000 0 0100 0100 111" "HELLO OTSUHACHI" ".... . .-.. .-.. --- --- - ... ..- .... .- -.-. .... .." "ARE YOU THERE?" ".- .-. . -.-- --- ..- - .... . .-. . ..--.."
ç¡äºãä½æãããã¨ãã§ããã
ã³ã¼ããæ¸ããããè¨äºã«ããæ¹ãç²ããã
ã¤ã³ã¹ãã¼ã«
以ä¸ã®ã³ãã³ããå®è¡ãããã¨ã§ã¤ã³ã¹ãã¼ã«ã§ããã
pip install git+https://github.com/Otsuhachi/OtsuMorseCode
使ãæ¹ã¯ä¸ã§ç¤ºããéãã
-
ä»åã¯ã¢ã«ãã¡ãããã®ã¿å¯¾å¿ãã¦ããã°ååã ã£ãã®ã§ãå®è£ ãã¦ããªãã↩
-
ãããåè±ãè¨å®å¯è½ãª
MorseCode
ã¯ã©ã¹ãä½æããããã°ãåã«å¯¾å¿ããæ£è¦è¡¨ç¾
ãå¥éè¨å®ããå¿ è¦ãããã↩ -
ã¨ãã£ã¿ã®ã¨ã©ã¼ãæ°ã«ããªããªã
# type: ignore
ã¯ãªãã¦ãããã↩ -
ãã®æç¹ã§
otsuvalidator
ã®ããªãã¼ã¿ãå¼æ°ã®å¤ãæ¤è¨¼ãã¦ããã↩ -
ãã®æç¹ã§ä¾å¤ãçºçããå¯è½æ§ãããã↩
-
ãã®ã¯ã©ã¹ã§ã¯
minimum_length
å±æ§ãçç¹ã®é·ã↩ -
BT
ã¯=
,AR
ã¯+
ã¨åãã¢ã¼ã«ã¹è¡¨ç¾ã«ãªãã↩
Pythonã§æååãã¢ã¼ã«ã¹ä¿¡å·ã«å¤æãã -å®ç¾©ç·¨-
ä»åã¯ã¿ã¤ãã«éãæååãã¢ã¼ã«ã¹ä¿¡å·ã«å¤æããã©ã¤ãã©ãªãä½ã£ã¦ã¿ã(å®ç¾©ç·¨)ã
å®è£
ç·¨ã«ã¤ãã¦ã¯ãã¡ãã
Windows
éå®ã§ãä»OSç¨ã®å·®ãæ¿ãã«ã¤ãã¦ã¯å®è£
ç·¨ã®æå¾ã®æ¹ã§å°ã触ããç¨åº¦ã«ãªãäºå®ã
ã¾ãèªä½ã©ã¤ãã©ãªotsuvalidatorã使ç¨ããã®ã§(宣ä¼ï¼)ã¤ã³ã¹ãã¼ã«ãå¿
è¦ã
ãã以å¤ã®éæ¨æºã©ã¤ãã©ãªã¯ä¸ä½¿ç¨ã
ä»æ§ã決ãã
å¤æå¯è½ãªæåå
対å¿ããã®ã¯åè§è±æ°åã¨.,?_+-Ã^/@()"'=
ããããåè§ç©ºç½ã
ã¾ããåè§è±åã¯ãã¹ã¦å¤§æåã«å¤æãã¦æ±ãã
é£ç¶ãã空ç½ã¯1ã¤ã¨ãã¦æ±ãã
åé³å¯¾å¿ãèããã¨éè¤ãããã¿ã¼ã³ãåºã¦ãã¾ãã®ã§ç¡ãã
åºå
æååã¨ãã¦åºåããéã«ã¯å
ã®ããã¹ã1ã表示ãããã¨ã«ããã
ã¾ãmorse_code
ã¨ããå±æ§ã§ã¢ã¼ã«ã¹è¡¨ç¾
ãåå¾ã§ããããã«ããã
ã¤ã³ã¹ã¿ã³ã¹çæ
å¼æ°ã¨ãã¦ä½¿ç¨ããã®ã¯ä»¥ä¸ã®éãã
åå | å | æ¦è¦ |
---|---|---|
text | str | ã¢ã¼ã«ã¹ã¨ãã¦æ±ãããæåå |
short | str | ã¢ã¼ã«ã¹ä¿¡å·ã®çç¹1ã¨ãã¦æ±ãããæå |
long | str | ã¢ã¼ã«ã¹ä¿¡å·ã®é·ç¹1ã¨ãã¦æ±ãããæå |
sep | str | ã¢ã¼ã«ã¹ä¿¡å·ã®æåé1ã«ä½¿ç¨ãããæå |
frequency | int | åçæã«ä½¿ç¨ããå¨æ³¢æ°37 ï½32767 ã®é |
minimum_length | int | åçæã®1é³ã®é·ã(ããªç§) |
以ä¸ã®å
ãå¿
é ãªã®ã¯text
ã®ã¿ã
short
, long
, sep
ã¯1æå
ã§ããããç°ãªãå¿
è¦ãããã
minimum_length
ã¯åçæã®åºæºã¨ãªãé·ãã
æ©è½
é¢æ° | æ¦è¦ | åè |
---|---|---|
play | ã¢ã¼ã«ã¹ä¿¡å·ãåçãã | |
parse_morse | ã¢ã¼ã«ã¹è¡¨ç¾ããMorseCode ã¤ã³ã¹ã¿ã³ã¹ãçæãã |
ã¯ã©ã¹ã¡ã½ãã |
__add__ | MorseCode ã¤ã³ã¹ã¿ã³ã¹ã¾ãã¯strå+x ã§ã¨ã©ã¼ãçºçããªããªãã¸ã§ã¯ãx ããMorseCode ã¤ã³ã¹ã¿ã³ã¹ãçæããæ¬æ以å¤ã® __init__ ç¨å¼æ°ã¯self ããå¼ãç¶ã |
足ãç®ç¨ã®ãã¸ãã¯ã¡ã½ãã |
play
ã¢ã¼ã«ã¹ä¿¡å·ãåçããã
å¼æ°ã¯ä»¥ä¸ã®éãã
åå | å | æ¦è¦ |
---|---|---|
repeat | int | æ¬æã®ç¹°ãè¿ãåæ° |
BT | bool | æ¬æåçåã«éä¿¡éå§ã®åå³BT ãåçãããã©ãã |
AR | bool | æ¬æåçå¾ã«éä¿¡çµäºã®åå³AR ãåçãããã©ãã |
å¿ é å¼æ°ã¯ç¡ãã
parse_morse
ã¢ã¼ã«ã¹è¡¨ç¾ãåºã«ã¢ã¼ã«ã¹ä¿¡å·ã¤ã³ã¹ã¿ã³ã¹ãçæããã
å¼æ°ã¯ä»¥ä¸ã®éãã
åå | å | æ¦è¦ |
---|---|---|
code | str | ã¢ã¼ã«ã¹è¡¨ç¾ã®æååshort , long , sep ã¨åè§ç©ºç½ä»¥å¤ã®æåãå«ãã§ã¯ãªããªã |
short | str | ã¢ã¼ã«ã¹ä¿¡å·ã®çç¹[^2]ã¨ãã¦æ±ãããæå |
long | str | ã¢ã¼ã«ã¹ä¿¡å·ã®é·ç¹[^3]ã¨ãã¦æ±ãããæå |
sep | str | ã¢ã¼ã«ã¹ä¿¡å·ã®æåé[^4]ã«ä½¿ç¨ãããæå |
frequency | int | åçæã«ä½¿ç¨ããå¨æ³¢æ°37 ï½32767 ã®é |
minimum_length | int | åçæã®1é³ã®é·ã(ããªç§) |
å¿
é å¼æ°ã¯code
ã®ã¿ã
注æç¹ã¨ãã¦ãX
ã¨Ã
ãåãã¢ã¼ã«ã¹è¡¨ç¾ã«ãªããã1Ã2=2
ã¨ãªããããªã¢ã¼ã«ã¹è¡¨ç¾ãä¸ããå ´å1X2=2
ã¨ãã¦è§£éããã¦ãã¾ãã
__add__
MorseCodeã¤ã³ã¹ã¿ã³ã¹ + object
ã¨ããå¼ãå®è¡ããããã®ãã¸ãã¯ã¡ã½ããã
MorseCodeã¤ã³ã¹ã¿ã³ã¹ += object
ã¯é対å¿ãªã®ã§æ³¨æã
object
ã¯MorseCodeã¤ã³ã¹ã¿ã³ã¹
ãstr + object
ãã¨ã©ã¼ã«ãªããªããã®ã§ããã°OKã
self
ããtext
以å¤ã®ã¤ã³ã¹ã¿ã³ã¹çæã§åãåãå¼æ°ãåãç¶ãã§ãæ°ããtext
ãæã¤MorseCodeã¤ã³ã¹ã¿ã³ã¹
ãçæããã
Pythonçµã¿è¾¼ã¿é¢æ°8 -chrã»ordç·¨-
Pythonãããã第8段
å¶ç´ã¨ãã¦å
¬å¼ããã¥ã¡ã³ãã®ã¿åç
§*1ã¨ãã¦ãèªãçãã¤ããè¨ç·´ãå
¼ããã
ä»åã¯chré¢æ°
ã¨ordé¢æ°
ã®2種é¡ã«ã¤ãã¦ã
chr
ã¯æ´æ°ã«å¯¾å¿ããæåãè¿ããord
ã¯ãã®éã«æåã«å¯¾å¿ããæ´æ°ãè¿ãã
æ´æ°ã¨æåã®å¯¾å¿ã¯Unicode
ã§åç
§ãã¦ãããããã
å 容çã«ã¯ããã§å ¨é¨ãªæ°ãããã®ã§ãè足ããããªããã°ããã§çµäºã解æ£ï¼
èªã¿è¾¼ãããã¥ã¡ã³ãã¯ãã¡ã[chr, ord]
æ§æ
ä»åã®é¢æ°ã¯ä»¥ä¸ã®ããã«ãªã£ã¦ããã
chr(i)
ord(c)
i
ã¯intå
, c
ã¯strå
1ã表ãã
使ã£ã¦ã¿ã
ã
ï½ã
ã表示ããã¦ã¿ããã¨ã«ããã
ã¾ããå¤æåã®æ´æ°ã«ã¤ãã¦ã¯16é²æ°
ã§è¡¨ãã
å®è¡ããã³ã¼ãã¯ä»¥ä¸ã®éãã
for i in range(ord('ã'), ord('ã') + 1): print(f'{i:X} -> {chr(i)}')
3042 -> ã 3043 -> ã 3044 -> ã 3045 -> ã 3046 -> ã 3047 -> ã 3048 -> ã 3049 -> ã 304A -> ã 304B -> ã 304C -> ã 304D -> ã 304E -> ã 304F -> ã 3050 -> ã 3051 -> ã 3052 -> ã 3053 -> ã 3054 -> ã 3055 -> ã 3056 -> ã 3057 -> ã 3058 -> ã 3059 -> ã 305A -> ã 305B -> ã 305C -> ã 305D -> ã 305E -> ã 305F -> ã 3060 -> ã 3061 -> ã¡ 3062 -> 㢠3063 -> 㣠3064 -> 㤠3065 -> 㥠3066 -> 㦠3067 -> 㧠3068 -> 㨠3069 -> ã© 306A -> 㪠306B -> ã« 306C -> 㬠306D -> ã 306E -> ã® 306F -> 㯠3070 -> ã° 3071 -> ã± 3072 -> ã² 3073 -> ã³ 3074 -> ã´ 3075 -> ãµ 3076 -> 㶠3077 -> ã· 3078 -> 㸠3079 -> ã¹ 307A -> 㺠307B -> ã» 307C -> ã¼ 307D -> ã½ 307E -> ã¾ 307F -> ã¿ 3080 -> ã 3081 -> ã 3082 -> ã 3083 -> ã 3084 -> ã 3085 -> ã 3086 -> ã 3087 -> ã 3088 -> ã 3089 -> ã 308A -> ã 308B -> ã 308C -> ã 308D -> ã 308E -> ã 308F -> ã 3090 -> ã 3091 -> ã 3092 -> ã 3093 -> ã
ä»åã®åºåã¯ããã®è¡¨ã¨å¯¾å¿ãã¦ããã®ããããã
ord
ã§åå¾ã§ããæ´æ°ã¯ã4æ¡ã®16é²æ°ã«å¤æãã¦'\uXXXX'
ã¨ãããã¨ã§ã¦ãã³ã¼ãã¨ã¹ã±ã¼ãã¨ãã¦ä½¿ç¨ã§ããã
ããã«chr
ã§0xXXXX
ã調ã¹ããã¨ã§å
ã®æåã調ã¹ããã¨ãã§ããã
'\uXXXX'
ã®ãããªæååãè¦ãããéã¯è©¦ãã¦ããããããããªãã
ç· ã
ä»åç´¹ä»ããé¢æ°ã¯ãã¾ãã¡ä½¿ãã©ãããé åãããããã£ã¦ããªãã
ä¸å¿ãä¸ã®ä¾ã®ããã«æ°åã§ã¯ç¯å²ãããããããªãã
ï½ã
ãrange
ã§æå®ãããã¨ãã§ãã¦ããããã·ã³ãã«ãª50é³ãåå¾ã§ãã¦ããããã§ã¯ãªãã®ã§ãå®ç¨æ§ã¨ããç¹ã§ã¯é¦ãæ»ããããå¾ãªãã
A
ï½Z
ã§ããã°æå®ã§ãããâ¦â¦ã
ãµãã¿ã¤ãºãæå·åã§ä½¿ç¨ããã®ã ãããâ¦â¦ã
ãã¾ãã¡ç· ã¾ããªããããã以ä¸ã®ãã¨ãæ¸ããã¨ãã§ããªãã®ã§ããã«ã¦ã
Pythonã§ã¯charå
ãåå¨ããªããã
-
ãã ã1æåã§ããå¿ è¦ããã↩
*1:ãããããã解説ãã¦ããä»ãµã¤ããè¦ãªã