# Mathematical Symbols in Python I often use mathematical symbols in Python code which results in me scrabbling around to find the ones I need so I decided to write a simple module to simplify the process, which I will describe in this article.

## Overview

The Unicode character encoding system currently (version 15.0, released September 2022) consists of 149,186 characters in 30 sub-categories. The characters likely to be used for mathematical notation are scattered across several categories so for my mathsymbols module I gathered them together into a dictionary, and also provided functions for searching the dictionary and printing out details of each symbol.

With nearly 150,000 Unicode characters it is almost inevitable that I have missed some which could be considered mathematical so if you know of any that you think should be included please let me know.

Once you import the mathsymbols module there are no less than four ways to use them in code which we'll see later.

## The Project

This project consists of the following files:

• mathsymbols.py

• mathsymbolsdemo.py

## The Code

This is the mathsymbols.py file.

mathsymbols.py

from types import MappingProxyType

symbols = MappingProxyType(
{
"set_empty": "∅",
"set_union": "∪",
"set_intersection": "∩",
"set_is_element_of": "∈",
"set_is_not_element_of": "∉",
"set_is_subset_of": "⊆",
"set_is_proper_subset_of": "⊂",
"set_is_not_subset_of": "⊄",
"set_is_superset_of": "⊇",
"set_is_proper_superset_of": "⊃",
"set_is_not_superset_of": "⊅",
"set_universal": "ξ",
"set_minus": "∖",
"set_cartesian_product": "×",
"set_difference": "\\",
"set_symmetric_difference": "Δ",
"set_cardinality": "|",
"set_complement": "'",
"set_power_set": "ℙ",
"set_contains_as_member": "∋",
"set_does_not_contain_as_member": "∌",
"complex_numbers": "ℂ",
"real_numbers": "ℝ",
"rational_numbers": "ℚ",
"integers": "ℤ",
"natural_numbers": "ℕ",
"superscript_i": "ⁱ",
"superscript_n": "ⁿ",
"superscript_plus_sign": "⁺",
"superscript_minus": "⁻",
"superscript_zero_0": "⁰",
"superscript_one_1": "¹",
"superscript_two_2": "²",
"superscript_three_3": "³",
"superscript_four_4": "⁴",
"superscript_five_5": "⁵",
"superscript_six_6": "⁶",
"superscript_seven_7": "⁷",
"superscript_eight_8": "⁸",
"superscript_nine_9": "⁹",
"subscript_zero_0": "₀",
"subscript_one_1": "₁",
"subscript_two_2": "₂",
"subscript_three_3": "₃",
"subscript_four_4": "₄",
"subscript_five_5": "₅",
"subscript_six_6": "₆",
"subscript_seven_7": "₇",
"subscript_eight_8": "₈",
"subscript_nine_9": "₉",
"fraction_one_half_1_2": "½",
"fraction_zero_thirds_0_3": "↉",
"fraction_one_third_1_3": "⅓",
"fraction_two_thirds_2_3": "⅔",
"fraction_one_quarter_1_4": "¼",
"fraction_three_quarters_3_4": "¾",
"fraction_one_fifth_1_5": "⅕",
"fraction_two_fifths_2_5": "⅖",
"fraction_three_fifths_3_5": "⅗",
"fraction_four_fifths_4_5": "⅘",
"fraction_one_sixth_1_6": "⅙",
"fraction_five_sixths_5_6": "⅚",
"fraction_one_seventh_1_7": "⅐",
"fraction_one_eighth_1_8": "⅛",
"fraction_three_eighths_3_8": "⅜",
"fraction_five_eighths_5_8": "⅝",
"fraction_seven_eighths_7_8": "⅞",
"fraction_one_ninth_1_9": "⅑",
"fraction_one_tenth_1_10": "⅒",
"degree_angle": "°",
"degree_celsius": "℃",
"degree_fahrenheit": "℉",
"diameter": "⌀",
"multiplication": "✕",
"division": "÷",
"left_floor": "⌊",
"right_floor": "⌋",
"left_ceiling": "⌈",
"right_ceiling": "⌉",
"product": "∏",
"coproduct": "∐",
"summation": "∑",
"summation_top": "⎲",
"summation_bottom": "⎳",
"partial_differential": "∂",
"integral": "∫",
"top_half_integral": "⌠",
"bottom_half_integral": "⌡",
"not_sign": "¬",
"plus_minus_sign": "±",
"square_root": "√",
"cube_root": "∛",
"fourth_root": "∜",
"proportional_to": "∝",
"infinity": "∞",
"right_angle": "∟",
"angle": "∠",
"therefore": "∴",
"approximately_equal_to": "≅",
"not_equal_to": "≠",
"less_than_or_equal_to": "≤",
"greater_than_or_equal_to": "≥",
"right_angle_with_arc": "⊾",
"right_triangle": "⊿",
"dot_operator": "⋅",
}
)

def search(namelike):

"""
Return a dictionary of symbols with names
containing namelike argument
"""

filtered = {k: v for k, v in symbols.items() if namelike in k}

