一套小工具

bluewindde / 2024-09-13 / 原文

本文作者 Yile Wang,在 GNU Free Documentation License version 1.3 下发布。不提供任何担保。

本文给出的部分代码在 GNU General Public License version 3, or any later version 下发布,详见对应代码的文件头声明。

COPYING

Copyright (c)  2024  Yile Wang
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".

BRIEFING

这是一个小工具集合,作者希望它有用,但不提供任何担保。

MENU

  • random_prime
  • checker
  • nospace
  • sweeper
  • find_problem

random_prime

\([l, r]\) 之间随机选择一个数,找出第一个不小于它的质数并输出。

import math

def chkprime(x: int) -> bool:
    p = int(math.sqrt(x))
    if x == 1:
        return False
    if x == 2:
        return True
    for i in range(2, p + 1):
        if x % i == 0:
            return False
    return True

import random

l = int(1e9)
r = int(2e9)

x = random.randint(l, r)
while not chkprime(x):
    x += 1
print(x)

checker

简单的文件比对,推荐更强大的比对工具 GNU Diffutils。

out = "/path/to/out"
ans = "/path/to/ans"

with open(out) as file:
    out = file.readlines()
with open(ans) as file:
    ans = file.readlines()

for i in range(len(ans)):
    if len(out) <= i:
        print("miss")
        break
    if out[i] != ans[i]:
        print("err:", i + 1)

nospace

去除 C++ 代码文件中多余的空格,你可以通过调整代码开头的选项改变其行为。对代码的修改也应使用 GNU 通用公共许可证(第三版以上)发布。

"""
nospace.py
Copyright (C) 2024  Yile Wang

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

======================================================================

You can contact the author by email. (mailto:bluewindde@163.com)

This program expects to do as follow: remove unnecessary space from
C++ source file.
"""

FIRST_OF_ALL = """
nospace.py  Copyright (C) 2024  Yile Wang
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
Learn more in the copyright statement at the beginning
of the source code.
"""

print(FIRST_OF_ALL)

# 忽略注释 NotImplemented
ignore_comment = False
# 忽略行尾空格
ignore_ending_space = False
# 忽略预编译指令
ignore_precopile_command = True

path = "/path/to/cpp"

with open(path, "r", encoding="utf-8") as file:
    text = file.read().splitlines()

def chk(x: str, y: str) -> bool:
    flag1 = flag2 = False
    if x.islower() or x.isupper() or x.isdigit():
        flag1 = True
    if y.islower() or y.isupper() or y.isdigit():
        flag2 = True
    return (flag1 and flag2) or x == " " or y == " "

ret = []
for i in range(len(text)):
    if ignore_ending_space:
        para = text[i]
    else:
        para = text[i].rstrip()
    if ignore_precopile_command and len(para) != 0 and para[0] == "#":
        ret.append(para)
        continue
    ret.append("")
    for j in range(len(para)):
        ch = para[j]
        if ch == " ":
            if j > 0 and j < len(para) - 1 and not chk(para[j - 1], para[j + 1]):
                continue
        ret[-1] += ch

with open(path + ".ret.cpp", "w", encoding="utf-8") as file:
    for para in ret:
        file.write(para)
        file.write("\n")

sweeper

寻找当前工作目录下可能无用的文件,并询问是否删除。

你可以通过修改源代码自定义程序的行为,部分参数在代码中有注释说明。请注意,你修改后的程序仍应以 GNU 通用公共许可证(第三版以上)发布。

"""
sweeper.py
Copyright (C) 2024  Yile Wang

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

======================================================================

You can contact the author by email. (mailto:bluewindde@163.com)

This program expects to do as follow: walk current directory then find
maybe-useless files.
"""

FIRST_OF_ALL = """
sweeper.py  Copyright (C) 2024  Yile Wang
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
Learn more in the copyright statement at the beginning
of the source code.
"""

print(FIRST_OF_ALL)

import os

def isexec(path: str):
    """
    如果 path 指向 ELF 文件,返回 True;否则返回 False
    """
    try:
        file = open(path, "rb")
        if file.read(4)[1:] == b"ELF":
            return True
        return False
    except OSError:
        return False

