|
| 1 | +"""Create a LaTeX table with numbers in different systems.""" |
| 2 | +from math import ceil, log |
| 3 | + |
| 4 | +COLUMNS = 2 |
| 5 | +MAX_NUMBER = COLUMNS * ceil((64 + 1) / COLUMNS) |
| 6 | + |
| 7 | +BASES = {"dec": 10, "bin": 2, "oct": 8, "hex": 16} |
| 8 | +HIGHLIGHTS = ["red", "blue", "violet", "green!80!black"] |
| 9 | + |
| 10 | +BASE_NAMES_LIST = ["decimal~(dec)", "binary~(bin)", "octal~(oct)", |
| 11 | + "hexadecimal~(hex)"] |
| 12 | +DIGITS = [hex(i)[-1] for i in range(max(BASES.values()))] |
| 13 | + |
| 14 | +print(r"\begin{table}%") |
| 15 | +print(r"\centering%") |
| 16 | +print(r"\setlength{\tabcolsep}{0.2em}%") |
| 17 | + |
| 18 | +base_names = ", ".join(BASE_NAMES_LIST[:-1]) + ", and " + BASE_NAMES_LIST[-1] |
| 19 | +print( |
| 20 | + r"\caption{A table with number conversions to the " |
| 21 | + + base_names.lower() + |
| 22 | + " systems. The values of the digits are noted in the second row of " |
| 23 | + "the header. Powers of the bases are highlighted.}%") |
| 24 | +print(r"\label{tbl:numbersBases}%") |
| 25 | +print(r"\smallskip%") |
| 26 | +print(r"\resizebox{0.99999\linewidth}{!}{") |
| 27 | + |
| 28 | +BASE_COLS = [int(ceil(log(MAX_NUMBER + 1, base))) for base in BASES.values()] |
| 29 | +COL_WIDTHS = [f"{ceil(log(base ** (BASE_COLS[i] - 1) + 1, 10))}ex" |
| 30 | + for i, base in enumerate(BASES.values())] |
| 31 | + |
| 32 | +BASE_HEADER_1_lst = [r"\textbf{" + name + "}" for name in BASES] |
| 33 | +BASE_HEADER_1 = "&".join((r"\multicolumn{" + str(bc) + r"}{c" + ( |
| 34 | + "|" if i < len(BASE_COLS) - 1 else "ZZ") + "}{" |
| 35 | + + BASE_HEADER_1_lst[i] + "}") for i, bc in enumerate(BASE_COLS)) |
| 36 | + |
| 37 | +BASE_HEADER_2_lst = ["Base~" + str(base) for base in BASES.values()] |
| 38 | +BASE_HEADER_2 = "&".join((r"\multicolumn{" + str(bc) + r"}{c" + ( |
| 39 | + "|" if i < len(BASE_COLS) - 1 else "ZZ") + "}{" |
| 40 | + + BASE_HEADER_2_lst[i] + "}") for i, bc in enumerate(BASE_COLS)) |
| 41 | +BASE_HEADER_3 = "&".join( |
| 42 | + (r"\parbox{" + COL_WIDTHS[i] + r"}{\centering\noindent" + |
| 43 | + str(base ** (BASE_COLS[i] - j - 1)) + "}") for i, base in enumerate( |
| 44 | + BASES.values()) for j in range(BASE_COLS[i])) |
| 45 | +BASE_COLS_STRS = "|".join(( ("c" * j) for i, j in enumerate(BASE_COLS))) |
| 46 | + |
| 47 | +print(r"\begin{tabular}{" + "||".join(BASE_COLS_STRS |
| 48 | + for _ in range(COLUMNS)) + "}%") |
| 49 | +print(r"\hline%") |
| 50 | +print(("&".join(BASE_HEADER_1 for _ in range(COLUMNS)) + r"\\%").replace( |
| 51 | + "ZZ", "||", COLUMNS-1).replace("ZZ", "")) |
| 52 | +#print(("&".join(BASE_HEADER_2 for _ in range(COLUMNS)) + r"\\%").replace( |
| 53 | +# "ZZ", "||", COLUMNS-1).replace("ZZ", "")) |
| 54 | +print("&".join(BASE_HEADER_3 for _ in range(COLUMNS)) + r"\\%") |
| 55 | +print(r"\hline%") |
| 56 | + |
| 57 | +output = "" |
| 58 | +color_row = False |
| 59 | +for number in range(MAX_NUMBER): |
| 60 | + |
| 61 | + for i, base in enumerate(BASES.values()): |
| 62 | + use_num = number |
| 63 | + if use_num > 0: |
| 64 | + pw_check = log(use_num, base) |
| 65 | + highlight = pw_check == int(pw_check) |
| 66 | + else: |
| 67 | + highlight = False |
| 68 | + if highlight: |
| 69 | + hls = r"\textcolor{" + HIGHLIGHTS[i] + r"}{\textbf{" |
| 70 | + hle = r"}}" |
| 71 | + else: |
| 72 | + hls = hle = "" |
| 73 | + for j in range(BASE_COLS[i]): |
| 74 | + value = base ** (BASE_COLS[i] - j - 1) |
| 75 | + res = use_num // value |
| 76 | + |
| 77 | + output = output + hls + DIGITS[res] + hle + "&" |
| 78 | + use_num = use_num % value |
| 79 | + |
| 80 | + if (number + 1) % COLUMNS == 0: |
| 81 | + output = output[:-1] + r"\\%" |
| 82 | + if color_row: |
| 83 | + output = r"\rowcolor{gray!20}" + output |
| 84 | + color_row = not color_row |
| 85 | + print(output) |
| 86 | + output = "" |
| 87 | + continue |
| 88 | + |
| 89 | +print(r"\hline%") |
| 90 | +print(r"\end{tabular}%") |
| 91 | +print("}%") |
| 92 | +print(r"\end{table}%") |
0 commit comments