Python Forum
The of ( : ) what does it do?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
The of ( : ) what does it do?
#1
Hi,

I dont understand this part of the code.
The : between protein and Nutrient in protein: Nutrient = Nutrient(name="Protein") what does it do?

Thank you


from ingredient import *
from nutrition_rule import *
from typing import List

protein: Nutrient = Nutrient(name="Protein")
fat: Nutrient = Nutrient(name="Fat")
fibre: Nutrient = Nutrient(name="Fibre")
salt: Nutrient = Nutrient(name="Salt")
Nutrients: List[Item] = [protein, fat, fibre, salt]

for n in Nutrients:
    print(n)

NutrientRules: List[NutrientRule] = [NutrientRule(protein, op=OPERATOR_MIN, value=8.0),
                                     NutrientRule(fat, OPERATOR_MIN, 6.0),
                                     NutrientRule(fibre, OPERATOR_MAX, 2.0),
                                     NutrientRule(salt, OPERATOR_MAX, 0.4)]

for r in NutrientRules:
    print(r)

Ingredients: List[Ingredient] = [
    Ingredient(name="CHICKEN", cost=0.013,
               nutrient_percents={protein.name: 0.1, fat.name: 0.08, fibre.name: 0.001, salt.name: 0.002}),
    Ingredient("BEEF", 0.008, {protein.name: 0.2, fat.name: 0.1, fibre.name: 0.005, salt.name: 0.005}),
    Ingredient("MUTTON", 0.010, {protein.name: 0.15, fat.name: 0.11, fibre.name: 0.003, salt.name: 0.007}),
    Ingredient("RICE", 0.002, {protein.name: 0, fat.name: 0.01, fibre.name: 0.1, salt.name: 0.002}),
    Ingredient("WHEAT", 0.005, {protein.name: 0.04, fat.name: 0.01, fibre.name: 0.15, salt.name: 0.008}),
    Ingredient("GEL", 0.001, {protein.name: 0, fat.name: 0, fibre.name: 0, salt.name: 0})
]

for i in Ingredients:
    print(i)
Reply
#2
In your example colons are used to construct dictionaries and for type hints.

my_dictionary = {key : value}

variable : type_hint = value
Frankduc likes this post
Reply
#3
protein: Nutrient = Nutrient(name="Protein")

so protein is the name of the variable dictionary.
Nutrient is the key
Nutrient(name="Protein") the returned value of the function is value.

Those values has been inserted in list Nutrients: List[Item] = [protein, fat, fibre, salt]

and been extracted.

for n in Nutrients:
print(n)

not obvious at first glance.
Thank you
Reply
#4
You guessed wrong. In "protein: Nutrient = Nutrient(name="Protein")" the colon is used in a type hint, not in a dictionary.

protein is a variable. It is assigned the value Nutrient(name="Protein"). The assignment has a type hint telling the reader that Nutrient(name="Protein") returns an instance of class "Nutrient".

variable : type_hint = value
protien : Nutrient = Nutrient(name="Protein")

The code does exactly the same thing if you leave the type hint out.

protien = Nutrient(name="Protein")
fracjackmac, Frankduc, ibreeden like this post
Reply
#5
I guess its a slicing of list starting from 0 index to the last index.

code:

