Introdução
Para efeitos deste artigo, todo o código será em Python.
No seu desafio #48in24, o Exercism está a explorar a forma como a comunidade aborda diferentes desafios de programação. O "Hello, World!" é o exercício mais básico do Exercism e foi considerado demasiado simples para ter um vídeo oficial. Mas não tenho bem a certeza, e achei que podia ser divertido olhar para algumas abordagens mais interessantes a este exercício tão simples!
Conhece o "Hello, World!"
O "Hello, World!" é provavelmente o programa mais famoso do mundo. Praticamente todas as pessoas que aprenderam a programar já o escreveram pelo menos uma vez. A sua simplicidade e a mensagem amigável costumam marcar o primeiro passo no maravilhoso mundo da programação.
No Exercism, recebes uma função chamada hello que devolve "Goodbye, Mars!".
def hello():
return 'Goodbye, Mars!'
A tua tarefa é alterá-la para que devolva "Hello, World!".
A abordagem tradicional
Para começar, temos a abordagem mais simples, e aquela que o Exercism espera que implementes. Basta uma simples alteração da string, de "Goodbye, Mars!" para "Hello, World!", e já a podemos devolver em segurança!
def hello() -> str:
return 'Hello, World'
Abordagens alternativas
Vou resolver este exercício com todos os métodos diferentes de que me lembrei.
Para efeitos de narrativa, vou referir-me a esta função simples como "a máquina", uma máquina cujo único trabalho é devolver uma saudação "Hello, World!".
Vamos ver no que isto dá...!
O join
A máquina já conhece algumas das palavras, mas parece que não as consegue... enfim, juntar numa string.
def hello() -> str:
words = ["Hello", " world!"]
return ",".join(words)
O title
Hoje a bateria da máquina está um pouco fraca: as palavras estão sem energia e as maiúsculas não estão no sítio certo.
def hello() -> str:
words = "hello, world!"
return words.title()
A inversão
De alguma forma, a máquina sabe a saudação, mas há algo nela que parece... ao contrário.
def hello() -> str:
sdrow = "!dlroW ,olleH"
return sdrow[::-1]
Nota: Reverse String é um exercício em destaque do desafio #48in24. Não te esqueças de espreitar as várias abordagens de como fazer isto em diferentes linguagens!
O fatiar e picar
Talvez a máquina precise de mudar o óleo, porque a mensagem de saudação normal parece estar um pouco baralhada.
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]}"
O curry
Uh oh, algumas partes da máquina estão em modo de manutenção. Esqueceu-se da mensagem de saudação e agora só consegue receber a mensagem parte a parte.
def hello(greet: str):
def world(location: str) -> str:
return f"{greet}, {location}!"
return world
hello = hello("Hello")
hello("World")
O ASCII
Entornaste acidentalmente limonada para cima da máquina e agora ela só te mostra estes números estranhos em vez dos caracteres habituais da mensagem.
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)
O dicionário
Viste as notícias e apanhaste uma peça sobre um homem que foi resgatado com um sinal S.O.S. "Talvez a máquina também devesse saber lidar com código Morse!", pensaste tu, sem saber bem porquê. Afinal, o único trabalho dela é devolver a mensagem de saudação...
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(".... . .-.. .-.. --- --..-- / .-- --- .-. .-.. -.. -.-.--"))
O funcional
Como a tua máquina atual está sujeita a alterações e a danos, decides construir uma máquina mais pequena, mas imutável e indestrutível, que faz exatamente a mesma coisa. Sempre que a máquina normal não estiver a funcionar ou estiver a dar problemas, ativa a mais pequena em vez dela. Espera aí, porque é que não passamos simplesmente a usar a mais pequena a partir de agora...
def hi() -> str:
return "Hello, World!"
def hello() -> str:
return hi()
A permutação
Passou uma trovoada forte e a tua pobre máquina sem sorte foi atingida por um raio. Continua a ligar-se, mas agora está a portar-se de forma estranha. Todos os caracteres para montar a mensagem de saudação continuam lá, mas não estão por ordem, e os danos na placa lógica fazem com que a máquina já não consiga acertar na ordem da mensagem. E, para tua sorte, a máquina mais pequena, incrivelmente fiável e indestrutível, que tinhas construído antes, afinal podia ser roubada (sim, desapareceu!). Por isso, decides deixar o teu velho amigo experimentar todas as formas possíveis de baralhar estas letras até formar a mensagem correta. Afinal, são só 13 caracteres e a máquina tem muita memória. Isto deve ser rápido...
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)
A pesquisa
Decidiste atualizar a máquina para a deixar cumprimentar em várias línguas. Mas o ÚNICO trabalho dela é dizer "Hello, World!" em inglês, por isso, na sua confusão, decide descarregar uma infinidade de formas de dizer "Hello, World!", cada uma com maiúsculas e posições ligeiramente diferentes. Isso deixou-te confuso, sem saber qual escolher, mas ao menos estão todas mais ou menos por ordem. Tens de dizer à máquina a forma correta de o escrever, para que ela encontre a frase e volte ao normal (talvez).
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!")
O teu irmão mais novo, que esteve a assistir a tudo, perguntou-te porque é que não apagavas simplesmente toda a confusão e davas à máquina a frase correta para ela se lembrar. Não respondeste e limitaste-te a olhar para ele com má cara.
Com classe
Decides experimentar e afinar a máquina para se comportar de forma diferente conforme o botão que é premido.
Pensaste em torná-la um pouco mais informal, começando a dizer "Hi", mas, como és uma pessoa com classe, decides usar sempre o método hello e tapar o outro.
E apercebes-te de que tens bastante tempo livre para estas coisas...
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()
A recursão
Por alguma razão, achaste que seria engraçado se a máquina ficasse um pouco lenta e só respondesse 10 segundos depois. O teu irmão volta a levantar a questão da lógica por trás desta funcionalidade, porque, segundo ele, és o único que usa a máquina.
import time
def hello(n=10):
if n == 0:
return "Hello, World!"
else:
time.sleep(1)
return hello(n-1)
A aleatoriedade
De repente, um dia cansas-te de ouvir sempre a mesma saudação, por isso decides deixá-la cumprimentar-te uma última vez e reformar a máquina de vez, para nunca mais lhe tocar. Como a máquina está contigo nos bons e maus momentos há muito tempo, decides deixar este encontro final entre "amigos" nas mãos do destino. Ligas a máquina uma última vez e deixas que ela gire...
import random
def hello():
chars = list("Helo,Wrld!")
greeting = ""
while (greeting != "Hello, World!"):
greeting = "".join(random.choices(chars, k=13))
return greeting
O fim
Foi uma viagem atribulada pela minha mente. Não sei se foi útil, mas foi sem dúvida divertido.
Obrigado pela leitura e boa programação!