my_module1.py 5.71 KB
#!/usr/bin/env python3

from __future__ import annotations

# TODO :
# - classmethod vs staticmethod
# - doctest
# - exception (custom)
# - dataclass
# - generic types
# TODO: return type de plusieurs params :
# def response(query: str) -> Response[str]:
# -> Any:
# -> Generic
# -> None:
# -> Sequence[T]:
# -> Dict[str, int]:
# -> [int,float]: ???
# -> List[T]:
# -> tuple[int, str]:
# ...


# '''
# =================================================================
#     MODULE Comment
# =================================================================
# '''


# '''
# =================================================================
#     PACKAGES IMPORT
# =================================================================
# '''

# --- GENERAL PURPOSE IMPORTS ---

from typing import Dict, List, Tuple
import platform
from datetime import date

# --- PROJECT SPECIFIC IMPORTS ---

#from django.conf import settings as djangosettings
#from common.models import AgentSurvey, AgentCmd, AgentLogs
#from src.core.pyros_django.obsconfig.configpyros import ConfigPyros
#from device_controller.abstract_component.device_controller import (
#    DCCNotFoundException, UnknownGenericCmdException, UnimplementedGenericCmdException, UnknownNativeCmdException
#)


# '''
# =================================================================
#     GENERAL MODULE CONSTANTS & FUNCTIONS DEFINITIONS
# =================================================================
# '''

# - General constants

DEBUG = False

IS_WINDOWS = platform.system() == "Windows"


#
# - General Functions
#

def general_function_that_returns_a_float(arg_a: int, arg_b: str, arg_c: float=1.2, arg_d: bool=True) -> float:
    '''
    This function is used for ... blabla ...

    Args:
        arg_a: the path of the file to wrap
        arg_b: instance to wrap
        arg_c: toto
        arg_d: whether or not to delete the file when the File instance is destructed

    Returns:
        A buffered writable file descriptor

    Raises:
        AttributeError: The ``Raises`` section is a list of all exceptions
            that are relevant to the interface.
        ValueError: If `arg_a` is equal to `arg_b`.
    '''

    # comment on a
    a = 1

    # comment on b
    b = 2

    return 3.5


def general_function_that_returns_a_tuple_of_3_elem(a: int, b: int=2, c: str='titi') -> Tuple[str, float, str]:
    ''' Commentaire général sur la fonction

    Args:
        a: the path of the file to wrap
        b: instance to wrap
        c: toto
    '''

    return (a, b, c+' toto')


class MySuperClass1:
    pass


class MySuperClass2:
    pass


# '''
# =================================================================
#     CLASS MyFirstClass
# =================================================================
# '''
class MySimpleClass(MySuperClass1, MySuperClass2):
    ''' a Class with multi-inheritance

    blabla

    blabla
    '''

    #
    # The class attributes
    #

    names: List[str] = ["Guido", "Jukka", "Ivan"]
    ''' List is mutable'''

    version: Tuple[int, int, int] = (3, 7, 1)
    ''' Tuple is UNmutable'''

    options: Dict[str, bool] = {"centered": False, "capitalize": True}
    ''' Dict (is mutable) '''

    my_attr1: dict = {}
    current_file = None
    pickle_file = "obsconfig.p"

    #
    # The class methods
    #

    def __init__(self, a: int, b: float) -> None:
        '''
        La methode __init__ doit toujours retourner "None"

        Args:
            a: blabla
        '''

        c = 1
        d = 2

        return False

    def __str__(self) -> str:
        '''
        La methode __str__ doit toujours retourner "str"
        '''
        return "toto"

    def my_method2(self, a: int, b: float) -> None:
        a = 1
        b = 2


# '''
# =================================================================
#     CLASS Person
# =================================================================
# '''

class Person:
    """ Class to create a person, in several ways (several Factory methods)

    => Illustrate difference btw static and class methods

    Usage:

    1) Classic Constructor :

    >>> person1 = Person('Alfredo', 21)

    2) Class method (Factory) :

    >>> person2 = Person.fromBirthYear('Peter', 2000)
    >>> person2.age
    22

    3) Another class method (Factory) :

    >>> person3 = Person.twin('John', person2)
    >>> person3.age == person2.age
    True
    >>> person3.name == person2.name
    False

    4) Static method (does not need access to the class attributes or methods) :

    >>> Person.isAdult(22)
    True

    """

    def __init__(self, name: str, age: int) -> None:
        self.name = name
        self.age = age

    # a class method to create a Person object by birth year
    @classmethod
    def fromBirthYear(cls, name: str, year: int) -> Person:
        return cls(name, date.today().year - year)

    # a class method to create a Person object from another
    @classmethod
    def twin(cls, name: str, p: Person) -> Person:
        return cls(name, p.age)

    # a static method to check if a Person is adult or not
    @staticmethod
    def isAdult(age: int):
        return age > 18


# '''
# =================================================================
#    Main function (definition)
# =================================================================
# '''


def main() -> None:
    '''
    Comment on Main function definition
    '''
    a = 1
    b = 2
    c = a+b

    a = general_function_that_returns_a_tuple_of_3_elem(1, 2)
    print(a)

    import doctest
    doctest.testmod()


'''
=================================================================
    Main function (execution)
=================================================================
'''
if __name__ == "__main__":
    '''
    Comment on Main function execution
    '''
    main()