millerlib 1.0.1__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.
@@ -0,0 +1,22 @@
1
+ Metadata-Version: 2.4
2
+ Name: millerlib
3
+ Version: 1.0.1
4
+ Summary: Набор CLI и GUI утилит: таблицы истинности, системы счисления, битовые сдвиги
5
+ Author: Твое Имя/Никнейм
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.6
10
+ Description-Content-Type: text/markdown
11
+ Dynamic: author
12
+ Dynamic: classifier
13
+ Dynamic: description
14
+ Dynamic: description-content-type
15
+ Dynamic: requires-python
16
+ Dynamic: summary
17
+
18
+ Запустить приложение:
19
+
20
+ launch_app_ui() - запуск CLI программы
21
+
22
+ launch_app_gui() - запуск GUI программы
@@ -0,0 +1,5 @@
1
+ Запустить приложение:
2
+
3
+ launch_app_ui() - запуск CLI программы
4
+
5
+ launch_app_gui() - запуск GUI программы
@@ -0,0 +1,331 @@
1
+ from time import sleep
2
+ import tkinter as tk
3
+ from tkinter import messagebox, simpledialog
4
+
5
+ # ==========================================
6
+ # 1. СИСТЕМЫ СЧИСЛЕНИЯ (Логика)
7
+ # ==========================================
8
+ class BaseConverter:
9
+ def __init__(self, alphabet="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
10
+ self.letters = alphabet
11
+
12
+ def to_10(self, number, base):
13
+ a = str(number).upper()
14
+ dec = 0
15
+ for i in range(len(a)):
16
+ dec += (self.letters.find(a[i])) * base**(len(a)-i-1)
17
+ return dec
18
+
19
+ def from_10(self, number, base):
20
+ a = int(number)
21
+ if a == 0: return self.letters[0]
22
+ k = ""
23
+ while a > 0:
24
+ k = k + self.letters[a % base]
25
+ a //= base
26
+ return k[::-1]
27
+
28
+ def base_to_base(self, number, base, to_base):
29
+ a = self.to_10(number, base)
30
+ return self.from_10(a, to_base)
31
+
32
+ # ==========================================
33
+ # 2. УМНОЖЕНИЕ БИТОВЫМ СДВИГОМ (Логика)
34
+ # ==========================================
35
+ def bitwise_multiply(a, b):
36
+ result = 0
37
+ steps = []
38
+ abs_a, abs_b = abs(a), abs(b)
39
+ steps.append(f"Умножаем {abs_a} на {abs_b} битовым сдвигом:")
40
+
41
+ while abs_b > 0:
42
+ step_info = f"[A={abs_a:<4} | B={abs_b:<4}] Младший бит B: {abs_b & 1}"
43
+ if abs_b & 1:
44
+ result += abs_a
45
+ step_info += f" -> Прибавляем A. (Сумма: {result})"
46
+ else:
47
+ step_info += f" -> Пропускаем."
48
+
49
+ steps.append(step_info)
50
+ abs_a <<= 1
51
+ abs_b >>= 1
52
+
53
+ if (a < 0 and b > 0) or (a > 0 and b < 0):
54
+ result = -result
55
+ return result, steps
56
+
57
+ # ==========================================
58
+ # 3. ТАБЛИЦА ИСТИННОСТИ (Логика)
59
+ # ==========================================
60
+ english_alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
61
+ "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
62
+
63
+ PREC = {"not": 5, "and": 4, "xor": 3, "or": 2, "->": 1, "=": 0}
64
+ RIGHT = {"not", "->", "="}
65
+
66
+ SYMB = {
67
+ "+": "or", "or": "or", "*": "and", "and": "and",
68
+ "xor": "xor", "XOR": "xor", "!=": "xor",
69
+ "not": "not", "->": "->", "=>": "->", "=": "=", "==": "="
70
+ }
71
+ DISPLAY_SYM = {"and": "*", "or": "+", "xor": "xor", "->": "->", "=": "="}
72
+
73
+ def apply_op(op, a, b=None):
74
+ if op == "not": return not a
75
+ if op == "and": return a and b
76
+ if op == "or": return a or b
77
+ if op == "xor": return a != b
78
+ if op == "->": return (not a) or b
79
+ if op == "=": return a == b
80
+ raise ValueError("Неизвестный оператор: " + str(op))
81
+
82
+ def remove_outer_brackets(s):
83
+ if not (s.startswith("(") and s.endswith(")")): return s
84
+ depth = 0
85
+ for i in range(len(s)):
86
+ if s[i] == "(": depth += 1
87
+ elif s[i] == ")": depth -= 1
88
+ if depth == 0 and i < len(s) - 1: return s
89
+ return s[1:-1]
90
+
91
+ def prettify(name):
92
+ name = remove_outer_brackets(name)
93
+ changed = True
94
+ while changed:
95
+ changed = False
96
+ new_name = ""
97
+ i = 0
98
+ while i < len(name):
99
+ if name.startswith("(not ", i):
100
+ j = name.find(")", i)
101
+ if j != -1:
102
+ inner = name[i + 5:j]
103
+ if " " not in inner and "(" not in inner and ")" not in inner:
104
+ new_name += "not " + inner
105
+ i = j + 1
106
+ changed = True
107
+ continue
108
+ new_name += name[i]
109
+ i += 1
110
+ name = new_name
111
+ return name
112
+
113
+ def calculate(h, params):
114
+ values = {p[0]: bool(p[1]) for p in params}
115
+ out, ops, steps = [], [], []
116
+
117
+ def apply_top():
118
+ op = ops.pop()
119
+ if op == "not":
120
+ name, val = out.pop()
121
+ new = ("(not " + name + ")", not val)
122
+ else:
123
+ b_name, b_val = out.pop()
124
+ a_name, a_val = out.pop()
125
+ new = ("(" + a_name + " " + DISPLAY_SYM[op] + " " + b_name + ")", apply_op(op, a_val, b_val))
126
+ out.append(new)
127
+ steps.append(new)
128
+
129
+ for t in h:
130
+ if t == "(": ops.append(t)
131
+ elif t == ")":
132
+ while ops and ops[-1] != "(": apply_top()
133
+ ops.pop()
134
+ elif t in PREC:
135
+ while (ops and ops[-1] != "(" and
136
+ (PREC[ops[-1]] > PREC[t] or (PREC[ops[-1]] == PREC[t] and t not in RIGHT))):
137
+ apply_top()
138
+ ops.append(t)
139
+ elif t in values: out.append((t, values[t]))
140
+
141
+ while ops: apply_top()
142
+ return steps
143
+
144
+ def custom_tabulate(headers, rows):
145
+ """Кастомный рендер таблиц без сторонних библиотек"""
146
+ col_widths = [len(str(h)) for h in headers]
147
+ for row in rows:
148
+ for i, cell in enumerate(row):
149
+ col_widths[i] = max(col_widths[i], len(str(cell)))
150
+
151
+ separator = "+" + "+".join("-" * (w + 2) for w in col_widths) + "+"
152
+ lines = [separator]
153
+
154
+ header_str = "|" + "|".join(f" {str(headers[i]).center(col_widths[i])} " for i in range(len(headers))) + "|"
155
+ lines.append(header_str)
156
+ lines.append(separator)
157
+
158
+ for row in rows:
159
+ row_str = "|" + "|".join(f" {str(row[i]).center(col_widths[i])} " for i in range(len(row))) + "|"
160
+ lines.append(row_str)
161
+
162
+ lines.append(separator)
163
+ return "\n".join(lines)
164
+
165
+
166
+ # ==========================================
167
+ # 4. КОНСОЛЬНЫЙ ИНТЕРФЕЙС (CLI)
168
+ # ==========================================
169
+ width_programm = 60
170
+ converter = BaseConverter()
171
+
172
+ def clear(): print("\n" * 40)
173
+ def group(num, symbol): print((symbol * width_programm + "\n") * (num - 1), end=""); print(symbol * width_programm)
174
+ def pregroup(string, space, symbol): print(symbol * max(0, (width_programm - len(string) - space * 2) // 2) + " " * space + string + " " * space + symbol * max(0, (width_programm - len(string) - space * 2) // 2))
175
+ def warning(text, space): group(1, "!"); pregroup(text, space, "!"); group(1, "!"); sleep(1); input("Нажмите ENTER..."); clear()
176
+ def print_centered(text):
177
+ for line in text.split("\n"): print(" " * max(0, (width_programm - len(line)) // 2) + line)
178
+
179
+ def cli_truth_table():
180
+ clear()
181
+ group(3, "-"); pregroup("ТАБЛИЦА ИСТИННОСТИ", 3, "-"); group(3, "-")
182
+ raw = input("Введите выражение: ").replace("(", " ( ").replace(")", " ) ")
183
+ tokens = raw.split()
184
+ a = [SYMB.get(t, t) for t in tokens]
185
+ params, lettersin = [], []
186
+ for i in english_alphabet:
187
+ if i in a: params.append([i, 0]); lettersin.append(i)
188
+
189
+ if not params: return warning("В выражении нет переменных!", 2)
190
+
191
+ try: steps_example = calculate(a, params)
192
+ except Exception as e: return warning(f"Ошибка: {e}", 2)
193
+
194
+ step_names = [prettify(name) for name, _ in steps_example]
195
+ columns = lettersin + step_names
196
+ results = [[] for _ in range(len(columns))]
197
+ end = False
198
+
199
+ while not end:
200
+ for i in range(len(params) - 1, 0, -1):
201
+ if params[i][1] == 2: params[i][1] = 0; params[i - 1][1] += 1
202
+ if params[0][1] == 2: end = True
203
+ else:
204
+ for i in range(len(params)): results[i].append(params[i][1])
205
+ steps = calculate(a, params)
206
+ for j in range(len(steps)): results[len(lettersin) + j].append(int(steps[j][1]))
207
+ params[-1][1] += 1
208
+
209
+ rows = list(zip(*results))
210
+ table_text = custom_tabulate(columns, rows)
211
+
212
+ clear()
213
+ group(1, "="); pregroup("Результат:", 3, "="); group(1, "=")
214
+ print()
215
+ print_centered(table_text)
216
+ print()
217
+ warning("Готово!", 3)
218
+
219
+ def launch_app_ui():
220
+ """Запускает программу в режиме консоли"""
221
+ while True:
222
+ clear()
223
+ group(3, "="); pregroup("ГЛАВНОЕ МЕНЮ (КОНСОЛЬ)", 3, "=")
224
+ pregroup("1 - Таблица истинности", 3, " ")
225
+ pregroup("2 - Системы счисления", 3, " ")
226
+ pregroup("3 - Умножение битовым сдвигом", 3, " ")
227
+ pregroup("0 - Выход", 3, " ")
228
+ group(3, "=")
229
+
230
+ choice = input("Ваш выбор: ")
231
+ if choice == "1": cli_truth_table()
232
+ elif choice == "2":
233
+ clear()
234
+ try:
235
+ inp = input("Введите число и его базу через пробел: ").split()
236
+ num, base = inp[0], int(inp[1])
237
+ to_base = int(input("В какую базу перевести? "))
238
+ print(f"Результат: {converter.base_to_base(num, base, to_base)}")
239
+ warning("Успешно!", 1)
240
+ except: warning("Ошибка ввода!", 1)
241
+ elif choice == "3":
242
+ clear()
243
+ try:
244
+ a, b = int(input("Первое число: ")), int(input("Второе число: "))
245
+ res, steps = bitwise_multiply(a, b)
246
+ for step in steps: print(step); sleep(0.05)
247
+ print(f"\nОТВЕТ: {res}")
248
+ warning("Успешно!", 1)
249
+ except: warning("Ошибка ввода!", 1)
250
+ elif choice == "0": break
251
+
252
+
253
+ # ==========================================
254
+ # 5. ГРАФИЧЕСКИЙ ИНТЕРФЕЙС (GUI - Tkinter)
255
+ # ==========================================
256
+ def launch_app_gui():
257
+ """Запускает программу в режиме оконного приложения (Tkinter)"""
258
+ root = tk.Tk()
259
+ root.title("Miller Tools")
260
+ root.geometry("400x350")
261
+ root.configure(bg="#2b2b2b")
262
+
263
+ def gui_base_converter():
264
+ num = simpledialog.askstring("Ввод", "Введите число:", parent=root)
265
+ if not num: return
266
+ base = simpledialog.askinteger("Ввод", "Система счисления числа:", parent=root)
267
+ to_base = simpledialog.askinteger("Ввод", "В какую систему перевести:", parent=root)
268
+ try:
269
+ res = converter.base_to_base(num, base, to_base)
270
+ messagebox.showinfo("Результат", f"{num} (база {base}) = {res} (база {to_base})")
271
+ except: messagebox.showerror("Ошибка", "Проверьте правильность ввода!")
272
+
273
+ def gui_bitwise():
274
+ a = simpledialog.askinteger("Ввод", "Первое число:", parent=root)
275
+ if a is None: return
276
+ b = simpledialog.askinteger("Ввод", "Второе число:", parent=root)
277
+ if b is None: return
278
+ res, steps = bitwise_multiply(a, b)
279
+ messagebox.showinfo("Результат", f"{a} * {b} = {res}\n\n" + "\n".join(steps))
280
+
281
+ def gui_truth_table():
282
+ raw = simpledialog.askstring("Ввод", "Введите выражение (например: A * B + C):", parent=root)
283
+ if not raw: return
284
+ raw = raw.replace("(", " ( ").replace(")", " ) ")
285
+ a = [SYMB.get(t, t) for t in raw.split()]
286
+ params, lettersin = [], []
287
+ for i in english_alphabet:
288
+ if i in a: params.append([i, 0]); lettersin.append(i)
289
+
290
+ if not params:
291
+ messagebox.showerror("Ошибка", "Нет переменных!")
292
+ return
293
+
294
+ try:
295
+ steps_example = calculate(a, params)
296
+ step_names = [prettify(name) for name, _ in steps_example]
297
+ columns = lettersin + step_names
298
+ results = [[] for _ in range(len(columns))]
299
+ end = False
300
+ while not end:
301
+ for i in range(len(params) - 1, 0, -1):
302
+ if params[i][1] == 2: params[i][1] = 0; params[i - 1][1] += 1
303
+ if params[0][1] == 2: end = True
304
+ else:
305
+ for i in range(len(params)): results[i].append(params[i][1])
306
+ steps = calculate(a, params)
307
+ for j in range(len(steps)): results[len(lettersin) + j].append(int(steps[j][1]))
308
+ params[-1][1] += 1
309
+
310
+ rows = list(zip(*results))
311
+ table_text = custom_tabulate(columns, rows)
312
+
313
+ # Открываем новое окно для таблицы
314
+ top = tk.Toplevel(root)
315
+ top.title("Таблица истинности")
316
+ txt = tk.Text(top, font=("Courier New", 10), wrap="none", bg="#1e1e1e", fg="#00ff00")
317
+ txt.insert("1.0", table_text)
318
+ txt.pack(expand=True, fill="both")
319
+ except Exception as e:
320
+ messagebox.showerror("Ошибка", str(e))
321
+
322
+ tk.Label(root, text="Набор утилит", font=("Courier New", 18, "bold"), bg="#2b2b2b", fg="white").pack(pady=15)
323
+ btn_style = {"font": ("Courier New", 11), "bg": "#4CAF50", "fg": "white", "width": 30, "pady": 5}
324
+
325
+ tk.Button(root, text="1. Таблица истинности", command=gui_truth_table, **btn_style).pack(pady=5)
326
+ tk.Button(root, text="2. Системы счисления", command=gui_base_converter, **btn_style).pack(pady=5)
327
+ tk.Button(root, text="3. Умножение сдвигом", command=gui_bitwise, **btn_style).pack(pady=5)
328
+
329
+ tk.Button(root, text="Выход", command=root.destroy, font=("Courier New", 11), bg="#d32f2f", fg="white", width=30).pack(pady=15)
330
+
331
+ root.mainloop()
@@ -0,0 +1,22 @@
1
+ Metadata-Version: 2.4
2
+ Name: millerlib
3
+ Version: 1.0.1
4
+ Summary: Набор CLI и GUI утилит: таблицы истинности, системы счисления, битовые сдвиги
5
+ Author: Твое Имя/Никнейм
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.6
10
+ Description-Content-Type: text/markdown
11
+ Dynamic: author
12
+ Dynamic: classifier
13
+ Dynamic: description
14
+ Dynamic: description-content-type
15
+ Dynamic: requires-python
16
+ Dynamic: summary
17
+
18
+ Запустить приложение:
19
+
20
+ launch_app_ui() - запуск CLI программы
21
+
22
+ launch_app_gui() - запуск GUI программы
@@ -0,0 +1,7 @@
1
+ README.md
2
+ setup.py
3
+ millerlib/__init__.py
4
+ millerlib.egg-info/PKG-INFO
5
+ millerlib.egg-info/SOURCES.txt
6
+ millerlib.egg-info/dependency_links.txt
7
+ millerlib.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ millerlib
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,17 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="millerlib", # Имя пакета для pip install (используй дефис вместо подчеркивания)
5
+ version="1.0.1",
6
+ author="Твое Имя/Никнейм",
7
+ description="Набор CLI и GUI утилит: таблицы истинности, системы счисления, битовые сдвиги",
8
+ long_description=open("README.md", encoding="utf-8").read(),
9
+ long_description_content_type="text/markdown",
10
+ packages=find_packages(),
11
+ classifiers=[
12
+ "Programming Language :: Python :: 3",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Operating System :: OS Independent",
15
+ ],
16
+ python_requires=">=3.6",
17
+ )