avatarChris Webb

Summary

The undefined website article discusses a Python module named mathsymbols that simplifies the use of mathematical symbols in Python code by providing a dictionary of Unicode characters, search functionality, and examples of usage.

Abstract

The article introduces the mathsymbols Python module, a tool designed to streamline the incorporation of mathematical symbols into Python code. Recognizing the vast number of Unicode characters and the difficulty in locating the correct ones, the author has compiled a dictionary of mathematical symbols, categorizing them for ease of access. The module is part of a project hosted on GitHub and includes two main files: mathsymbols.py and mathsymbolsdemo.py. The mathsymbols.py file contains the dictionary and functions for searching and printing symbols, while mathsymbolsdemo.py demonstrates various ways to utilize the symbols in code. The author encourages feedback on missing mathematical symbols and notes the possibility of some characters not displaying correctly across different platforms and fonts. The article also touches on the new feature of Medium for native code formatting and provides a brief tutorial on how to use it.

Opinions

  • The author believes that the mathsymbols module enhances code readability and simplifies the process of using mathematical notation in Python.
  • They express a preference for using dictionary keys for less common symbols and copy-pasting well-known symbols directly into the code for clarity.
  • The author values community input, inviting readers to suggest additional mathematical symbols that could be included in the module.
  • They find the new Medium code formatting feature beneficial and recommend it to other writers who include code in their articles.
  • The author notes a personal observation that some Unicode characters may not render correctly on all devices, highlighting the importance of font support for Unicode characters.

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 source code lives in a Github repository.

The Code

This is the mathsymbols.py file.

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="")

        print(f"   hexadecimal: \\u{hex(ord(symbols_to_print[symbol]))[2:]}") 

All my previous articles on Medium have used Github Gists for source code. Medium recently added the ability to post formatted code natively and this is the first time I have used this feature. I hope you like it. If you write articles on Medium which include code you might want to try it yourself. This article by Alex Benzer takes you through the process.

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.

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 using hexadecimal Unicode
    # 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:

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.

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.

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.

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:

&#[decimal]; &#x[hexadecimal];

As I mentioned above, if you know of any Unicode characters of a generally mathematical nature which I have missed please let me know.

This article was previously published on CodeDrome

Python
Programming
Mathematics
Recommended from ReadMedium