Seria legal se profissionais de informática dessem consultas como médicos ou advogados, mas algo nos impede de cobrar por tudo e esse desejo ou intenção de compartilhar ideias nos consome.
Eu participo de vários grupos de Telegram, principalmente sobre Python, um deles é o PyCoding e o outro é o pybr. Normalmente eu leio os grupos quando estou usando meu celular, então nem sempre é possível ajudar com as dúvidas, mas vou tentar separar um pouco de tempo para explorar algumas ideias aqui e lá.
Hoje está tão fácil aprender qualquer coisa que tenho notado uma ansiedade cada vez maior de quem começa a programar de aprender tudo. Em um só mês, algumas pessoas querem aprender Python, SciPi, TensorFlow, Android e o que mais der. Um mês é pouco tempo. Pode-se aprender a programar em períodos relativamente pequenos, mas leva tempo para se acostumar com as novas ideias, linguagens e bibliotecas. O Peter Norvig comentou sobre essa ansiedade no Learn Programming in Ten Years.
Cálculo de médias
Vamos ao interesse do post, a tal consulta.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
print('-------->DESCUBRA SE VOCE FOI APROVADO OU REPROVADO NA ESCOLA<---------\n-AVISO!!!!\n-ANTES DE COMEÇAR,LEMBRRE-SE QUE NAO E PERMITIDO O USO DE (VIRGULAS),APENAS (PONTOS)')
while True:
nome = input('Digite o nome do aluno: ') #input»comando tipo pergunta ex:digite alguma coisa
m1 = input('Digite a media da sua escola: ')
n1 = input('Digite a primeira nota: ') #nao precisa informar o tipo da variavel,da o nome e qqr valor
n2 = input('Digite a segunda nota: ') #mais precisa declarar a variavel sempre
n3 = input('Digite a terceira nota: ')
n4 = input('Digite a quarta nota: ') #variaveis:int==inteiro:str==string e float
media = float(n1)+float(n2)+float(n3)+float(n4) /4
print("A media do aluno e:",(media))
print('Sendo que a media da escola e:',(m1))#print;comando,escreva
try:
media == 2/0
except Exception as erro:
print('Aconteceu algum erro😨 sistema nao reconhece (virgulas),apenas (pontos)'
'\n»» SE VOCE NAO COMETEU NENHUM ERRO DESCONSIDERE ESSA MENSAGEM. ««')
if float(media) >= float(m1): #if{se}
print((nome),'Foi APROVADO!!!')
else: #else{se nao}
print ((nome), 'SE FUDEU!!!Aluno REPROVADO')
print('.')
print('.') #comparaçoes == igual;>= maior ou igual;<=menor ou igual;!= diferente ou igual
print('.') #comparaçoes; and or
print('.')
print('.')
print('.')
print('.')
print('.')
print('.')
print('.')
print('.')
print( '.............................fim do sistema.................................................' )
O colega Wesley enviou dois programas, vou começar pelo mais simples. Primeiro vamos desconsiderar os palavrões, nosso colega é jovem.Uma coisa que gostei muito foi a primeira linha de mensagens. Poucos se preocupam em dizer o que faz o programa, isso é legal! Eu faria apenas uma pequena modificação para que a linha não fosse tão grande.
Como eu cresci nos anos 80, sem letras minúsculas e acentos, é questão de honra corrigir as mensagens.
Nas linhas 7 a 11, os valores das variávies m1, n1, n2, n3 e n4 são solicitados. Como a função input retorna strings, veja que no resto do programa a função float foi utilizada para converter estes valores. Neste caso, o valor convertido deveria ser armazenado diretamente na variável.
Desta forma, simplificamos a linha 12 de forma a facilmente perceber um erro de prioridade de operações. Quando fazemos o cálculo de n1 + n2 + n3 + n4 / 4, sem utilizar parênteses, as operações são realizados por ordem de prioridade, como na matemática. Assim, n4/4 é somado a n1, n2 e n3. Para calcular a média, precisamos de parênteses: (n1 + n2 + n3 + n4) / 4. Agora, a soma das notas é calculada e depois dividida por quatro, como queríamos.
Entre as linhas 15 e 19 acredito que tenha sido apenas um teste. Vou remover para não atrapalhar o entendimento do programa final.
As linhas de 24 a 35 imprimem vários pontos, vou apenas simplificar.
Para terminar, pequenas modificações para usar as f strings do Python 3.6.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
print("""
--------> DESCUBRA SE VOCE FOI APROVADO OU REPROVADO NA ESCOLA <---------
!!!AVISO!!!!
- Antes de começar, lembre-se que não é permitido o uso de vírgulas,
apenas pontos.""")
while True:
nome = input('Digite o nome do aluno: ') #input»comando tipo pergunta ex:digite alguma coisa
m1 = float(input('Digite a média da sua escola: '))
n1 = float(input('Digite a primeira nota: ')) #nao precisa informar o tipo da variavel,da o nome e qqr valor
n2 = float(input('Digite a segunda nota: ')) #mais precisa declarar a variavel sempre
n3 = float(input('Digite a terceira nota: '))
n4 = float(input('Digite a quarta nota: ')) #variaveis:int==inteiro:str==string e float
média = (n1 + n2 +n3 +n4) / 4
print(f"A media do aluno é: {média}")
print(f'Sendo que a média da escola é: {m1}') #print;comando,escreva
if média >= m1: #if{se}
print(f'{nome} - Aluno APROVADO!!!')
else: #else{senao}
print(f"{nome} - Aluno REPROVADO")
print(".\n" * 12)
print("{'fim do sistema':.^80}")
Programa com tkinter
O outro programa é uma interface gráfica, usando tkinter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from tkinter import messagebox
from tkinter import *
janela = tkinter.Tk()
janela.title('MEDIA ALUNO')
janela.configure(background='#000000')
rotulo = tkinter.Label(janela, text='»»»»»DESCUBRA SE VOCE FOI APROVADO OU REPROVADO NA ESCOLA«««««««',bg='#FFB6C1')
rotulo.pack()
rotulo2 = LabelFrame(janela, text="-AVISO!!!!!!!!",bg='#FFB6C1')
rotulo2.pack(fill="both", expand="yes")
rotulo3 = Label(rotulo2, text="-ANTES DE COMEÇAR,LEMBRRE-SE QUE NAO E PERMITIDO O USO DE (VIRGULAS),APENAS (PONTOS)",bg='#FFB6C1')
rotulo3.pack()
rotulonome =tkinter.Label(janela,text='DIGITE O PRIMEIRO NOME DO ALUNO: ',bg='#FFB6C1') # input»comando tipo pergunta ex:digite alguma coisa
rotulonome.pack()
camponome = tkinter.Entry(bd =5)
camponome.pack()
rotulom1 = tkinter.Label(janela,text='DIGITE A MEDIA DA ESCOLA DO ALUNO: ',bg='#FFB6C1')
rotulom1.pack()
campom1 = tkinter.Spinbox(from_=0, to=10)
campom1.pack()
rotulon1 = tkinter.Label(janela,text='DIGITE A PRIMEIRA NOTA: ',bg='#FFB6C1',bd =5) # nao precisa informar o tipo da variavel,da o nome e qqr valor
rotulon1.pack()
campon1 = tkinter.Entry()
campon1.pack()
rotulon2 = tkinter.Label(janela,text='DIGITE A SEGUNDA NOTA: ',bg='#FFB6C1') # mais precisa declarar a variavel sempre
rotulon2.pack()
campon2 = tkinter.Entry(bd =5)
campon2.pack()
rotulon3 = tkinter.Label(janela,text='DIGITE A TERCEIRA NOTA: ',bg='#FFB6C1')
rotulon3.pack()
campon3 = tkinter.Entry(bd =5)
campon3.pack()
rotulon4 = tkinter.Label(janela,text='DIGITE A QUARTA NOTA: ',bg='#FFB6C1') # variaveis:int==inteiro:str==string e float
rotulon4.pack()
campon4 = tkinter.Entry(bd =5)
campon4.pack()
def resultado():
soma1 = float(campon1.get())+float(campon2.get())+float(campon3.get())+float(campon4.get())
soma = soma1 / 4
if soma <= float(campom1.get()):
tkinter.messagebox.showinfo('»RESULTADO«',(camponome.get(),'SE FUDEU!! ALUNO REPROVADO\n A MEDIA DO ALUNO É: ' +str(soma)))
else:
tkinter.messagebox.showinfo('»RESULTADO«',(camponome.get(),'ALUNO APROVADO \n a media do aluno e: ' + str(soma)))
botao = tkinter.Button(janela, text='ENVIAR',bg='#FFB6C1', command=resultado)
botao.pack()
janela.mainloop()
Como os fontes foram postados no Telegram, muito se perde. De cara há um problema com o import da linha 2. Eu parabenizo o Wesley pela coragem de usar o tkinter. É umas das partes do Python que menos gosto, mas que funciona.Deve-se evitar os import * no Python, isso polui o namespace e causa problemas chatos de resolver. No caso do tkinter, é um caso a se pensar, mas nunca misturar o * com os imports de classes e funções individuais.
Uma coisa que salta aos olhos, não, não falo do fundo caladryl, mas da repetição da cor em várias partes do código. Vamos criar uma constante para cor de fundo, melhor, vamos retirar as cores e deixar as cores padrão.
Um outro problema é a validação de valores, acrescentei uma função float_ou_zero que retorna zero caso o valor digitado não possa ser convertido para float.
Usar tkinter sem classes é um tanto confuso, eu particularmente não gosto de ter funções com variáveis globais e de ter definições de funções e variáveis misturadas, mas isso é assunto para outro post.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import tkinter
import tkinter.messagebox
janela = tkinter.Tk()
janela.title('Média Aluno')
rotulo = tkinter.Label(janela, text='»»»»» Descubra se você foi aprovado ou reprovado na escola «««««««')
rotulo.grid(row=0, column=0, columnspan=2)
rotulo2 = tkinter.LabelFrame(janela, text="AVISO")
rotulo2.grid(row=1, column=0, columnspan=2, padx=10, pady=10)
rotulo3 = tkinter.Label(rotulo2, text="Antes de começar, lembre-se que não é permitido o uso de vírgulas, apenas pontos")
rotulo3.grid(row=2, column=0, columnspan=2, padx=10, pady=10)
rotulonome = tkinter.Label(janela, text='Primeiro nome do aluno:') # input»comando tipo pergunta ex:digite alguma coisa
rotulonome.grid(row=3, column=0, sticky=tkinter.E)
camponome = tkinter.Entry()
camponome.grid(row=3, column=1)
rotulom1 = tkinter.Label(janela, text='Média da escola do aluno:')
rotulom1.grid(row=4, column=0, sticky=tkinter.E)
campom1 = tkinter.Spinbox(from_=0, to=10)
campom1.grid(row=4, column=1)
rotulon1 = tkinter.Label(janela, text='Primeira nota:') # nao precisa informar o tipo da variavel,da o nome e qqr valor
rotulon1.grid(row=5, column=0, sticky=tkinter.E)
campon1 = tkinter.Entry()
campon1.grid(row=5, column=1)
rotulon2 = tkinter.Label(janela, text='Segunda nota:') # mais precisa declarar a variavel sempre
rotulon2.grid(row=6, column=0, sticky=tkinter.E)
campon2 = tkinter.Entry()
campon2.grid(row=6, column=1)
rotulon3 = tkinter.Label(janela, text='Terceira nota:')
rotulon3.grid(row=7, column=0, sticky=tkinter.E)
campon3 = tkinter.Entry()
campon3.grid(row=7, column=1)
rotulon4 = tkinter.Label(janela, text='Quarta nota:') # variaveis:int==inteiro:str==string e float
rotulon4.grid(row=8, column=0, sticky=tkinter.E)
campon4 = tkinter.Entry()
campon4.grid(row=8, column=1)
def float_ou_zero(campo):
try:
v = float(campo.get())
except ValueError:
v = 0.0
return v
def resultado():
soma1 = float_ou_zero(campon1) + float_ou_zero(campon2) + float_ou_zero(campon3) + float_ou_zero(campon4)
soma = soma1 / 4
if soma <= float_ou_zero(campom1):
tkinter.messagebox.showinfo('RESULTADO', f'Aluno {camponome.get()} - REPROVADO\nA média do alunoALUNO é: {soma}')
else:
tkinter.messagebox.showinfo('RESULTADO', f"Aluno {camponome.get()} - APROVADO \nA média do aluno é: {soma}")
botao = tkinter.Button(janela, text='ENVIAR', command=resultado)
botao.grid(row=9, column=0, columnspan=2, padx=10, pady=10)
janela.mainloop()
Vejamos como ficou!
Convertendo ints
Outro post interessante foi o de como converter vários ints de uma só vez. O problema inicial era calcular um valor do tipo hh:mm:ss em total de segundos.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
x, y, z = input().split(':')
h = int(x)
m = int(y)
s = int(z)
segundos = h * 3600 + m * 60 + s
print(f"Total de segundos: {segundos}")
O que me chamou atenção foi uma das soluções:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
h, m, s = [int(x) for x in input().split(':')]
Correta, porém, achei que o foco da solução não era mais o problema inicial, mas fazer em menos linhas. De repente, passa o medo de "Perlizar" o Python.
O problema em si, exige validação dos dados. Este é um detalhe importante que é fácil de ser esquecido. Então, ao invés de fazer com menos linhas, vamos adicionar o mínimo de validação.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import datetime
def m_int(*args):
return [int(a) for a in args]
while True:
try:
hs = input("Digite a hora a converter (hh:mm:ss): ")
t = datetime.time(*m_int(*hs.split(":")))
break
except ValueError as v:
print(f"Você digitou um valor inválido: {v}. Redigite.")
segundos = t.hour * 3600 + t.minute * 60 + t.second
print(f"Total em segundos: {segundos}")
Esta solução utiliza o módulo datetime do Python e o tipo time para validar as horas entre 0 e 23, minutos entre 0 e 60 e o mesmo para segundos. Se o usuário entrar um valor errado, terá que redigitar após receber uma mensagem de erro. Embora eu tenha usado a expansão de listas duas vezes em uma só linha (Perlização?), acho que o código ficou relativamente bom.São detalhes, mas que fazem a diferença em programas maiores. Nem sempre escrever em menos linhas é o mais correto ou deveria ser o foco principal da solução de um problema.
Ainda sobra margem para uma outra solução, onde criamos uma função para converter horas, minutos e segundos para total em segundos.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import datetime
def m_int(*args):
return [int(a) for a in args]
def horas_para_segundos(shoras):
t = datetime.time(*m_int(*hs.split(":")))
return t.hour * 3600 + t.minute * 60 + t.second
if __name__ == "__main__":
while True:
try:
hs = input("Digite a hora a converter (hh:mm:ss): ")
segundos = horas_para_segundos(hs)
print(f"Total em segundos: {segundos}")
break
except ValueError as v:
print(f"Você digitou um valor inválido: {v}. Redigite.")
Além da validação (ainda que mínima), ganhamos a flexibilidade de digitar valores como 10, 10:20 ou 10:20:30. O programa que fizemos pode ser importado por outros programas e suas funções reutilizadas, sem perder a funcionalidade inicial se usado como programa principal.
Um comentário:
Olá. Gostei do seu post pois ele ajuda a adquirir oas práticas quando se está trabalhando com Python. De fato é muito útil, principalmente em uma linguagem como o Python em que alguns detalhes são necessários para que o programa funcione e diferentemente de JS em que é possível escrever todo o código como se fosse um texto escrito em qualquer idioma.
A repeito da "ansiedade para aprender", por assim dier, realmente é algo que atrapalha e às vezes até impossibilita o aprendizado da linguagem principalmente se não é muito difundida como HTML ou Shell. É bem interessante ter abordado esse tema.
Pude ver alguns dos seus posts na comunidade brasileira de Python e espero ter a oportunidade de ler o seu livro.
Postar um comentário