Introduzione
Ai fini di questo articolo, tutto il codice sarà in Python.
Nella loro challenge #48in24, Exercism esplora come la community affronta le diverse challenge di programmazione. «Hello, World!» è l'esercizio più basilare di Exercism ed è stato giudicato troppo semplice per dedicargli un video ufficiale. Ma non ne sono così sicuro, e ho pensato che potesse essere divertente dare un'occhiata ad approcci più interessanti a questo semplice esercizio!
Conosciamo «Hello, World!»
«Hello, World!» è probabilmente il programma più famoso al mondo. Praticamente chiunque abbia imparato a programmare l'ha scritto almeno una volta. La sua semplicità e il messaggio amichevole spesso rappresentano il primo passo nel meraviglioso mondo della programmazione.
Su Exercism ti viene fornita una funzione di nome hello che restituisce «Goodbye, Mars!».
def hello():
return 'Goodbye, Mars!'
Il tuo compito è modificarla perché restituisca invece «Hello, World!».
L'approccio tradizionale
Per prima cosa abbiamo l'approccio più semplice, quello che Exercism spera che tu implementi. Con un semplice cambio della stringa da «Goodbye, Mars!» a «Hello, World!», ora possiamo restituirla senza problemi!
def hello() -> str:
return 'Hello, World'
Approcci alternativi
Risolverò questo esercizio usando tutti i metodi diversi che mi sono venuti in mente.
Per ragioni narrative, chiamerò questa semplice funzione «la macchina», una macchina il cui unico compito è restituire un saluto «Hello, World!».
Vediamo dove ci porta...!
Il join
La macchina conosce già alcune delle parole, ma sembra non riuscire a... ah, ehm... metterle insieme.
def hello() -> str:
words = ["Hello", " world!"]
return ",".join(words)
Il titolo
Oggi la batteria della macchina è un po' scarica: tutte le parole mancano di energia e non vengono maiuscolate come si deve.
def hello() -> str:
words = "hello, world!"
return words.title()
L'inversione
La macchina in qualche modo conosce il saluto, ma qualcosa in esso sembra un po'... al contrario.
def hello() -> str:
sdrow = "!dlroW ,olleH"
return sdrow[::-1]
Nota: Reverse String è un esercizio in evidenza per la challenge #48in24. Non dimenticare di dare un'occhiata ai vari approcci su come farlo in linguaggi diversi!
Il taglia e cuci
Forse la macchina ha bisogno di un cambio d'olio, visto che il normale messaggio di saluto sembra un po' mescolato.
def hello() -> str:
w = "Holld, Werlo!"
return f"{w[0]}{w[8]}{w[2:4]}{w[1]}{w[5:8]}{w[-2]}{w[-4:-2]}{w[4]}{w[-1]}"
Il curry
Oh oh, alcune parti della macchina sono in manutenzione. Ha dimenticato il messaggio di saluto e ora può accettarlo solo una parte alla volta.
def hello(greet: str):
def world(location: str) -> str:
return f"{greet}, {location}!"
return world
hello = hello("Hello")
hello("World")
L'ASCII
Hai versato per sbaglio della limonata sulla macchina e ora ti mostra solo questi strani numeri invece dei soliti caratteri del messaggio.
def hello() -> str:
ascii = [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33]
return ''.join(chr(value) for value in ascii)
Il dizionario
Hai guardato il telegiornale e hai visto un servizio su un uomo salvato grazie a un segnale S.O.S. «Forse la macchina dovrebbe saper gestire anche il codice Morse!», hai pensato, anche se non sei sicuro del perché. Il suo unico compito è restituire il messaggio di saluto...
def hello(morse) -> str:
morse_code = {
"...." : "H",
"." : "e",
".-.." : "l",
"---" : "o",
"--..--": ",",
"/" : " ",
".--" : "W",
".-." : "r",
"-.." : "d",
"-.-.--": "!"
}
return "".join(morse_code[value] for value in morse.split())
print(hello(".... . .-.. .-.. --- --..-- / .-- --- .-. .-.. -.. -.-.--"))
Il funzionale
Dato che la tua macchina attuale è soggetta a modifiche e danni, decidi di costruirne una più piccola, ma immutabile e indistruttibile, che fa esattamente la stessa cosa. Ogni volta che la macchina normale non funziona o fa i capricci, attiverà quella più piccola. Aspetta un attimo, perché non usiamo direttamente quella più piccola da adesso in poi?
def hi() -> str:
return "Hello, World!"
def hello() -> str:
return hi()
La permutazione
È passato un forte temporale e la tua povera sfortunata macchina è stata colpita da un fulmine. Si accende ancora, ma ora si comporta in modo strano. Tutti i caratteri per comporre il messaggio di saluto ci sono ancora, ma non sono in ordine, e i danni alla scheda logica fanno sì che la macchina non riesca più a metterli nell'ordine giusto per il messaggio. E, naturalmente, la macchinetta incredibilmente affidabile e indistruttibile che avevi costruito prima si è rivelata in realtà rubabile (sì, è sparita!). Quindi decidi di lasciare che il tuo buon vecchio amico provi in tutti i modi possibili a rimescolare queste lettere fino a ottenere il messaggio corretto. Dopotutto sono solo 13 caratteri e la macchina ha molta memoria. Dovrebbe essere veloce...
from itertools import permutations
def hello() -> str:
chars = ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!']
all_permutations = permutations(chars)
for perm in all_permutations:
if ("".join(perm) == "Hello, World!"):
return ''.join(perm)
La ricerca
Hai deciso di aggiornare la macchina per permetterle di salutare in lingue diverse. Ma il suo UNICO compito è dire «Hello, World!» in inglese, così, nella sua confusione, decide di scaricare un fantastiliardo di modi di dire «Hello, World!», ognuno con caratteri maiuscoli e posizioni leggermente diversi. Questo ti ha lasciato confuso, senza sapere quale scegliere, ma almeno sono tutti in un certo ordine. Devi dire alla macchina la formulazione corretta, così può trovare la frase e tornare normale (forse).
def hello(my_fav_phrase) -> str:
combinations = [
"HELLO, WORLD!",
# many many many items later,
"hello, world!"
]
lower = 0
upper = len(combinations)
while lower <= upper:
mid = (lower + upper) // 2
mid_val = combinations[mid]
if mid_val == my_fav_phrase:
return combinations[mid]
elif mid_val < my_fav_phrase:
lower = mid + 1
else:
high = mid - 1
return "Error: Can't find {my_fav_phrase}"
hello("Hello, World!")
Tuo fratello, che ha assistito a tutta la scena, ti ha chiesto perché non avessi semplicemente cancellato tutto quel pasticcio e poi dato alla macchina la frase corretta da ricordare. Non gli hai risposto e ti sei limitato a fulminarlo con lo sguardo.
La classe
Decidi di sperimentare e modificare la macchina perché si comporti diversamente a seconda del pulsante premuto.
Avevi pensato di renderla un po' più informale, facendole dire «Hi», ma, essendo una persona con classe, decidi di usare sempre e solo il metodo hello e di coprire l'altro con del nastro adesivo.
Ti rendi conto di avere parecchio tempo da perdere per queste cose...
class Greeting:
location = "World"
def __init__(self) -> None:
pass
def hello(self):
return f"Hello, {self.location}!"
def hi(self):
return f"Hi, {self.location}!"
salutation = Greeting()
salutation.hello()
La ricorsione
Per qualche motivo, hai deciso che sarebbe stato divertente se la macchina rallentasse un po' e rispondesse solo con 10 secondi di ritardo. Tuo fratello solleva ancora una volta la questione della logica dietro questa funzionalità, perché secondo lui sei l'unico a usare la macchina.
import time
def hello(n=10):
if n == 0:
return "Hello, World!"
else:
time.sleep(1)
return hello(n-1)
La casualità
All'improvviso, un giorno ti stanchi di sentire sempre lo stesso saluto, così decidi di lasciarti salutare un'ultima volta e di mandare in pensione la macchina per sempre, senza toccarla mai più. Poiché la macchina ti è stata accanto nella buona e nella cattiva sorte per molto tempo, decidi di lasciare questo ultimo incontro tra «amici» nelle mani del destino. La accendi un'ultima volta e la lasci girare...
import random
def hello():
chars = list("Helo,Wrld!")
greeting = ""
while (greeting != "Hello, World!"):
greeting = "".join(random.choices(chars, k=13))
return greeting
La fine
È stato un viaggio selvaggio nella mia mente. Non sono sicuro che sia stato utile, ma di sicuro è stato divertente.
Grazie per aver letto e buona programmazione!