names_of_footballers = ["Ronaldo","Messi","Zidan",'Saleh"];
print(names_of_footballers[:]);

>>>["Ronaldo","Messi","Zidan",'Saleh"]
Reply
#6
No, that wasn't the context in which the OP was asking. The answer, as above, was type hints.
Reply
#7
Dean is right removing the type hints return the same.
But whats the point of doing a type hint if you dont need it? I mean the code dont get lighter.
Thank you
Reply
#8
                            ┌─────Call─────┐
                            │              │
                            │              │
                            │              │
                            ▼              ▼
protein: Nutrient = Nutrient(name="Protein")
   ▲        ▲          ▲       ▲      ▲
   │        │          │       │      │
   │        │          │       │      │
  Name   TypeHint    Class  Keyword  str
TypeHints helps the IDE to detect types and gives the developer better Information.
During runtime, TypeHints are not validated. They could be used from other libraries like Pendantic and FastAPI.
Frankduc and Gribouillis like this post
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#9
I suppose that would explain why the log file return the {function.__name__} and {self.__class__} .

def fonction_log(function):
    # rappels;
    # args est un tuple qui conserve tous les paramètres de la fonction
    # kwargs est un dictionnaire qui conserve les paramètres nommés de la fonction
    def wrapper(*args, **kwargs):
        # __class__ indique le type d'une instance de classe
        # pour obtenir la référence d'une instance (self)
        # vous devez déballer le premier élément du tuple args
        self = args[0]
        print(f"La méthode {function.__name__} de la classe {self.__class__} est appelé")
        result = function(*args, **kwargs)
        return result

    return wrapper
La méthode __init__ de la classe <class 'nutrient.Nutrient'> est appelé
or init method of the class class 'nutrient.Nutrient' was called.

or maybe i am just wrong again.

While we are at it, anyone can explain why *args, **kwargs can also return function. Arent they suppose to be for tuples and dictionaries?

For example, in this case:

# ---------------------------------
# --- Nos fonctions utilitaires ---
def get_on_the_ship():
    print("Les astronautes montent dans le vaisseau")


def take_off_ship():
    print("Le vaisseau décolle !")


def land_ship():
    print("Le vaisseau atterit.")


def exit_the_ship():
    print("Les astronautes sortent du vaisseau")


def open_the_hold():
    print("Ils ouvrent la soute pour sortir le matériel d'expedition.")


"""Il s'agit ici d'utiliser la syntaxe pythonique des décorateurs."""

# ---------------------
# --- Le décorateur ---

def prepare_take_off_and_landing(function):
    """Génère un décorateur qui s'occupe d'automatiser le décollage et l'atterissage."""

    # *args et **kwargs sont des paramètres dynamiques
    # qui permet au décorateur de s'adapter à tout type de fonction
    # L'opérateur *  sert à "déballer" ou défaire une liste (unpacking) ** pour un dictionnaire
    # *args est un tuple permettant de déballer une collection de paramètres
    # **kwargs est un dictionnaire permettant de déballer une collection de paramètres nommés
    def wrapper(*args, **kwargs):
        """Décore une fonction en ajoutant du code avant et/ou après."""
        get_on_the_ship()
        take_off_ship()

        result = function(*args, **kwargs)

        land_ship()
        exit_the_ship()
        open_the_hold()

        return result

    # on donne la docstring de 'function' à 'wrapper' !
    #wrapper.__doc__ = function.__doc__

    return wrapper
Reply
#10
You are wrong if you think type hints has anything to do with why function_log prints (not returns) "La méthode __init__ de la classe <class 'nutrient.Nutrient'> est appelé". Python knows how to get this information without the aid of type hints.

You are correct that *args is a tuple and **kwargs is a dictionary, but they have nothing to do with prepare_takeoff_and_landing(function) returning a function.

In both cases what you are seeing is a decorator, a function that adds some extra processing to existing functions.

function_log(function) prints information about the function call before calling the function.

prepare_takeoff_and_landing(function) calls get_off_ship() and take_off_ship() before calling the function, then it calls land_ship(), exit_the_ship() and open_the_hold().

What is neat about decorators is they led you add this extra processing to your functions without you having to do any programming other than declaring that your function uses the decorator. For example, if you had a function named "do_interesting_stuff()" you could have it do logging by simply "decorating" the function definition
@function_log
def do_intersting_stuff(a, b, c, d):
    """This function does interesting stuff"""
    ...
Now when you program calls "some_value = do_interesting_stuff(a, b, c, d)" Python actually does this:
self = args[0]
print(f"La méthode {function.__name__} de la classe {self.__class__} est appelé")
some_value = do_interesting_stuff(a, b, c, d)
I think this is a nice writeup about decorators.

https://www.geeksforgeeks.org/decorators-in-python/
ndc85430 and Frankduc like this post
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020