Dokumenteerimine

Selles peatükis räägime, kuidas korrektselt dokumenteerida enda koodi ning miks seda teha tuleks. Lisaks räägime ka koodi kommenteerimise korrektsest stiilist.

Korrektne dokumenteerimine garanteerib koodilugejale koodiplokkide, funktsioonide ja muu sisu lihtsa mõistmise. Programmeerimise vallas toimub tihti projektide üleandmist või lahti seletamist teistele isikutele, kes koodist võimalikult kiiresti aru saama peavad. Selleks kasutatakse kommentaare ning docstringe.

Kommentaar

Kommentaarid on koodikirjeldused, mida kompilaator koodilugemisel eirab. Kommentaarid peaksid olema täislaused ning algama suure algustähega. Kommentaare defineeritakse sümboli # abil. Lisades # rea algusesse, eiratakse tervet koodirida. Kui sümbol ei paikne rea alguses, loetakse sellele eelnev kood ikkagi sisse. Kommentaar algab tühikuga ning kui kommentaar rea keskele lisada, peab koodi lõpu ning # sümboli vahele jätma vähemalt 2 tühikut.

Näide koodirea alguses olevast kommentaarist:

check = False
# Boolean to check whether all elements in a list are correctly sorted.

Näide koodirea lõpus olevast kommentaarist:

x += index  # Increase x by the value of index

Kommentaare kasutatakse sageli ka testitava koodi eiramiseks. Juhul kui koodirida ei ole valmis või ei tööta ajutiselt korrektselt, lisatakse rea algusesse kommentaar (kood kommenteeritakse välja).

# x = very_complex_function()
# This row and the row above will be ignored.

Attention

Lisainfona võib välja tuua, et Pythonis on olemas ka mitmerealine kommentaar, kuid PEP 8 koodistiil ei soovita selle kasutamist, kuna see sarnaneb väga docstringiga, mida vaatame järgmises alampeatükis. Mitmerealine kommentaar käib kolme jutumärgi vahele, olgu nad siis ühe- või kahekordsed jutumärgid.

Näide mitmerealisest kommentaarist:

'''
This is a multiline
comment.
'''

"""
This is also a multiline
comment.
"""

Docstring

Docstring on atribuut, mis lisatakse iga mooduli, funktsiooni, klassi ning meetodi külge ning mis seletab selle konkreetse elemendi sisu. Docstring defineeritakse kolme jutumärgipaari abil ning see saab olla ühe- või mitmerealine.

Üherealine docstring seletab lühidalt elemendi (nt funktsiooni) sisu.

def find_max_in_list(some_list: list):
    """Find and return the maximum value in some_list."""
    # Code

Mitmerealine docstring seletab elemendi sisu pikemalt lahti. Funktsiooni puhul lisatakse informatsiooni iga kaasaantud muutuja ning tagastatava väärtuse kohta.

def check_for_not_allowed_characters(text: str, chars: list) -> bool:
    """
    Check whether String text contains characters from List chars.

    :param text: String to be checked.
    :param chars: List containing not allowed characters.
    :return: Returns True when String text does not contain any
    characters from List chars. Otherwise returns False.
    """
     # Code

Mõned punktid, mida tuleb järgida docstring'i kirjutamisel:

  • Docstring'is kasutatakse kolmekordseid jutumärke """. Seda isegi juhul, kui kommentaar mahub ühele reale.

  • Enne ega pärast docstring'i ei ole tühje ridu. Docstring järgneb vahetult mooduli, funktsiooni, klassi või meetodi definitsioonile. Mooduli või klassi puhul järgneb kirjeldusele tühi rida.

  • Mitmerealise kirjelduse puhul peab esimene rida olema lühike kokkuvõte, mis lõppeb punktiga. Sellele järgneb tühi rida ning seejärel võib tulla elemendi pikem kirjeldus.

  • Kirjelduses kasutatakse täislauseid käskivas kõneviisis (ingl k imperative), näiteks sobib stiil Return sum, kuid ei sobi kirjeldus Returns sum.

Rohkem lugemist

Terve fail docstringidega

"""
Book Management Module

This module provides functionalities to manage a collection of books.
"""


class Book:
    """
    A class used to represent a Book.

    Attributes:
        title (str): The title of the book
        author (str): The author of the book
        year (int): The year the book was published
    """

    def __init__(self, title, author, year):
        """
        Constructs all the necessary attributes for the Book object.

        :param title: The title of the book
        :type title: str
        :param author: The author of the book
        :type author: str
        :param year: The year the book was published
        :type year: int
        """
        self.title = title
        self.author = author
        self.year = year

    def get_description(self):
        """
        Returns a string representation of the book.

        :return: A string in the format 'Title by Author, Year'.
        :rtype: str
        """
        return f"{self.title} by {self.author}, {self.year}"


def add_book(collection, book):
    """
    Adds a book to the collection.

    :param collection: The collection of books
    :type collection: list of Book
    :param book: The book to add
    :type book: Book
    :return: The updated collection with the new book added
    :rtype: list of Book
    """
    collection.append(book)
    return collection


def list_books(collection):
    """
    Prints all the books in the collection.

    :param collection: The collection of books
    :type collection: list of Book
    """
    for book in collection:
        print(book.get_description())


def find_book_by_title(collection, title):
    """
    Finds a book in the collection by its title.

    :param collection: The collection of books
    :type collection: list of Book
    :param title: The title of the book to find
    :type title: str
    :return: The book with the matching title, or None if not found
    :rtype: Book or None
    """
    for book in collection:
        if book.title == title:
            return book
    return None


if __name__ == "__main__":
    # Create a collection of books
    book_collection = []

    # Create some book instances
    book1 = Book("1984", "George Orwell", 1949)
    book2 = Book("To Kill a Mockingbird", "Harper Lee", 1960)

    # Add books to the collection
    add_book(book_collection, book1)
    add_book(book_collection, book2)

    # List all books
    print("Listing all books in the collection:")
    list_books(book_collection)

    # Find a book by title
    search_title = "1984"
    found_book = find_book_by_title(book_collection, search_title)
    if found_book:
        print(f"\nFound book: {found_book.get_description()}")
    else:
        print(f"\nBook with title '{search_title}' not found.")