# -*- coding: utf-8 -*-
"""
Calcolo dello span of control per l'organigramma "Mondo Legno"
Secondo le assunzioni spiegate:
- Il titolare Antonio Lovato ha 3 direttori come diretti.
- I direttori (Produzione, Marketing e vendite, Amministrazione) hanno come diretti
i capi dei rispettivi uffici/reparti.
- I capi reparto/ufficio hanno come diretti i collaboratori
(impiegati/operai/autista).
"""
from collections import defaultdict
# Rappresentiamo l'organigramma come dizionario: manager -> lista di diretti
org = {
"Antonio Lovato (Titolare)": [
"Direttore Produzione",
"Direttore Marketing e vendite",
"Direttore Amministrazione",
],
# Direttore Produzione -> capi reparto/ufficio (ognuno è un manager)
"Direttore Produzione": [
"Capo Ufficio Progettazione",
"Capo Reparto Falegnameria",
"Capo Reparto Montaggio",
"Capo Reparto Verniciatura",
"Capo Reparto Magazzino",
],
# Marketing e vendite
"Direttore Marketing e vendite": [
"Capo Ufficio Marketing - Italia",
"Capo Ufficio Marketing - Estero",
],
# Amministrazione
"Direttore Amministrazione": [
"Capo Ufficio Acquisti",
"Capo Ufficio Contabilità e bilancio",
"Capo Ufficio Banche",
],
# Capi reparto/ufficio con i loro collaboratori (numerici)
"Capo Ufficio Progettazione": ["Impiegato P1", "Impiegato P2", "Impiegato P3"],
# 3
"Capo Reparto Falegnameria": ["Operaio F{}".format(i+1) for i in range(18)],
# 18
"Capo Reparto Montaggio": ["Operaio M{}".format(i+1) for i in range(15)],
# 15
"Capo Reparto Verniciatura": ["Operaio V{}".format(i+1) for i in range(5)],
# 5
"Capo Reparto Magazzino": ["Operaio Mag1", "Operaio Mag2", "Autista Mag"],
# 3
"Capo Ufficio Marketing - Italia": ["Impiegato MI1", "Impiegato MI2"],
# 2
"Capo Ufficio Marketing - Estero": ["Impiegato ME1", "Impiegato ME2",
"Impiegato ME3"],# 3
"Capo Ufficio Acquisti": ["Impiegato A1", "Impiegato A2"],
# 2
"Capo Ufficio Contabilità e bilancio": ["Impiegato C1", "Impiegato C2",
"Impiegato C3"], #3
"Capo Ufficio Banche": ["Impiegato B1", "Impiegato B2"],
# 2
}
# RILEVAZIONE: calcoliamo lo span per ogni manager (chi è presente come chiave in
org)
span_per_manager = {}
for manager, diretti in [Link]():
span_per_manager[manager] = len(diretti)
# Classificazione per livello (basata sulla struttura che abbiamo modellato)
# Livello 0: Titolare
# Livello 1: Direttori
# Livello 2: Capi reparto / ufficio
levels = defaultdict(list)
# mettiamo manualmente i livelli secondo l'organigramma usato
levels[0].append("Antonio Lovato (Titolare)")
levels[1].extend([
"Direttore Produzione",
"Direttore Marketing e vendite",
"Direttore Amministrazione",
])
# tutti gli altri key che non sono a livello 0 o 1 consideriamoli livello 2
for key in [Link]():
if key not in levels[0] and key not in levels[1]:
levels[2].append(key)
# Calcolo medie
def average(lst):
return sum(lst)/len(lst) if lst else 0.0
# span per livello
span_per_level = {}
for lvl, managers in [Link]():
spans = [span_per_manager[m] for m in managers if m in span_per_manager]
span_per_level[lvl] = {
"managers": managers,
"spans": spans,
"media": average(spans)
}
# span medio totale (tra tutti i manager che hanno almeno un diretto)
all_spans = [v for v in span_per_manager.values() if v > 0]
span_medio_totale = average(all_spans)
# Stampa risultati in modo leggibile
print("=== Span of Control per manager ===")
for m, s in span_per_manager.items():
print(f"- {m}: span = {s}")
print("\n=== Span medio per livello ===")
for lvl in sorted(span_per_level.keys()):
info = span_per_level[lvl]
descr = {0: "Titolare (livello 0)", 1: "Direttori (livello 1)", 2: "Capi
reparto/ufficio (livello 2)"}
print(f"{[Link](lvl,'Livello '+str(lvl))}:")
print(f" managers: {info['managers']}")
print(f" spans: {info['spans']}")
print(f" span medio: {info['media']:.3f}")
print(f"\n=== Span medio totale dell'azienda ===\nSpan medio totale:
{span_medio_totale:.3f}")