Compare commits

..

3 Commits

Author SHA1 Message Date
Rhinemann ec152c5758 Some refactoring. 2023-09-27 23:02:49 +03:00
dymik739 e2ebe2d095 change labels for memory inputs 2023-08-01 16:10:25 +03:00
dymik739 5e5f76deee extend main.py interface to support chained commands 2023-07-30 17:15:19 +03:00
18 changed files with 21 additions and 7986 deletions

519
README.md
View File

@ -1,520 +1,3 @@
# binaryCalculatorPrototype
This is a Python language prototype for a binary calculator to be used in Computer Arithmetics lab works for first-year students studying Computer Engineering at KPI.
# English
## Requirements
The user must have installed:
- python 3 (for the calculator itself);
## Installation
### Cloning the repository
To install the experimental version of the calculator just clone the repository locally:
```
git clone -b master http://139.162.162.130:3000/Rhinemann/binaryCalculatorPrototype.git
```
### Stable packages
To install a stable release of the calculator download the archive from [releases](http://139.162.162.130:3000/Rhinemann/binaryCalculatorPrototype/releases) page and decompress it in a directory of your choice.
## User instructions
Start the calculator using the following command:
```
python3 main.py
```
After that you must input the binary number as your first and second operands, as such:
```
Enter first operand: 110101
Enter second operand: 110
```
Note that you can't input any digit other than 0 or 1 into the operands:
```
Enter first operand: 234123
[ERROR] The first operand may contain only 1-s and 0-s!
Enter first operand: 12314
[ERROR] The first operand may contain only 1-s and 0-s!
Enter first operand: 1234123
[ERROR] The first operand may contain only 1-s and 0-s!
```
After inputting the operands properly, you will be presented with such prompt:
```
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) >
```
`(110101 000110)` are the operands you have input.
You may now choose the operations performed on the operands as such:
```
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > a
Sum: 111011
Carry: 0
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > s
Subtraction: 101111
Carry: 1
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > m
Choose method to use (1-4):
(110101 000110) m > 1
Multiplication (method 1):
+------+--------+--------+--------+-----+----------------------+
| iter | RG1 | RG2 | RG3 | CT | MicroOperations |
+------+--------+--------+--------+-----+----------------------+
| 0 | 000000 | 110101 | 000110 | 110 | - |
+------+--------+--------+--------+-----+----------------------+
| 1 | 000110 | 110101 | 000110 | 110 | RG1 := RG1 + RG3 |
| 1 | 000011 | 011010 | 000110 | 101 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 2 | 000001 | 101101 | 000110 | 100 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 3 | 000111 | 101101 | 000110 | 100 | RG1 := RG1 + RG3 |
| 3 | 000011 | 110110 | 000110 | 011 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 4 | 000001 | 111011 | 000110 | 010 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 5 | 000111 | 111011 | 000110 | 010 | RG1 := RG1 + RG3 |
| 5 | 000011 | 111101 | 000110 | 001 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 6 | 001001 | 111101 | 000110 | 001 | RG1 := RG1 + RG3 |
| 6 | 000100 | 111110 | 000110 | 000 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
Result: 000100111110
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > d
Choose method to use (1-2):
(110101 000110) d > 1
Division (method 1):
+------+---------+----------+----------+-----------------------+
| iter | RG3 | RG2 | RG1 | MicroOperations |
+------+---------+----------+----------+-----------------------+
| 0 | 1111111 | 00110101 | 00000110 | - |
+------+---------+----------+----------+-----------------------+
| 1 | 1111111 | 00101111 | 00000110 | RG2 := RG2 - RG1 |
| 1 | 1111111 | 01011110 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 2 | 1111111 | 01011000 | 00000110 | RG2 := RG2 - RG1 |
| 2 | 1111111 | 10110000 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 3 | 1111111 | 10110110 | 00000110 | RG2 := RG2 + RG1 |
| 3 | 1111110 | 01101100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 4 | 1111110 | 01100110 | 00000110 | RG2 := RG2 - RG1 |
| 4 | 1111101 | 11001100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 5 | 1111101 | 11010010 | 00000110 | RG2 := RG2 + RG1 |
| 5 | 1111010 | 10100100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 6 | 1111010 | 10101010 | 00000110 | RG2 := RG2 + RG1 |
| 6 | 1110100 | 01010100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 7 | 1110100 | 01001110 | 00000110 | RG2 := RG2 - RG1 |
| 7 | 1101001 | 10011100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 8 | 1101001 | 10100010 | 00000110 | RG2 := RG2 + RG1 |
| 8 | 1010010 | 01000100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 9 | 1010010 | 00111110 | 00000110 | RG2 := RG2 - RG1 |
| 9 | 0100101 | 01111100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
Result: 100101
```
The results of the operations will be displayed, and you will get prompted for the next operation to perform.
**Note** the results of previous operations don't impact the operands, therefore you can't plug your previous results into the calculator without restarting the program!
Also, as a quality of life feature, you can chain multiple operations in one prompt as such:
```
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > asm1d1
Sum: 111011
Carry: 0
Subtraction: 101111
Carry: 1
Multiplication (method 1):
+------+--------+--------+--------+-----+----------------------+
| iter | RG1 | RG2 | RG3 | CT | MicroOperations |
+------+--------+--------+--------+-----+----------------------+
| 0 | 000000 | 110101 | 000110 | 110 | - |
+------+--------+--------+--------+-----+----------------------+
| 1 | 000110 | 110101 | 000110 | 110 | RG1 := RG1 + RG3 |
| 1 | 000011 | 011010 | 000110 | 101 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 2 | 000001 | 101101 | 000110 | 100 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 3 | 000111 | 101101 | 000110 | 100 | RG1 := RG1 + RG3 |
| 3 | 000011 | 110110 | 000110 | 011 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 4 | 000001 | 111011 | 000110 | 010 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 5 | 000111 | 111011 | 000110 | 010 | RG1 := RG1 + RG3 |
| 5 | 000011 | 111101 | 000110 | 001 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 6 | 001001 | 111101 | 000110 | 001 | RG1 := RG1 + RG3 |
| 6 | 000100 | 111110 | 000110 | 000 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
Result: 000100111110
Division (method 1):
+------+---------+----------+----------+-----------------------+
| iter | RG3 | RG2 | RG1 | MicroOperations |
+------+---------+----------+----------+-----------------------+
| 0 | 1111111 | 00110101 | 00000110 | - |
+------+---------+----------+----------+-----------------------+
| 1 | 1111111 | 00101111 | 00000110 | RG2 := RG2 - RG1 |
| 1 | 1111111 | 01011110 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 2 | 1111111 | 01011000 | 00000110 | RG2 := RG2 - RG1 |
| 2 | 1111111 | 10110000 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 3 | 1111111 | 10110110 | 00000110 | RG2 := RG2 + RG1 |
| 3 | 1111110 | 01101100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 4 | 1111110 | 01100110 | 00000110 | RG2 := RG2 - RG1 |
| 4 | 1111101 | 11001100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 5 | 1111101 | 11010010 | 00000110 | RG2 := RG2 + RG1 |
| 5 | 1111010 | 10100100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 6 | 1111010 | 10101010 | 00000110 | RG2 := RG2 + RG1 |
| 6 | 1110100 | 01010100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 7 | 1110100 | 01001110 | 00000110 | RG2 := RG2 - RG1 |
| 7 | 1101001 | 10011100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 8 | 1101001 | 10100010 | 00000110 | RG2 := RG2 + RG1 |
| 8 | 1010010 | 01000100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 9 | 1010010 | 00111110 | 00000110 | RG2 := RG2 - RG1 |
| 9 | 0100101 | 01111100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
Result: 100101
```
So that multiple operations are performed on the same operands without the need for multiple prompts.
# Українська
## Вимоги
Користувач мусить мати:
- python 3 (для роботи калькулятора);
## Завантаження
### Клонування репозиторію
Щоб встановити експериментальну версію калькулятора пропишіть цю команду, щоб клонувати репозиторій:
```
git clone -b master http://139.162.162.130:3000/Rhinemann/binaryCalculatorPrototype.git
```
### Стабільні версії
Щоб встановити стабільний реліз калькулятора завантажте архів зі сторінки [релізів](http://139.162.162.130:3000/Rhinemann/binaryCalculatorPrototype/releases) та розархівуйте в обраній директорії.
## Інструкція користувачам
Калькулятор запускається цією командою:
```
python3 main.py
```
Після цього користувач має ввести два операнди у двійковій системі, наприклад:
```
Enter first operand: 110101
Enter second operand: 110
```
Варто зауважити, що не можна ввести жодну цифру крім 0 чи 1 у значення операндів:
```
Enter first operand: 234123
[ERROR] The first operand may contain only 1-s and 0-s!
Enter first operand: 12314
[ERROR] The first operand may contain only 1-s and 0-s!
Enter first operand: 1234123
[ERROR] The first operand may contain only 1-s and 0-s!
```
Після коректного введення операндів користувач побачить такий запит:
```
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) >
```
`(110101 000110)` - це операнди введені користувачем.
Користувач тепер може обрати операції що виконуватимуться:
```
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > a
Sum: 111011
Carry: 0
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > s
Subtraction: 101111
Carry: 1
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > m
Choose method to use (1-4):
(110101 000110) m > 1
Multiplication (method 1):
+------+--------+--------+--------+-----+----------------------+
| iter | RG1 | RG2 | RG3 | CT | MicroOperations |
+------+--------+--------+--------+-----+----------------------+
| 0 | 000000 | 110101 | 000110 | 110 | - |
+------+--------+--------+--------+-----+----------------------+
| 1 | 000110 | 110101 | 000110 | 110 | RG1 := RG1 + RG3 |
| 1 | 000011 | 011010 | 000110 | 101 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 2 | 000001 | 101101 | 000110 | 100 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 3 | 000111 | 101101 | 000110 | 100 | RG1 := RG1 + RG3 |
| 3 | 000011 | 110110 | 000110 | 011 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 4 | 000001 | 111011 | 000110 | 010 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 5 | 000111 | 111011 | 000110 | 010 | RG1 := RG1 + RG3 |
| 5 | 000011 | 111101 | 000110 | 001 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 6 | 001001 | 111101 | 000110 | 001 | RG1 := RG1 + RG3 |
| 6 | 000100 | 111110 | 000110 | 000 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
Result: 000100111110
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > d
Choose method to use (1-2):
(110101 000110) d > 1
Division (method 1):
+------+---------+----------+----------+-----------------------+
| iter | RG3 | RG2 | RG1 | MicroOperations |
+------+---------+----------+----------+-----------------------+
| 0 | 1111111 | 00110101 | 00000110 | - |
+------+---------+----------+----------+-----------------------+
| 1 | 1111111 | 00101111 | 00000110 | RG2 := RG2 - RG1 |
| 1 | 1111111 | 01011110 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 2 | 1111111 | 01011000 | 00000110 | RG2 := RG2 - RG1 |
| 2 | 1111111 | 10110000 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 3 | 1111111 | 10110110 | 00000110 | RG2 := RG2 + RG1 |
| 3 | 1111110 | 01101100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 4 | 1111110 | 01100110 | 00000110 | RG2 := RG2 - RG1 |
| 4 | 1111101 | 11001100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 5 | 1111101 | 11010010 | 00000110 | RG2 := RG2 + RG1 |
| 5 | 1111010 | 10100100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 6 | 1111010 | 10101010 | 00000110 | RG2 := RG2 + RG1 |
| 6 | 1110100 | 01010100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 7 | 1110100 | 01001110 | 00000110 | RG2 := RG2 - RG1 |
| 7 | 1101001 | 10011100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 8 | 1101001 | 10100010 | 00000110 | RG2 := RG2 + RG1 |
| 8 | 1010010 | 01000100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 9 | 1010010 | 00111110 | 00000110 | RG2 := RG2 - RG1 |
| 9 | 0100101 | 01111100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
Result: 100101
```
Результати обчислень будуть виведені, а користувач отримає повторний запит операції.
**Увага** результати обчислень не змінюють операнди, тому їх неможливо використовувати у майбутніх обчисленнях без перезапуску програми!
Також, для зручності користувач може об'єднати декілька операцій у один запис:
```
Choose the operation:
[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [q]uit
(110101 000110) > asm1d1
Sum: 111011
Carry: 0
Subtraction: 101111
Carry: 1
Multiplication (method 1):
+------+--------+--------+--------+-----+----------------------+
| iter | RG1 | RG2 | RG3 | CT | MicroOperations |
+------+--------+--------+--------+-----+----------------------+
| 0 | 000000 | 110101 | 000110 | 110 | - |
+------+--------+--------+--------+-----+----------------------+
| 1 | 000110 | 110101 | 000110 | 110 | RG1 := RG1 + RG3 |
| 1 | 000011 | 011010 | 000110 | 101 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 2 | 000001 | 101101 | 000110 | 100 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 3 | 000111 | 101101 | 000110 | 100 | RG1 := RG1 + RG3 |
| 3 | 000011 | 110110 | 000110 | 011 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 4 | 000001 | 111011 | 000110 | 010 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 5 | 000111 | 111011 | 000110 | 010 | RG1 := RG1 + RG3 |
| 5 | 000011 | 111101 | 000110 | 001 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
| 6 | 001001 | 111101 | 000110 | 001 | RG1 := RG1 + RG3 |
| 6 | 000100 | 111110 | 000110 | 000 | RG2 := RG1[1].r(RG2) |
| | | | | | RG1 := 0.r(RG1) |
| | | | | | CT := CT - 1 |
+------+--------+--------+--------+-----+----------------------+
Result: 000100111110
Division (method 1):
+------+---------+----------+----------+-----------------------+
| iter | RG3 | RG2 | RG1 | MicroOperations |
+------+---------+----------+----------+-----------------------+
| 0 | 1111111 | 00110101 | 00000110 | - |
+------+---------+----------+----------+-----------------------+
| 1 | 1111111 | 00101111 | 00000110 | RG2 := RG2 - RG1 |
| 1 | 1111111 | 01011110 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 2 | 1111111 | 01011000 | 00000110 | RG2 := RG2 - RG1 |
| 2 | 1111111 | 10110000 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 3 | 1111111 | 10110110 | 00000110 | RG2 := RG2 + RG1 |
| 3 | 1111110 | 01101100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 4 | 1111110 | 01100110 | 00000110 | RG2 := RG2 - RG1 |
| 4 | 1111101 | 11001100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 5 | 1111101 | 11010010 | 00000110 | RG2 := RG2 + RG1 |
| 5 | 1111010 | 10100100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 6 | 1111010 | 10101010 | 00000110 | RG2 := RG2 + RG1 |
| 6 | 1110100 | 01010100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 7 | 1110100 | 01001110 | 00000110 | RG2 := RG2 - RG1 |
| 7 | 1101001 | 10011100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 8 | 1101001 | 10100010 | 00000110 | RG2 := RG2 + RG1 |
| 8 | 1010010 | 01000100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
| 9 | 1010010 | 00111110 | 00000110 | RG2 := RG2 - RG1 |
| 9 | 0100101 | 01111100 | 00000110 | RG3 := l(RG3).!RG2[8] |
| | | | | RG2 := l(RG2).0 |
+------+---------+----------+----------+-----------------------+
Result: 100101
```
Таким чином обчислення послідовно над операндами без потреби у декількох запитах.
This is a Python language prototype for a binary calculator to be used in Computer Arithmetics lab works for first-year students studying Computer Engineering at KPI.

View File

@ -1,3 +1,4 @@
import copy
from collections import deque
from typing_extensions import Self
@ -100,18 +101,6 @@ class Counter(BasicRegister):
return any(self.memory)
def negated(memory: deque[bool]) -> deque[bool]:
"""
Returns negated memory chunk.
:param deque[bool] memory: Memory chunk to be negated.
:return: Negated memory chunk.
:rtype: deque[bool]
"""
return deque([not value for value in memory])
def get_memory(variable_name: str) -> deque[bool]:
"""
Reads user input to be used as a memory array.
@ -247,12 +236,12 @@ def binary_multiplication_method_1(first_term: BasicRegister, second_term: Basic
:return: Register containing the product.
:rtype: BasicRegister
"""
first_term, second_term = align_registers(first_term, second_term)
n: int = len(first_term)
rg1 = BasicRegister(deque([False] * n))
rg2 = BasicRegister(first_term.memory)
rg3 = BasicRegister(second_term.memory)
rg2 = copy.copy(first_term)
rg3 = copy.copy(second_term)
ct = Counter(n)
data_table = [["iter", "RG1", "RG2", "RG3", "CT", "MicroOperations"]]
@ -289,11 +278,11 @@ def binary_multiplication_method_2(first_term: BasicRegister, second_term: Basic
:return: Register containing the product.
:rtype: BasicRegister
"""
first_term, second_term = align_registers(first_term, second_term)
n: int = len(first_term)
rg1 = BasicRegister(deque([False] * (2*n)))
rg2 = BasicRegister(first_term.memory)
rg2 = copy.copy(first_term)
rg3 = BasicRegister(deque([False] * n + list(second_term.memory)))
i = 0
@ -328,7 +317,7 @@ def binary_multiplication_method_3(first_term: BasicRegister, second_term: Basic
:return: Register containing the product.
:rtype: BasicRegister
"""
first_term, second_term = align_registers(first_term, second_term)
n: int = len(first_term)
data_table = [["iter", "RG2", "RG1", "RG3", "CT", "MicroOperations"]]
@ -372,11 +361,11 @@ def binary_multiplication_method_4(first_term: BasicRegister, second_term: Basic
:return: Register containing the product.
:rtype: BasicRegister
"""
first_term, second_term = align_registers(first_term, second_term)
n: int = len(first_term)
rg1 = BasicRegister(deque([False] * (2*n+1)))
rg2 = BasicRegister(first_term.memory)
rg2 = copy.copy(first_term)
rg3 = BasicRegister(deque([False]) + second_term.memory + deque([False] * n))
data_table = [["iter", "RG1", "RG2", "RG3", "MicroOperations"]]
@ -400,6 +389,7 @@ def binary_multiplication_method_4(first_term: BasicRegister, second_term: Basic
return BasicRegister(deque(list(rg1.memory)[:-1])), data_table
def binary_division_method_1(first_term: BasicRegister, second_term: BasicRegister) \
-> tuple[BasicRegister, list[list[str]]]:
"""
@ -412,7 +402,6 @@ def binary_division_method_1(first_term: BasicRegister, second_term: BasicRegist
:rtype: BasicRegister
"""
first_term, second_term = align_registers(first_term, second_term)
n: int = len(first_term)
rg1 = BasicRegister(deque([False, False]) + second_term.memory)
@ -442,6 +431,7 @@ def binary_division_method_1(first_term: BasicRegister, second_term: BasicRegist
return BasicRegister(deque(list(rg3.memory)[1:])), data_table
def binary_division_method_2(first_term: BasicRegister, second_term: BasicRegister) \
-> tuple[BasicRegister, list[list[str]]]:
"""
@ -454,7 +444,6 @@ def binary_division_method_2(first_term: BasicRegister, second_term: BasicRegist
:rtype: BasicRegister
"""
first_term, second_term = align_registers(first_term, second_term)
n: int = len(first_term)
rg1 = BasicRegister(deque([False]) + second_term.memory + deque([False]*n))
@ -484,68 +473,3 @@ def binary_division_method_2(first_term: BasicRegister, second_term: BasicRegist
data_table[-1].append(list(map(str, [i, rg3, rg2, rg1, f"RG3 := l(RG3).SM[p]\nRG1 := 0.r(RG1)"])))
return BasicRegister(deque(list(rg3.memory)[1:])), data_table
def binary_square_root(first_term: BasicRegister) \
-> tuple[BasicRegister, list[list[str]]]:
"""
Extracts the square root of first term.
:param: BasicRegister first_term: Register for square root extraction.
:return: Register containing the division result and the state table of a virtual
device that extracted the square root of the given term.
:rtype: tuple[BasicRegister, list[list[str]]]
"""
n: int = len(first_term)
i = 0
rga = BasicRegister(deque([False]*n))
rgb = BasicRegister(deque([False]*(n+2)))
rgc = BasicRegister(first_term.memory)
ct = Counter(n)
data_table = [["iter", "RGA", "RGB", "RGC", "CT", "MicroOperations"]]
data_table.append([])
data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "-"])))
# two initial shifts
rgb.left_shift(rgc.memory[0])
rgc.left_shift()
data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := l(RGB).RGC[0]\nRGC := l(RGC).0"])))
rgb.left_shift(rgc.memory[0])
rgc.left_shift()
data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := l(RGB).RGC[0]\nRGC := l(RGC).0"])))
# initial inverted addition
rgb = binary_sum(rgb, BasicRegister(negated(rga.memory) + deque([True, True])))
data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := RGB + !(RGA).11"])))
while ct.non_zero():
data_table.append([])
i += 1
rga.left_shift(not rgb.memory[0])
rgb.left_shift(rgc.memory[0])
rgc.left_shift()
data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGA := l(RGA).!(RGB[0])\nRGB := l(RGB).RGC[0]\nRGC := l(RGC).0"])))
rgb.left_shift(rgc.memory[0])
rgc.left_shift()
data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := l(RGB).RGC[0]\nRGC := l(RGC).0"])))
if rgb.memory[0]:
rgb = binary_sum(rgb, BasicRegister(rga.memory + deque([True, True])))
data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := RGB + RGA.11"])))
else:
rgb = binary_sum(rgb, BasicRegister(negated(rga.memory) + deque([True, True])))
data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "RGB := RGB + !(RGA).11"])))
ct.decrement()
data_table[-1].append(list(map(str, [i, rga, rgb, rgc, ct, "CT := CT - 1"])))
return rga, data_table

View File

@ -45,7 +45,7 @@ from html import escape
from html.parser import HTMLParser
from typing import Any
from lib import wcwidth
import wcwidth # type: ignore
# hrule styles
FRAME = 0
@ -1511,28 +1511,6 @@ class PrettyTable:
def copy(self):
return copy.deepcopy(self)
def get_formatted_string(self, out_format: str = "text", **kwargs) -> str:
"""Return string representation of specified format of table in current state.
Arguments:
out_format - resulting table format
kwargs - passed through to function that performs formatting
"""
if out_format == "text":
return self.get_string(**kwargs)
if out_format == "html":
return self.get_html_string(**kwargs)
if out_format == "json":
return self.get_json_string(**kwargs)
if out_format == "csv":
return self.get_csv_string(**kwargs)
if out_format == "latex":
return self.get_latex_string(**kwargs)
raise ValueError(
f"Invalid format {out_format}. "
"Must be one of: text, html, json, csv, or latex"
)
##############################
# MISC PRIVATE METHODS #
##############################
@ -2139,16 +2117,14 @@ class PrettyTable:
open_tag = ["<table"]
if options["attributes"]:
for attr_name in options["attributes"]:
open_tag.append(
f' {escape(attr_name)}="{escape(options["attributes"][attr_name])}"'
)
open_tag.append(f' {attr_name}="{options["attributes"][attr_name]}"')
open_tag.append(">")
lines.append("".join(open_tag))
# Title
title = options["title"] or self._title
if title:
lines.append(f" <caption>{escape(title)}</caption>")
lines.append(f" <caption>{title}</caption>")
# Headers
if options["header"]:
@ -2209,16 +2185,14 @@ class PrettyTable:
open_tag.append(' rules="cols"')
if options["attributes"]:
for attr_name in options["attributes"]:
open_tag.append(
f' {escape(attr_name)}="{escape(options["attributes"][attr_name])}"'
)
open_tag.append(f' {attr_name}="{options["attributes"][attr_name]}"')
open_tag.append(">")
lines.append("".join(open_tag))
# Title
title = options["title"] or self._title
if title:
lines.append(f" <caption>{escape(title)}</caption>")
lines.append(f" <caption>{title}</caption>")
# Headers
if options["header"]:

View File

@ -1 +0,0 @@
pip

View File

@ -1,27 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 Jeff Quast <contact@jeffquast.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Markus Kuhn -- 2007-05-26 (Unicode 5.0)
Permission to use, copy, modify, and distribute this software
for any purpose and without fee is hereby granted. The author
disclaims all warranties with regard to this software.

View File

@ -1,410 +0,0 @@
Metadata-Version: 2.1
Name: wcwidth
Version: 0.2.13
Summary: Measures the displayed width of unicode strings in a terminal
Home-page: https://github.com/jquast/wcwidth
Author: Jeff Quast
Author-email: contact@jeffquast.com
License: MIT
Keywords: cjk,combining,console,eastasian,emoji,emulator,terminal,unicode,wcswidth,wcwidth,xterm
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Localization
Classifier: Topic :: Software Development :: Internationalization
Classifier: Topic :: Terminals
License-File: LICENSE
Requires-Dist: backports.functools-lru-cache >=1.2.1 ; python_version < "3.2"
|pypi_downloads| |codecov| |license|
============
Introduction
============
This library is mainly for CLI programs that carefully produce output for
Terminals, or make pretend to be an emulator.
**Problem Statement**: The printable length of *most* strings are equal to the
number of cells they occupy on the screen ``1 character : 1 cell``. However,
there are categories of characters that *occupy 2 cells* (full-wide), and
others that *occupy 0* cells (zero-width).
**Solution**: POSIX.1-2001 and POSIX.1-2008 conforming systems provide
`wcwidth(3)`_ and `wcswidth(3)`_ C functions of which this python module's
functions precisely copy. *These functions return the number of cells a
unicode string is expected to occupy.*
Installation
------------
The stable version of this package is maintained on pypi, install using pip::
pip install wcwidth
Example
-------
**Problem**: given the following phrase (Japanese),
>>> text = u'コンニチハ'
Python **incorrectly** uses the *string length* of 5 codepoints rather than the
*printable length* of 10 cells, so that when using the `rjust` function, the
output length is wrong::
>>> print(len('コンニチハ'))
5
>>> print('コンニチハ'.rjust(20, '_'))
_______________コンニチハ
By defining our own "rjust" function that uses wcwidth, we can correct this::
>>> def wc_rjust(text, length, padding=' '):
... from wcwidth import wcswidth
... return padding * max(0, (length - wcswidth(text))) + text
...
Our **Solution** uses wcswidth to determine the string length correctly::
>>> from wcwidth import wcswidth
>>> print(wcswidth('コンニチハ'))
10
>>> print(wc_rjust('コンニチハ', 20, '_'))
__________コンニチハ
Choosing a Version
------------------
Export an environment variable, ``UNICODE_VERSION``. This should be done by
*terminal emulators* or those developers experimenting with authoring one of
their own, from shell::
$ export UNICODE_VERSION=13.0
If unspecified, the latest version is used. If your Terminal Emulator does not
export this variable, you can use the `jquast/ucs-detect`_ utility to
automatically detect and export it to your shell.
wcwidth, wcswidth
-----------------
Use function ``wcwidth()`` to determine the length of a *single unicode
character*, and ``wcswidth()`` to determine the length of many, a *string
of unicode characters*.
Briefly, return values of function ``wcwidth()`` are:
``-1``
Indeterminate (not printable).
``0``
Does not advance the cursor, such as NULL or Combining.
``2``
Characters of category East Asian Wide (W) or East Asian
Full-width (F) which are displayed using two terminal cells.
``1``
All others.
Function ``wcswidth()`` simply returns the sum of all values for each character
along a string, or ``-1`` when it occurs anywhere along a string.
Full API Documentation at https://wcwidth.readthedocs.org
==========
Developing
==========
Install wcwidth in editable mode::
pip install -e .
Execute unit tests using tox_::
tox -e py27,py35,py36,py37,py38,py39,py310,py311,py312
Updating Unicode Version
------------------------
Regenerate python code tables from latest Unicode Specification data files::
tox -e update
The script is located at ``bin/update-tables.py``, requires Python 3.9 or
later. It is recommended but not necessary to run this script with the newest
Python, because the newest Python has the latest ``unicodedata`` for generating
comments.
Building Documentation
----------------------
This project is using `sphinx`_ 4.5 to build documentation::
tox -e sphinx
The output will be in ``docs/_build/html/``.
Updating Requirements
---------------------
This project is using `pip-tools`_ to manage requirements.
To upgrade requirements for updating unicode version, run::
tox -e update_requirements_update
To upgrade requirements for testing, run::
tox -e update_requirements37,update_requirements39
To upgrade requirements for building documentation, run::
tox -e update_requirements_docs
Utilities
---------
Supplementary tools for browsing and testing terminals for wide unicode
characters are found in the `bin/`_ of this project's source code. Just ensure
to first ``pip install -r requirements-develop.txt`` from this projects main
folder. For example, an interactive browser for testing::
python ./bin/wcwidth-browser.py
====
Uses
====
This library is used in:
- `jquast/blessed`_: a thin, practical wrapper around terminal capabilities in
Python.
- `prompt-toolkit/python-prompt-toolkit`_: a Library for building powerful
interactive command lines in Python.
- `dbcli/pgcli`_: Postgres CLI with autocompletion and syntax highlighting.
- `thomasballinger/curtsies`_: a Curses-like terminal wrapper with a display
based on compositing 2d arrays of text.
- `selectel/pyte`_: Simple VTXXX-compatible linux terminal emulator.
- `astanin/python-tabulate`_: Pretty-print tabular data in Python, a library
and a command-line utility.
- `rspeer/python-ftfy`_: Fixes mojibake and other glitches in Unicode
text.
- `nbedos/termtosvg`_: Terminal recorder that renders sessions as SVG
animations.
- `peterbrittain/asciimatics`_: Package to help people create full-screen text
UIs.
- `python-cmd2/cmd2`_: A tool for building interactive command line apps
- `stratis-storage/stratis-cli`_: CLI for the Stratis project
- `ihabunek/toot`_: A Mastodon CLI/TUI client
- `saulpw/visidata`_: Terminal spreadsheet multitool for discovering and
arranging data
===============
Other Languages
===============
- `timoxley/wcwidth`_: JavaScript
- `janlelis/unicode-display_width`_: Ruby
- `alecrabbit/php-wcwidth`_: PHP
- `Text::CharWidth`_: Perl
- `bluebear94/Terminal-WCWidth`_: Perl 6
- `mattn/go-runewidth`_: Go
- `grepsuzette/wcwidth`_: Haxe
- `aperezdc/lua-wcwidth`_: Lua
- `joachimschmidt557/zig-wcwidth`_: Zig
- `fumiyas/wcwidth-cjk`_: `LD_PRELOAD` override
- `joshuarubin/wcwidth9`_: Unicode version 9 in C
=======
History
=======
0.2.13 *2024-01-06*
* **Bugfix** zero-width support for Hangul Jamo (Korean)
0.2.12 *2023-11-21*
* re-release to remove .pyi file misplaced in wheel files `Issue #101`_.
0.2.11 *2023-11-20*
* Include tests files in the source distribution (`PR #98`_, `PR #100`_).
0.2.10 *2023-11-13*
* **Bugfix** accounting of some kinds of emoji sequences using U+FE0F
Variation Selector 16 (`PR #97`_).
* **Updated** `Specification <Specification_from_pypi_>`_.
0.2.9 *2023-10-30*
* **Bugfix** zero-width characters used in Emoji ZWJ sequences, Balinese,
Jamo, Devanagari, Tamil, Kannada and others (`PR #91`_).
* **Updated** to include `Specification <Specification_from_pypi_>`_ of
character measurements.
0.2.8 *2023-09-30*
* Include requirements files in the source distribution (`PR #82`_).
0.2.7 *2023-09-28*
* **Updated** tables to include Unicode Specification 15.1.0.
* Include ``bin``, ``docs``, and ``tox.ini`` in the source distribution
0.2.6 *2023-01-14*
* **Updated** tables to include Unicode Specification 14.0.0 and 15.0.0.
* **Changed** developer tools to use pip-compile, and to use jinja2 templates
for code generation in `bin/update-tables.py` to prepare for possible
compiler optimization release.
0.2.1 .. 0.2.5 *2020-06-23*
* **Repository** changes to update tests and packaging issues, and
begin tagging repository with matching release versions.
0.2.0 *2020-06-01*
* **Enhancement**: Unicode version may be selected by exporting the
Environment variable ``UNICODE_VERSION``, such as ``13.0``, or ``6.3.0``.
See the `jquast/ucs-detect`_ CLI utility for automatic detection.
* **Enhancement**:
API Documentation is published to readthedocs.org.
* **Updated** tables for *all* Unicode Specifications with files
published in a programmatically consumable format, versions 4.1.0
through 13.0
0.1.9 *2020-03-22*
* **Performance** optimization by `Avram Lubkin`_, `PR #35`_.
* **Updated** tables to Unicode Specification 13.0.0.
0.1.8 *2020-01-01*
* **Updated** tables to Unicode Specification 12.0.0. (`PR #30`_).
0.1.7 *2016-07-01*
* **Updated** tables to Unicode Specification 9.0.0. (`PR #18`_).
0.1.6 *2016-01-08 Production/Stable*
* ``LICENSE`` file now included with distribution.
0.1.5 *2015-09-13 Alpha*
* **Bugfix**:
Resolution of "combining_ character width" issue, most especially
those that previously returned -1 now often (correctly) return 0.
resolved by `Philip Craig`_ via `PR #11`_.
* **Deprecated**:
The module path ``wcwidth.table_comb`` is no longer available,
it has been superseded by module path ``wcwidth.table_zero``.
0.1.4 *2014-11-20 Pre-Alpha*
* **Feature**: ``wcswidth()`` now determines printable length
for (most) combining_ characters. The developer's tool
`bin/wcwidth-browser.py`_ is improved to display combining_
characters when provided the ``--combining`` option
(`Thomas Ballinger`_ and `Leta Montopoli`_ `PR #5`_).
* **Feature**: added static analysis (prospector_) to testing
framework.
0.1.3 *2014-10-29 Pre-Alpha*
* **Bugfix**: 2nd parameter of wcswidth was not honored.
(`Thomas Ballinger`_, `PR #4`_).
0.1.2 *2014-10-28 Pre-Alpha*
* **Updated** tables to Unicode Specification 7.0.0.
(`Thomas Ballinger`_, `PR #3`_).
0.1.1 *2014-05-14 Pre-Alpha*
* Initial release to pypi, Based on Unicode Specification 6.3.0
This code was originally derived directly from C code of the same name,
whose latest version is available at
https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c::
* Markus Kuhn -- 2007-05-26 (Unicode 5.0)
*
* Permission to use, copy, modify, and distribute this software
* for any purpose and without fee is hereby granted. The author
* disclaims all warranties with regard to this software.
.. _`Specification_from_pypi`: https://wcwidth.readthedocs.io/en/latest/specs.html
.. _`tox`: https://tox.wiki/en/latest/
.. _`prospector`: https://github.com/landscapeio/prospector
.. _`combining`: https://en.wikipedia.org/wiki/Combining_character
.. _`bin/`: https://github.com/jquast/wcwidth/tree/master/bin
.. _`bin/wcwidth-browser.py`: https://github.com/jquast/wcwidth/blob/master/bin/wcwidth-browser.py
.. _`Thomas Ballinger`: https://github.com/thomasballinger
.. _`Leta Montopoli`: https://github.com/lmontopo
.. _`Philip Craig`: https://github.com/philipc
.. _`PR #3`: https://github.com/jquast/wcwidth/pull/3
.. _`PR #4`: https://github.com/jquast/wcwidth/pull/4
.. _`PR #5`: https://github.com/jquast/wcwidth/pull/5
.. _`PR #11`: https://github.com/jquast/wcwidth/pull/11
.. _`PR #18`: https://github.com/jquast/wcwidth/pull/18
.. _`PR #30`: https://github.com/jquast/wcwidth/pull/30
.. _`PR #35`: https://github.com/jquast/wcwidth/pull/35
.. _`PR #82`: https://github.com/jquast/wcwidth/pull/82
.. _`PR #91`: https://github.com/jquast/wcwidth/pull/91
.. _`PR #97`: https://github.com/jquast/wcwidth/pull/97
.. _`PR #98`: https://github.com/jquast/wcwidth/pull/98
.. _`PR #100`: https://github.com/jquast/wcwidth/pull/100
.. _`Issue #101`: https://github.com/jquast/wcwidth/issues/101
.. _`jquast/blessed`: https://github.com/jquast/blessed
.. _`selectel/pyte`: https://github.com/selectel/pyte
.. _`thomasballinger/curtsies`: https://github.com/thomasballinger/curtsies
.. _`dbcli/pgcli`: https://github.com/dbcli/pgcli
.. _`prompt-toolkit/python-prompt-toolkit`: https://github.com/prompt-toolkit/python-prompt-toolkit
.. _`timoxley/wcwidth`: https://github.com/timoxley/wcwidth
.. _`wcwidth(3)`: https://man7.org/linux/man-pages/man3/wcwidth.3.html
.. _`wcswidth(3)`: https://man7.org/linux/man-pages/man3/wcswidth.3.html
.. _`astanin/python-tabulate`: https://github.com/astanin/python-tabulate
.. _`janlelis/unicode-display_width`: https://github.com/janlelis/unicode-display_width
.. _`rspeer/python-ftfy`: https://github.com/rspeer/python-ftfy
.. _`alecrabbit/php-wcwidth`: https://github.com/alecrabbit/php-wcwidth
.. _`Text::CharWidth`: https://metacpan.org/pod/Text::CharWidth
.. _`bluebear94/Terminal-WCWidth`: https://github.com/bluebear94/Terminal-WCWidth
.. _`mattn/go-runewidth`: https://github.com/mattn/go-runewidth
.. _`grepsuzette/wcwidth`: https://github.com/grepsuzette/wcwidth
.. _`jquast/ucs-detect`: https://github.com/jquast/ucs-detect
.. _`Avram Lubkin`: https://github.com/avylove
.. _`nbedos/termtosvg`: https://github.com/nbedos/termtosvg
.. _`peterbrittain/asciimatics`: https://github.com/peterbrittain/asciimatics
.. _`aperezdc/lua-wcwidth`: https://github.com/aperezdc/lua-wcwidth
.. _`joachimschmidt557/zig-wcwidth`: https://github.com/joachimschmidt557/zig-wcwidth
.. _`fumiyas/wcwidth-cjk`: https://github.com/fumiyas/wcwidth-cjk
.. _`joshuarubin/wcwidth9`: https://github.com/joshuarubin/wcwidth9
.. _`python-cmd2/cmd2`: https://github.com/python-cmd2/cmd2
.. _`stratis-storage/stratis-cli`: https://github.com/stratis-storage/stratis-cli
.. _`ihabunek/toot`: https://github.com/ihabunek/toot
.. _`saulpw/visidata`: https://github.com/saulpw/visidata
.. _`pip-tools`: https://pip-tools.readthedocs.io/
.. _`sphinx`: https://www.sphinx-doc.org/
.. |pypi_downloads| image:: https://img.shields.io/pypi/dm/wcwidth.svg?logo=pypi
:alt: Downloads
:target: https://pypi.org/project/wcwidth/
.. |codecov| image:: https://codecov.io/gh/jquast/wcwidth/branch/master/graph/badge.svg
:alt: codecov.io Code Coverage
:target: https://app.codecov.io/gh/jquast/wcwidth/
.. |license| image:: https://img.shields.io/pypi/l/wcwidth.svg
:target: https://pypi.org/project/wcwidth/
:alt: MIT License

View File

@ -1,20 +0,0 @@
wcwidth-0.2.13.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
wcwidth-0.2.13.dist-info/LICENSE,sha256=cLmKlaIUTrcK-AF_qMbZXOJH5AhnQ26LxknhN_4T0ho,1322
wcwidth-0.2.13.dist-info/METADATA,sha256=wBs2ALubn0kTdhEFDXc1gZBU_zf4rlfNgv1YS02jzLQ,14992
wcwidth-0.2.13.dist-info/RECORD,,
wcwidth-0.2.13.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
wcwidth-0.2.13.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
wcwidth-0.2.13.dist-info/top_level.txt,sha256=LLjS8SFiXXuLEcD2BNdFdGhpKWe5opHtvn7KNj9AIRI,8
wcwidth-0.2.13.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
wcwidth/__init__.py,sha256=ecZx3UVoktZuAvatG6NetByVFgENkKl9htmk0ZasTmA,1076
wcwidth/__pycache__/__init__.cpython-311.pyc,,
wcwidth/__pycache__/table_vs16.cpython-311.pyc,,
wcwidth/__pycache__/table_wide.cpython-311.pyc,,
wcwidth/__pycache__/table_zero.cpython-311.pyc,,
wcwidth/__pycache__/unicode_versions.cpython-311.pyc,,
wcwidth/__pycache__/wcwidth.cpython-311.pyc,,
wcwidth/table_vs16.py,sha256=hPbuoFxmxrGfuBaeoheMTAGmgB2a4EudhxYsYokLf6o,6857
wcwidth/table_wide.py,sha256=vUHjEOuRw1WGyUcIw2L9GymZsYvC2I3dc858mlYyTYM,100896
wcwidth/table_zero.py,sha256=4ZeihLZDH8obgrwA6ct-vu2lxc4t_DsfyiB9p9Ovxbo,359450
wcwidth/unicode_versions.py,sha256=7nShgeRYrvZFkGpREdr-PkUeXnuM-WxeOmGYj6QNaaE,851
wcwidth/wcwidth.py,sha256=TLzyH1ahdEDDPOIMcqVO4U0gyKwSyZdzAsSgEPuVFGY,14512

View File

@ -1,6 +0,0 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.41.2)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

View File

@ -1 +0,0 @@
wcwidth

View File

@ -1 +0,0 @@

View File

@ -1,29 +0,0 @@
"""
Wcwidth module.
https://github.com/jquast/wcwidth
"""
# re-export all functions & definitions, even private ones, from top-level
# module path, to allow for 'from wcwidth import _private_func'. Of course,
# user beware that any _private function may disappear or change signature at
# any future version.
# local
from .wcwidth import ZERO_WIDTH # noqa
from .wcwidth import (WIDE_EASTASIAN,
VS16_NARROW_TO_WIDE,
wcwidth,
wcswidth,
_bisearch,
list_versions,
_wcmatch_version,
_wcversion_value)
# The __all__ attribute defines the items exported from statement,
# 'from wcwidth import *', but also to say, "This is the public API".
__all__ = ('wcwidth', 'wcswidth', 'list_versions')
# We also used pkg_resources to load unicode version tables from version.json,
# generated by bin/update-tables.py, but some environments are unable to
# import pkg_resources for one reason or another, yikes!
__version__ = '0.2.13'

View File

@ -1,125 +0,0 @@
"""
Exports VS16_NARROW_TO_WIDE table keyed by supporting unicode version level.
This code generated by wcwidth/bin/update-tables.py on 2023-11-07 16:43:49 UTC.
"""
VS16_NARROW_TO_WIDE = {
'9.0.0': (
# Source: 9.0.0
# Date: 2023-02-01, 02:22:54 GMT
#
(0x00023, 0x00023,), # Number Sign
(0x0002a, 0x0002a,), # Asterisk
(0x00030, 0x00039,), # Digit Zero ..Digit Nine
(0x000a9, 0x000a9,), # Copyright Sign
(0x000ae, 0x000ae,), # Registered Sign
(0x0203c, 0x0203c,), # Double Exclamation Mark
(0x02049, 0x02049,), # Exclamation Question Mark
(0x02122, 0x02122,), # Trade Mark Sign
(0x02139, 0x02139,), # Information Source
(0x02194, 0x02199,), # Left Right Arrow ..South West Arrow
(0x021a9, 0x021aa,), # Leftwards Arrow With Hoo..Rightwards Arrow With Ho
(0x02328, 0x02328,), # Keyboard
(0x023cf, 0x023cf,), # Eject Symbol
(0x023ed, 0x023ef,), # Black Right-pointing Dou..Black Right-pointing Tri
(0x023f1, 0x023f2,), # Stopwatch ..Timer Clock
(0x023f8, 0x023fa,), # Double Vertical Bar ..Black Circle For Record
(0x024c2, 0x024c2,), # Circled Latin Capital Letter M
(0x025aa, 0x025ab,), # Black Small Square ..White Small Square
(0x025b6, 0x025b6,), # Black Right-pointing Triangle
(0x025c0, 0x025c0,), # Black Left-pointing Triangle
(0x025fb, 0x025fc,), # White Medium Square ..Black Medium Square
(0x02600, 0x02604,), # Black Sun With Rays ..Comet
(0x0260e, 0x0260e,), # Black Telephone
(0x02611, 0x02611,), # Ballot Box With Check
(0x02618, 0x02618,), # Shamrock
(0x0261d, 0x0261d,), # White Up Pointing Index
(0x02620, 0x02620,), # Skull And Crossbones
(0x02622, 0x02623,), # Radioactive Sign ..Biohazard Sign
(0x02626, 0x02626,), # Orthodox Cross
(0x0262a, 0x0262a,), # Star And Crescent
(0x0262e, 0x0262f,), # Peace Symbol ..Yin Yang
(0x02638, 0x0263a,), # Wheel Of Dharma ..White Smiling Face
(0x02640, 0x02640,), # Female Sign
(0x02642, 0x02642,), # Male Sign
(0x0265f, 0x02660,), # Black Chess Pawn ..Black Spade Suit
(0x02663, 0x02663,), # Black Club Suit
(0x02665, 0x02666,), # Black Heart Suit ..Black Diamond Suit
(0x02668, 0x02668,), # Hot Springs
(0x0267b, 0x0267b,), # Black Universal Recycling Symbol
(0x0267e, 0x0267e,), # Permanent Paper Sign
(0x02692, 0x02692,), # Hammer And Pick
(0x02694, 0x02697,), # Crossed Swords ..Alembic
(0x02699, 0x02699,), # Gear
(0x0269b, 0x0269c,), # Atom Symbol ..Fleur-de-lis
(0x026a0, 0x026a0,), # Warning Sign
(0x026a7, 0x026a7,), # Male With Stroke And Male And Female Sign
(0x026b0, 0x026b1,), # Coffin ..Funeral Urn
(0x026c8, 0x026c8,), # Thunder Cloud And Rain
(0x026cf, 0x026cf,), # Pick
(0x026d1, 0x026d1,), # Helmet With White Cross
(0x026d3, 0x026d3,), # Chains
(0x026e9, 0x026e9,), # Shinto Shrine
(0x026f0, 0x026f1,), # Mountain ..Umbrella On Ground
(0x026f4, 0x026f4,), # Ferry
(0x026f7, 0x026f9,), # Skier ..Person With Ball
(0x02702, 0x02702,), # Black Scissors
(0x02708, 0x02709,), # Airplane ..Envelope
(0x0270c, 0x0270d,), # Victory Hand ..Writing Hand
(0x0270f, 0x0270f,), # Pencil
(0x02712, 0x02712,), # Black Nib
(0x02714, 0x02714,), # Heavy Check Mark
(0x02716, 0x02716,), # Heavy Multiplication X
(0x0271d, 0x0271d,), # Latin Cross
(0x02721, 0x02721,), # Star Of David
(0x02733, 0x02734,), # Eight Spoked Asterisk ..Eight Pointed Black Star
(0x02744, 0x02744,), # Snowflake
(0x02747, 0x02747,), # Sparkle
(0x02763, 0x02764,), # Heavy Heart Exclamation ..Heavy Black Heart
(0x027a1, 0x027a1,), # Black Rightwards Arrow
(0x02934, 0x02935,), # Arrow Pointing Rightward..Arrow Pointing Rightward
(0x02b05, 0x02b07,), # Leftwards Black Arrow ..Downwards Black Arrow
(0x1f170, 0x1f171,), # Negative Squared Latin C..Negative Squared Latin C
(0x1f17e, 0x1f17f,), # Negative Squared Latin C..Negative Squared Latin C
(0x1f321, 0x1f321,), # Thermometer
(0x1f324, 0x1f32c,), # White Sun With Small Clo..Wind Blowing Face
(0x1f336, 0x1f336,), # Hot Pepper
(0x1f37d, 0x1f37d,), # Fork And Knife With Plate
(0x1f396, 0x1f397,), # Military Medal ..Reminder Ribbon
(0x1f399, 0x1f39b,), # Studio Microphone ..Control Knobs
(0x1f39e, 0x1f39f,), # Film Frames ..Admission Tickets
(0x1f3cb, 0x1f3ce,), # Weight Lifter ..Racing Car
(0x1f3d4, 0x1f3df,), # Snow Capped Mountain ..Stadium
(0x1f3f3, 0x1f3f3,), # Waving White Flag
(0x1f3f5, 0x1f3f5,), # Rosette
(0x1f3f7, 0x1f3f7,), # Label
(0x1f43f, 0x1f43f,), # Chipmunk
(0x1f441, 0x1f441,), # Eye
(0x1f4fd, 0x1f4fd,), # Film Projector
(0x1f549, 0x1f54a,), # Om Symbol ..Dove Of Peace
(0x1f56f, 0x1f570,), # Candle ..Mantelpiece Clock
(0x1f573, 0x1f579,), # Hole ..Joystick
(0x1f587, 0x1f587,), # Linked Paperclips
(0x1f58a, 0x1f58d,), # Lower Left Ballpoint Pen..Lower Left Crayon
(0x1f590, 0x1f590,), # Raised Hand With Fingers Splayed
(0x1f5a5, 0x1f5a5,), # Desktop Computer
(0x1f5a8, 0x1f5a8,), # Printer
(0x1f5b1, 0x1f5b2,), # Three Button Mouse ..Trackball
(0x1f5bc, 0x1f5bc,), # Frame With Picture
(0x1f5c2, 0x1f5c4,), # Card Index Dividers ..File Cabinet
(0x1f5d1, 0x1f5d3,), # Wastebasket ..Spiral Calendar Pad
(0x1f5dc, 0x1f5de,), # Compression ..Rolled-up Newspaper
(0x1f5e1, 0x1f5e1,), # Dagger Knife
(0x1f5e3, 0x1f5e3,), # Speaking Head In Silhouette
(0x1f5e8, 0x1f5e8,), # Left Speech Bubble
(0x1f5ef, 0x1f5ef,), # Right Anger Bubble
(0x1f5f3, 0x1f5f3,), # Ballot Box With Ballot
(0x1f5fa, 0x1f5fa,), # World Map
(0x1f6cb, 0x1f6cb,), # Couch And Lamp
(0x1f6cd, 0x1f6cf,), # Shopping Bags ..Bed
(0x1f6e0, 0x1f6e5,), # Hammer And Wrench ..Motor Boat
(0x1f6e9, 0x1f6e9,), # Small Airplane
(0x1f6f0, 0x1f6f0,), # Satellite
(0x1f6f3, 0x1f6f3,), # Passenger Ship
),
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +0,0 @@
"""
Exports function list_versions() for unicode version level support.
This code generated by wcwidth/bin/update-tables.py on 2023-09-14 15:45:33 UTC.
"""
def list_versions():
"""
Return Unicode version levels supported by this module release.
Any of the version strings returned may be used as keyword argument
``unicode_version`` to the ``wcwidth()`` family of functions.
:returns: Supported Unicode version numbers in ascending sorted order.
:rtype: list[str]
"""
return (
"4.1.0",
"5.0.0",
"5.1.0",
"5.2.0",
"6.0.0",
"6.1.0",
"6.2.0",
"6.3.0",
"7.0.0",
"8.0.0",
"9.0.0",
"10.0.0",
"11.0.0",
"12.0.0",
"12.1.0",
"13.0.0",
"14.0.0",
"15.0.0",
"15.1.0",
)

View File

@ -1,345 +0,0 @@
"""
This is a python implementation of wcwidth() and wcswidth().
https://github.com/jquast/wcwidth
from Markus Kuhn's C code, retrieved from:
http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
This is an implementation of wcwidth() and wcswidth() (defined in
IEEE Std 1002.1-2001) for Unicode.
http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
In fixed-width output devices, Latin characters all occupy a single
"cell" position of equal width, whereas ideographic CJK characters
occupy two such cells. Interoperability between terminal-line
applications and (teletype-style) character terminals using the
UTF-8 encoding requires agreement on which character should advance
the cursor by how many cell positions. No established formal
standards exist at present on which Unicode character shall occupy
how many cell positions on character terminals. These routines are
a first attempt of defining such behavior based on simple rules
applied to data provided by the Unicode Consortium.
For some graphical characters, the Unicode standard explicitly
defines a character-cell width via the definition of the East Asian
FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
In all these cases, there is no ambiguity about which width a
terminal shall use. For characters in the East Asian Ambiguous (A)
class, the width choice depends purely on a preference of backward
compatibility with either historic CJK or Western practice.
Choosing single-width for these characters is easy to justify as
the appropriate long-term solution, as the CJK practice of
displaying these characters as double-width comes from historic
implementation simplicity (8-bit encoded characters were displayed
single-width and 16-bit ones double-width, even for Greek,
Cyrillic, etc.) and not any typographic considerations.
Much less clear is the choice of width for the Not East Asian
(Neutral) class. Existing practice does not dictate a width for any
of these characters. It would nevertheless make sense
typographically to allocate two character cells to characters such
as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
represented adequately with a single-width glyph. The following
routines at present merely assign a single-cell width to all
neutral characters, in the interest of simplicity. This is not
entirely satisfactory and should be reconsidered before
establishing a formal standard in this area. At the moment, the
decision which Not East Asian (Neutral) characters should be
represented by double-width glyphs cannot yet be answered by
applying a simple rule from the Unicode database content. Setting
up a proper standard for the behavior of UTF-8 character terminals
will require a careful analysis not only of each Unicode character,
but also of each presentation form, something the author of these
routines has avoided to do so far.
http://www.unicode.org/unicode/reports/tr11/
Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
"""
from __future__ import division
# std imports
import os
import sys
import warnings
# local
from .table_vs16 import VS16_NARROW_TO_WIDE
from .table_wide import WIDE_EASTASIAN
from .table_zero import ZERO_WIDTH
from .unicode_versions import list_versions
try:
# std imports
from functools import lru_cache
except ImportError:
# lru_cache was added in Python 3.2
# 3rd party
from backports.functools_lru_cache import lru_cache
# global cache
_PY3 = sys.version_info[0] >= 3
def _bisearch(ucs, table):
"""
Auxiliary function for binary search in interval table.
:arg int ucs: Ordinal value of unicode character.
:arg list table: List of starting and ending ranges of ordinal values,
in form of ``[(start, end), ...]``.
:rtype: int
:returns: 1 if ordinal value ucs is found within lookup table, else 0.
"""
lbound = 0
ubound = len(table) - 1
if ucs < table[0][0] or ucs > table[ubound][1]:
return 0
while ubound >= lbound:
mid = (lbound + ubound) // 2
if ucs > table[mid][1]:
lbound = mid + 1
elif ucs < table[mid][0]:
ubound = mid - 1
else:
return 1
return 0
@lru_cache(maxsize=1000)
def wcwidth(wc, unicode_version='auto'):
r"""
Given one Unicode character, return its printable length on a terminal.
:param str wc: A single Unicode character.
:param str unicode_version: A Unicode version number, such as
``'6.0.0'``. A list of version levels suported by wcwidth
is returned by :func:`list_versions`.
Any version string may be specified without error -- the nearest
matching version is selected. When ``latest`` (default), the
highest Unicode version level is used.
:return: The width, in cells, necessary to display the character of
Unicode string character, ``wc``. Returns 0 if the ``wc`` argument has
no printable effect on a terminal (such as NUL '\0'), -1 if ``wc`` is
not printable, or has an indeterminate effect on the terminal, such as
a control character. Otherwise, the number of column positions the
character occupies on a graphic terminal (1 or 2) is returned.
:rtype: int
See :ref:`Specification` for details of cell measurement.
"""
ucs = ord(wc) if wc else 0
# small optimization: early return of 1 for printable ASCII, this provides
# approximately 40% performance improvement for mostly-ascii documents, with
# less than 1% impact to others.
if 32 <= ucs < 0x7f:
return 1
# C0/C1 control characters are -1 for compatibility with POSIX-like calls
if ucs and ucs < 32 or 0x07F <= ucs < 0x0A0:
return -1
_unicode_version = _wcmatch_version(unicode_version)
# Zero width
if _bisearch(ucs, ZERO_WIDTH[_unicode_version]):
return 0
# 1 or 2 width
return 1 + _bisearch(ucs, WIDE_EASTASIAN[_unicode_version])
def wcswidth(pwcs, n=None, unicode_version='auto'):
"""
Given a unicode string, return its printable length on a terminal.
:param str pwcs: Measure width of given unicode string.
:param int n: When ``n`` is None (default), return the length of the entire
string, otherwise only the first ``n`` characters are measured. This
argument exists only for compatibility with the C POSIX function
signature. It is suggested instead to use python's string slicing
capability, ``wcswidth(pwcs[:n])``
:param str unicode_version: An explicit definition of the unicode version
level to use for determination, may be ``auto`` (default), which uses
the Environment Variable, ``UNICODE_VERSION`` if defined, or the latest
available unicode version, otherwise.
:rtype: int
:returns: The width, in cells, needed to display the first ``n`` characters
of the unicode string ``pwcs``. Returns ``-1`` for C0 and C1 control
characters!
See :ref:`Specification` for details of cell measurement.
"""
# this 'n' argument is a holdover for POSIX function
_unicode_version = None
end = len(pwcs) if n is None else n
width = 0
idx = 0
last_measured_char = None
while idx < end:
char = pwcs[idx]
if char == u'\u200D':
# Zero Width Joiner, do not measure this or next character
idx += 2
continue
if char == u'\uFE0F' and last_measured_char:
# on variation selector 16 (VS16) following another character,
# conditionally add '1' to the measured width if that character is
# known to be converted from narrow to wide by the VS16 character.
if _unicode_version is None:
_unicode_version = _wcversion_value(_wcmatch_version(unicode_version))
if _unicode_version >= (9, 0, 0):
width += _bisearch(ord(last_measured_char), VS16_NARROW_TO_WIDE["9.0.0"])
last_measured_char = None
idx += 1
continue
# measure character at current index
wcw = wcwidth(char, unicode_version)
if wcw < 0:
# early return -1 on C0 and C1 control characters
return wcw
if wcw > 0:
# track last character measured to contain a cell, so that
# subsequent VS-16 modifiers may be understood
last_measured_char = char
width += wcw
idx += 1
return width
@lru_cache(maxsize=128)
def _wcversion_value(ver_string):
"""
Integer-mapped value of given dotted version string.
:param str ver_string: Unicode version string, of form ``n.n.n``.
:rtype: tuple(int)
:returns: tuple of digit tuples, ``tuple(int, [...])``.
"""
retval = tuple(map(int, (ver_string.split('.'))))
return retval
@lru_cache(maxsize=8)
def _wcmatch_version(given_version):
"""
Return nearest matching supported Unicode version level.
If an exact match is not determined, the nearest lowest version level is
returned after a warning is emitted. For example, given supported levels
``4.1.0`` and ``5.0.0``, and a version string of ``4.9.9``, then ``4.1.0``
is selected and returned:
>>> _wcmatch_version('4.9.9')
'4.1.0'
>>> _wcmatch_version('8.0')
'8.0.0'
>>> _wcmatch_version('1')
'4.1.0'
:param str given_version: given version for compare, may be ``auto``
(default), to select Unicode Version from Environment Variable,
``UNICODE_VERSION``. If the environment variable is not set, then the
latest is used.
:rtype: str
:returns: unicode string, or non-unicode ``str`` type for python 2
when given ``version`` is also type ``str``.
"""
# Design note: the choice to return the same type that is given certainly
# complicates it for python 2 str-type, but allows us to define an api that
# uses 'string-type' for unicode version level definitions, so all of our
# example code works with all versions of python.
#
# That, along with the string-to-numeric and comparisons of earliest,
# latest, matching, or nearest, greatly complicates this function.
# Performance is somewhat curbed by memoization.
_return_str = not _PY3 and isinstance(given_version, str)
if _return_str:
# avoid list-comprehension to work around a coverage issue:
# https://github.com/nedbat/coveragepy/issues/753
unicode_versions = list(map(lambda ucs: ucs.encode(), list_versions()))
else:
unicode_versions = list_versions()
latest_version = unicode_versions[-1]
if given_version in (u'auto', 'auto'):
given_version = os.environ.get(
'UNICODE_VERSION',
'latest' if not _return_str else latest_version.encode())
if given_version in (u'latest', 'latest'):
# default match, when given as 'latest', use the most latest unicode
# version specification level supported.
return latest_version if not _return_str else latest_version.encode()
if given_version in unicode_versions:
# exact match, downstream has specified an explicit matching version
# matching any value of list_versions().
return given_version if not _return_str else given_version.encode()
# The user's version is not supported by ours. We return the newest unicode
# version level that we support below their given value.
try:
cmp_given = _wcversion_value(given_version)
except ValueError:
# submitted value raises ValueError in int(), warn and use latest.
warnings.warn("UNICODE_VERSION value, {given_version!r}, is invalid. "
"Value should be in form of `integer[.]+', the latest "
"supported unicode version {latest_version!r} has been "
"inferred.".format(given_version=given_version,
latest_version=latest_version))
return latest_version if not _return_str else latest_version.encode()
# given version is less than any available version, return earliest
# version.
earliest_version = unicode_versions[0]
cmp_earliest_version = _wcversion_value(earliest_version)
if cmp_given <= cmp_earliest_version:
# this probably isn't what you wanted, the oldest wcwidth.c you will
# find in the wild is likely version 5 or 6, which we both support,
# but it's better than not saying anything at all.
warnings.warn("UNICODE_VERSION value, {given_version!r}, is lower "
"than any available unicode version. Returning lowest "
"version level, {earliest_version!r}".format(
given_version=given_version,
earliest_version=earliest_version))
return earliest_version if not _return_str else earliest_version.encode()
# create list of versions which are less than our equal to given version,
# and return the tail value, which is the highest level we may support,
# or the latest value we support, when completely unmatched or higher
# than any supported version.
#
# function will never complete, always returns.
for idx, unicode_version in enumerate(unicode_versions):
# look ahead to next value
try:
cmp_next_version = _wcversion_value(unicode_versions[idx + 1])
except IndexError:
# at end of list, return latest version
return latest_version if not _return_str else latest_version.encode()
# Maybe our given version has less parts, as in tuple(8, 0), than the
# next compare version tuple(8, 0, 0). Test for an exact match by
# comparison of only the leading dotted piece(s): (8, 0) == (8, 0).
if cmp_given == cmp_next_version[:len(cmp_given)]:
return unicode_versions[idx + 1]
# Or, if any next value is greater than our given support level
# version, return the current value in index. Even though it must
# be less than the given value, its our closest possible match. That
# is, 4.1 is returned for given 4.9.9, where 4.1 and 5.0 are available.
if cmp_next_version > cmp_given:
return unicode_version
assert False, ("Code path unreachable", given_version, unicode_versions) # pragma: no cover

15
main.py
View File

@ -9,7 +9,7 @@ user_input = []
def process_command(symbol):
global operation, method
if symbol.lower() in "asmdrq":
if symbol.lower() in "asmdq":
operation = symbol
elif operation == "m" and symbol in "1234":
method = symbol
@ -65,10 +65,6 @@ def perform_operation(first_register: bu.BasicRegister, second_register: bu.Basi
operation, method = "", ""
case _:
pass
case "r":
result, data_table = bu.binary_square_root(first_register)
print(f"\nSquare root:\n{bu.format_device_state_table(data_table)}\nResult: {result}")
operation, method = "", ""
case "q":
exit(0)
@ -97,11 +93,10 @@ def input_handler(first_register: bu.BasicRegister, second_register: bu.BasicReg
while True:
prompt_text: str = get_prompt_text(operation, method).format(first_register, second_register, operation, method)
# print()
print()
if operation == "":
raw_user_input = input("Choose the operation:\n"
"[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, [r]oot, [q]uit\n" +
prompt_text + " > ")
raw_user_input = input("Choose the operation:\n[a]ddition, [s]ubtraction, [m]ultiplication, [d]ivision, "
"[q]uit\n" + prompt_text + " > ")
elif operation == "m":
raw_user_input = input("Choose method to use (1-4):\n" + prompt_text + " > ")
elif operation == "d":
@ -118,6 +113,4 @@ if __name__ == '__main__':
reg1: bu.BasicRegister = bu.BasicRegister(bu.get_memory("first operand"))
reg2: bu.BasicRegister = bu.BasicRegister(bu.get_memory("second operand"))
# TODO live-swapping of registers!!!
input_handler(reg1, reg2)