ignore = [] # 不扫描的子文件夹,相对路径和绝对路径均可
def isignore(path: str) -> bool:
    """
    如果 path 指向被忽略的文件夹,返回 True;否则返回 False
    """
    path = os.path.normpath(path)
    for dir in ignore:
        if dir.startswith("."):
            dir = os.path.join(os.getcwd(), dir)
        dir = os.path.normpath(dir)
        if path == dir:
            print(f"\033[34mignore:\033[0m {path}")
            return True
        elif path.startswith(dir):
            return True

exts = [] # 被认为“无用”的文件拓展名
def iswaste(path: str) -> bool:
    """
    如果 path 指向无用文件,返回 True;否则返回 False
    """
    for ext in exts:
        if path.endswith(ext):
            return True
    if isexec(path):
        return True
    return False

def sweep(path: str):
    """
    清扫 path 指向的文件夹
    """
    aim = []
    for dirpath, dirnames, filenames in os.walk(path):
        if isignore(dirpath):
            continue
        print(f"\033[34msweeping:\033[0m {dirpath}:")
        for file in filenames:
            print(f"\tchecking: {file}...", end="")
            path = os.path.join(dirpath, file)
            flag = iswaste(path)
            if flag == True:
                print("\033[33mwaste.\033[0m")
                aim.append(path)
            elif flag is None:
                print("\033[31mpermission denied.\033[0m")
            else:
                print("\033[32mok.\033[0m")
    if len(aim) == 0:
        print("won't remove any file.")
        return
    elif len(aim) == 1:
        print("would remove 1 file:")
    else:
        print(f"would remove {len(aim)} files:")
    for file in aim:
        print(f"\t{file}")
    confirm = input("confirm ? [Y/n] ").strip()
    if confirm == "Y" or confirm == "y":
        failed = []
        for file in aim:
            try:
                os.remove(file)
            except Exception as msg:
                failed.append((file, msg))
        if len(failed) > 0:
            print("\033[31mfailed\033[0m while removing files below:")
            for file, err in failed:
                print(f"\t{file}: {err}")
        else:
            print("\033[32msuccess.\033[0m")

if __name__ == "__main__":
    try:
        os.chdir(os.path.dirname(__file__))
    except OSError:
        pass
    sweep(os.getcwd())

find_problem

尝试寻找可能为算法竞赛题目编号的字段并输出。

"""
find_problem.py
Copyright (C) 2024  Yile Wang

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

======================================================================

You can contact the author by email. (mailto:bluewindde@163.com)

This program expects to do as follow: read a Markdown file,
find and output possible problem from competitive programming.
"""

FIRST_OF_ALL = """
find_problem.py  Copyright (C) 2024  Yile Wang
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
Learn more in the copyright statement at the beginning
of the source code.
"""

print(FIRST_OF_ALL)

path = input("Type or paste the path to file here: ")

import re

patterns = [
    r"\bLuogu [BP][0-9]+\b",
    r"\bCodeForces [1-9][0-9]*[A-Z][1-9]?\b",
    r"\b((AGC)|(ABC)|(ARC))[0-9]+[A-Z]\b",
    r"\bSPOJ [A-Z]+[2-9]?\b",
    r"\bUVA[1-9][0-9]*\b",
    r"\bUOJ[1-9][0-9]*\b",
    r"\bLOJ[1-9][0-9]*\b",
]

try:
    ret = []
    with open(path, "r", encoding="utf-8") as file:
        ln = 0
        for line in file.readlines():
            ln += 1
            if line.strip().startswith("-") or line.strip().startswith(">"):
                continue
            for pattern in patterns:
                cur = re.findall(pattern, line)
                ret += cur
                for id in cur:
                    print(f"ln {ln}: {id}")
except Exception as err:
    print(f"error: {err}")
else:
    print()
    print(f"In total: {len(ret)}")
    print("Problem ID are as follow:")
    for id in ret:
        print(id, end=", ")
    print()