return filtered

def print_symbols(symbols_to_print = symbols):

"""
Prints symbols in the symbols argument,
or all if this is omitted
"""

for symbol in symbols_to_print.keys():

print(f"{symbol.ljust(32, ' ')}", end="")

print(f" {symbols_to_print[symbol]}", end="")

print(f"   decimal: {str(ord(symbols_to_print[symbol])).ljust(5, ' ')}", end="")

## The symbols Dictionary

This dictionary, which is wrapped in a MappingProxyType to make it immutable, uses brief descriptions as its keys and the characters themselves as values. Note that the descriptions are not the same as those used by Unicode but chosen to be more consistent and easily searchable. This means there is a certain amount of duplication in some keys, for example fractions contain the numbers in both words and digits, eg. fraction_seven_eighths_7_8.

## The search Function

This is a simple list comprehension wrapped as a dictionary, returning any keys/values with a key containing namelike. I didn't consider it necessary to provide any wildcard options due to the small number of items in the symbols dictionary.

## The print_symbols Function

This prints the supplied dictionary, symbols_to_print, or the entire symbols dictionary if this is not supplied. We can use this function to print a dictionary obtained from the search function.

Now let's try it out with the mathsymbolsdemo.py program.

mathsymbolsdemo.py

import mathsymbols as ms

def main():

print("------------------------")
print("| codedrome.com        |")
print("| Mathematical Symbols |")
print("------------------------\n")

ms.print_symbols()

# f = ms.search("root")
# ms.print_symbols(f)

# print using dictionary key
# print(f"12{ms.symbols['superscript_two_2']} = {12**2}")

# print using symbols copied/pasted into code
# print(f"⅝ + ⅛ = ¾")

# print using decimal Unicode
# temp_celsius = 18.5
# print(f"The temperature is {temp_celsius}{chr(8451)}")

# print("\u221e + \u221e = \u221e")

if __name__ == "__main__":

main()

This short program demonstrates printing all symbols, searching and printing the result, and the four ways of using symbols in code.

The line currently uncommented calls print_symbols() without an argument so prints all of the symbols dictionary. Note that I aliased mathsymbols as ms in the import. Run the code thus:

Running the Program

python3 mathsymbolsdemo.py

This will give you the following output. This is truncated to the first 12 lines but you might like to print all 106 symbols and browse through them to see the sort of stuff available. As you can see we also get the Unicode values in decimal and hexadecimal.

Program Output (truncated)

set_empty                        ∅   decimal: 8709    hexadecimal: \u2205
set_union                        ∪   decimal: 8746    hexadecimal: \u222a
set_intersection                 ∩   decimal: 8745    hexadecimal: \u2229
set_is_element_of                ∈   decimal: 8712    hexadecimal: \u2208
set_is_not_element_of            ∉   decimal: 8713    hexadecimal: \u2209
set_is_subset_of                 ⊆   decimal: 8838    hexadecimal: \u2286
set_is_proper_subset_of          ⊂   decimal: 8834    hexadecimal: \u2282
set_is_not_subset_of             ⊄   decimal: 8836    hexadecimal: \u2284
set_is_superset_of               ⊇   decimal: 8839    hexadecimal: \u2287
set_is_proper_superset_of        ⊃   decimal: 8835    hexadecimal: \u2283
set_is_not_superset_of           ⊅   decimal: 8837    hexadecimal: \u2285
set_universal                    ξ   decimal: 958     hexadecimal: \u3be

Few if any fonts offer a full complement of Unicode characters so there is a chance you might not see some of the more obscure ones. For me the characters in the symbols dictionary all work fine in VSCode and Firefox, but on my phone (Chrome on Android) they all work except superscript 4. Very strange.

Uncomment the next two lines which search for any symbols containing "root" and print the result. Running the program again gives us this output.

Program Output - search function

square_root                      √   decimal: 8730    hexadecimal: \u221a
cube_root                        ∛   decimal: 8731    hexadecimal: \u221b
fourth_root                      ∜   decimal: 8732    hexadecimal: \u221c

Uncomment the rest of the code (don't uncomment the actual comments!) which show symbols printed using the following four methods:

• Accessing the dictionary value using the key

• Copying/pasting symbols from the result of using the search function

• Using the decimal code and the chr function

• Using the hexadecimal code prefixed with \u

I can't see any reason to use either decimal or hexadecimal in Python, but would suggest the ideal usage would be to copy/paste any well known symbols into code, and use the dictionary key for more obscure ones. The latter option makes code self-documenting although admittedly rather long. Ultimately it's a personal choice based on who is likely to read or maintain your code.

After you have uncommented the last lines of code run the program one more time.

Program Output - Symbols in Code

12² = 144
⅝ + ⅛ = ¾
The temperature is 18.5℃
∞ + ∞ = ∞

A quick note about using these symbols in HTML. As this is a Python project I have output the hexadecimal values with \u as required in Python code. However, if you need to use them in HTML you can use decimal or hexadecimal codes like this:

Use in HTML

&#[decimal];