Programação

André!

Membro Veterano
Matrícula
4 Março 2021
Mensagens
318
Curso
Eng. Informática
Instituição
Faculdade da Vida
@Pedro D. Jesus @André!:

Penso que, para aquele problema, existe uma solução mais engraçada e potencialmente útil por ser um bocadinho de lateral thinking, que às vezes é a melhor forma de se chegar a uma solução óptima:

Python:
num = int(input("Escreva um inteiro positivo: "))
alg = 0
ret = 0
while num > 0:
  digit = num % 10
  num = num // 10
  if digit % 2 == 1:
  # a % b dá o resto da divisão de a por b
  # Logo, a % 2 é 0 para pares, 1 para ímpares
    ret = ret + digit * 10 ** alg
    # 10 ** alg é 10 elevado a alg
    # Isto, para todos os efeitos,
    # dá-nos o algarismo onde vamos querer escrever
    # o dígito se ele for ímpar
    alg = alg + 1
print("Todos os algarismos ímpares:  ", ret)

Já agora, outro comentário importante: usar o eval é genericamente má ideia, porque introduz falhas de segurança (estás literalmente a permitir que o utilizador injecte código no teu programa!). Se estiveres a usar Python 3.x, como suponho que estejas, o input retorna uma string (que é um conjunto de caracteres, @Pedro D. Jesus, já deves ter ouvido falar, basicamente são aquelas coisas que aparecem "assim" ou 'assim'...), que depois podes converter para o tipo que quiseres usando int(...) ou o que quiseres. Vê, por exemplo: How can I read inputs as numbers?

Visto que, usando o input, nós recebemos uma string, podemos fazer isto trabalhando não o número, mas a string. Isto tem uma grande vantagem: as strings são acessíveis carácter a carácter, o que quer dizer que não precisamos de artifícios matemáticos para aceder a cada dígito, e depois dá para concatenar as strings, o que quer dizer que também não precisamos de truques para garantir que os novos dígitos ficam no sítio certo. E, mais, visto que as strings se armazenam da esquerda para a direita, as coisas aparecem já na ordem que desejaríamos!
Python:
inputstring = input("Escreva um inteiro positivo: ")
out = ""
for character in inputstring:
# Este 'for' é típico de Python e muito útil:
# vai executar uma vez por cada elemento de inputstring,
# com character a corresponder a cada um desses elementos.
# Neste caso, os algarismos do número.
  if (ord(character)-ord('0')) % 2 == 1:
  # ord(character) dá-nos a representação numérica do carácter;
  # por construção, os algarismos estão todos juntos,
  # o que quer dizer que ord('x')-ord('0') == x
  # para um dado algarismo x
  # Uma alternativa ligeiramente menos eficiente
  # seria fazer simpesmente int(character),
  # mas eu prometi que a solução era 'avançada'...
    out = out + character
    # E isto concatena as strings...
print("Todos os algarismos ímpares: ", out)
Pois, esse solução já envolve matemática, já não ia chegar lá por mim mesmo 🤣
 

NemoExNihilo

Membro Catedrático
Colaborador Editorial
Matrícula
5 Agosto 2015
Mensagens
11,852
Curso
Contestação Aplicada
Instituição
Toda e Qualquer Injustiça
Pois, esse solução já envolve matemática, já não ia chegar lá por mim mesmo 🤣
Desculpa, mas o facto de [imath]12345 = 1 \times 10^4 + 2 \times 10^3 + 3 \times 10^2 + 4 \times 10^1 + 5 \times 10^0[/imath] é a simples definição de um sistema numérico de base 10.

Imagina que, em vez de querermos extrair os algarismos do número em base 10, queríamos extrair os bits. Era uma questão de fazer coisas semelhantes, mas, em vez de num % 10 e num // 10, usaríamos num % 2 == num & 1 e num // 2 = num >> 1...
 

André!

Membro Veterano
Matrícula
4 Março 2021
Mensagens
318
Curso
Eng. Informática
Instituição
Faculdade da Vida
Desculpa, mas o facto de [imath]12345 = 1 \times 10^4 + 2 \times 10^3 + 3 \times 10^2 + 4 \times 10^1 + 5 \times 10^0[/imath] é a simples definição de um sistema numérico de base 10.

Imagina que, em vez de querermos extrair os algarismos do número em base 10, queríamos extrair os bits. Era uma questão de fazer coisas semelhantes, mas, em vez de num % 10 e num // 10, usaríamos num % 2 == num & 1 e num // 2 = num >> 1...
Humm pois
 

Pedro D. Jesus

O Revoltado
Matrícula
18 Julho 2018
Mensagens
1,111
Curso
Matemática
Instituição
UMa
Já agora, outro comentário importante: usar o eval é genericamente má ideia, porque introduz falhas de segurança (estás literalmente a permitir que o utilizador injecte código no teu programa!). Se estiveres a usar Python 3.x, como suponho que estejas, o input retorna uma string (que é um conjunto de caracteres, @Pedro D. Jesus, já deves ter ouvido falar, basicamente são aquelas coisas que aparecem "assim" ou 'assim'...), que depois podes converter para o tipo que quiseres usando int(...) ou o que quiseres. Vê, por exemplo: How can I read inputs as numbers?
Mas sem o eval o programa não reconhece a variável que o utilizador mete como sendo um número 🥺
 

NemoExNihilo

Membro Catedrático
Colaborador Editorial
Matrícula
5 Agosto 2015
Mensagens
11,852
Curso
Contestação Aplicada
Instituição
Toda e Qualquer Injustiça
Mas sem o eval o programa não reconhece a variável que o utilizador mete como sendo um número 🥺
É o int(...) que eu referi.

O input (em Python 3.x, que deve ser o que estás a usar) retorna uma string com os caracteres que o utilizador escreveu (ver a minha solução com batota), fazeres int(input(...)) é a forma de converteres essa string num número.
 

Pedro D. Jesus

O Revoltado
Matrícula
18 Julho 2018
Mensagens
1,111
Curso
Matemática
Instituição
UMa
É o int(...) que eu referi.

O input (em Python 3.x, que deve ser o que estás a usar) retorna uma string com os caracteres que o utilizador escreveu (ver a minha solução com batota), fazeres int(input(...)) é a forma de converteres essa string num número.
Mas o int não era para obrigar a ser numero inteiro?
 

NemoExNihilo

Membro Catedrático
Colaborador Editorial
Matrícula
5 Agosto 2015
Mensagens
11,852
Curso
Contestação Aplicada
Instituição
Toda e Qualquer Injustiça
Mas o int não era para obrigar a ser numero inteiro?
Existe um conceito em muitas linguagens de programação que é o chamado tipo, ou type, que, como o nome indica, determina a natureza de uma variável (e, por extensão, a forma como será representada em memória, as operações que se poderão fazer com ela e por aí fora).

Python não é propriamente a melhor linguagem para exemplificar esse conceito devido à forma como trata as suas variáveis, mas ele também existe em Python e é importante compreendê-lo. Podes ver, por exemplo, esta página para descobrires os tipos existentes em Python, e podes consultar por exemplo a página na Wikipédia para leres mais sobre os tipos em geral.

Ora, para aqui, o que nos interessa é que o que o input retorna é um objecto que tem o tipo "string", o que quer dizer que é um conjunto de caracteres seguidos, correspondendo ao que o utilizador escreveu. Quando tu fazes int(...), estás a especificar uma conversão do tipo do que está em ... para o tipo "int", o que corresponde a um número inteiro. Neste caso, estás a especificar uma conversão de string para inteiro, que é precisamente o que queres.

Quando fazes eval, o que estás a fazer é a pedir ao interpretador de Python para pegar no que o utilizador escreveu e interpretar isso como código Python válido. Sucede que, quando introduzes um número inteiro, ele interpreta isso (como seria de esperar) como um número inteiro. No entanto, estás para todos os efeitos a permitir que o utilizador execute código praticamente arbitrário com esse input, o que quer dizer que, a partir desse momento, se o utilizador for malicioso, pode dar-te cabo de todo o programa. Por isso, deve ser evitado.
 

Pedro D. Jesus

O Revoltado
Matrícula
18 Julho 2018
Mensagens
1,111
Curso
Matemática
Instituição
UMa
Quando fazes eval, o que estás a fazer é a pedir ao interpretador de Python para pegar no que o utilizador escreveu e interpretar isso como código Python válido. Sucede que, quando introduzes um número inteiro, ele interpreta isso (como seria de esperar) como um número inteiro. No entanto, estás para todos os efeitos a permitir que o utilizador execute código praticamente arbitrário com esse input, o que quer dizer que, a partir desse momento, se o utilizador for malicioso, pode dar-te cabo de todo o programa. Por isso, deve ser evitado.
Por enquanto apenas estamos a fazer programas e guardar no pc e não expor na net mas vou começar a usar int então em vez de eval, é mais simples.
 

NemoExNihilo

Membro Catedrático
Colaborador Editorial
Matrícula
5 Agosto 2015
Mensagens
11,852
Curso
Contestação Aplicada
Instituição
Toda e Qualquer Injustiça
Por enquanto apenas estamos a fazer programas e guardar no pc e não expor na net mas vou começar a usar int então em vez de eval, é mais simples.
A questão não é só para expor na Internet, acaba por ser um dos elementos básicos do desenho de um bom programa: admite sempre que o input do utilizador pode ser literalmente qualquer coisa, e, em particular, o pior possível para te partir o programa.

Exemplo: esperas um número entre 0 e 9. O utilizador dá como input "hjlmsanadsnkjslkndnlakssahjl".

Às vezes, quando estás bem-disposto, até podes admitir que nem é de propósito. 🙃

Obviamente, quando permites a execução de código mais ou menos arbitrário com o eval, fica ainda mais difícil garantires que não te partem o programa...
 
  • Haha
Reactions: Pedro D. Jesus

Pedro D. Jesus

O Revoltado
Matrícula
18 Julho 2018
Mensagens
1,111
Curso
Matemática
Instituição
UMa
Obviamente, quando permites a execução de código mais ou menos arbitrário com o eval, fica ainda mais difícil garantires que não te partem o programa...
Já percebo melhor, não te preocupes, vou deixar o "eval" de lado. Hoje a professora mostrou 2 exercicios com soluções dela meios... estranhos... nem percebi e quando cheguei a casa para copiar o primeiro, deu errado?? Mas pronto, amanhã vou rever com um colega cenas que tenho dúvidas já que a prof vai faltar à aula 😅 Já tenho 5 horas de algebra para repor e agora 1h30 de paradigmas da programação 😂
 

André!

Membro Veterano
Matrícula
4 Março 2021
Mensagens
318
Curso
Eng. Informática
Instituição
Faculdade da Vida
Já percebo melhor, não te preocupes, vou deixar o "eval" de lado. Hoje a professora mostrou 2 exercicios com soluções dela meios... estranhos... nem percebi e quando cheguei a casa para copiar o primeiro, deu errado?? Mas pronto, amanhã vou rever com um colega cenas que tenho dúvidas já que a prof vai faltar à aula 😅 Já tenho 5 horas de algebra para repor e agora 1h30 de paradigmas da programação 😂
Se na execução dela resultou e no teu não, pode ser um problema qualquer de identação, o python é um bocado manhoso nisso
 
  • Like
Reactions: Pedro D. Jesus

NemoExNihilo

Membro Catedrático
Colaborador Editorial
Matrícula
5 Agosto 2015
Mensagens
11,852
Curso
Contestação Aplicada
Instituição
Toda e Qualquer Injustiça
Se na execução dela resultou e no teu não, pode ser um problema qualquer de identação, o python é um bocado manhoso nisso
O mítico "but it works on my machine!" é das técnicas mais úteis para a programação em grupo, acho bem que a professora já os esteja a ensinar desde o início. 😉
 

Pedro D. Jesus

O Revoltado
Matrícula
18 Julho 2018
Mensagens
1,111
Curso
Matemática
Instituição
UMa
1635348338261.png
def funçao_cinco(n):
while n==5:
print("True")
n=int(input("Esc"))

while n!=5:
print("False")
n=int(input("Esc"))

Isto está correto mas eu queria tornar isto um loop, ou seja, sempre a perguntar e depois dando resposta, e funciona mas depois quando volto a meter 5, nem dá resposta. Exemplo:
1635348406501.png
1635348435441.png
E reparei agora se meter 5, mudar para diferente de 5, e voltar a meter 5, o programa não me responde mais... alguém sabe como resolver isto?
 

roby

Membro
Matrícula
13 Agosto 2021
Mensagens
45
Olá @Pedro D. Jesus , vou tentar dar uma ajuda.
Pelo que percebi pelo enunciado, o exercício pede-te uma função que retorna True ou False, ou seja, uma função que retorna um Boolean. (tu só estas a printar se é ou não!)
O que tu estás a tentar fazer faz sentido sim, mas seria muito melhor se fizesses o loop a pedir o número fora da função, ou seja, vais pedindo um número ao utilizador e usas a função para esse número, e não usares uma função para pedir todos os números.

Por exemplo, com um for loop de 0 a 5 a verificar se algum dos números é 5.
Python:
def cinco(n):
    return n == 5

for i in range(6):
    print(cinco(i))

Output:
Código:
False
False
False
False
False
True

Espero que isto te consiga ajudar.
 
  • Like
Reactions: Pedro D. Jesus

Pedro D. Jesus

O Revoltado
Matrícula
18 Julho 2018
Mensagens
1,111
Curso
Matemática
Instituição
UMa
Olá @Pedro D. Jesus , vou tentar dar uma ajuda.
Pelo que percebi pelo enunciado, o exercício pede-te uma função que retorna True ou False, ou seja, uma função que retorna um Boolean. (tu só estas a printar se é ou não!)
O que tu estás a tentar fazer faz sentido sim, mas seria muito melhor se fizesses o loop a pedir o número fora da função, ou seja, vais pedindo um número ao utilizador e usas a função para esse número, e não usares uma função para pedir todos os números.

Por exemplo, com um for loop de 0 a 5 a verificar se algum dos números é 5.
Python:
def cinco(n):
    return n == 5

for i in range(6):
    print(cinco(i))

Output:
Código:
False
False
False
False
False
True

Espero que isto te consiga ajudar.
Demasiado avançado para mim essa parte do range 😅 Ainda nem demos isso na aula ahah Preferia resolver usando o meu método para puder compreender.
 

roby

Membro
Matrícula
13 Agosto 2021
Mensagens
45
Demasiado avançado para mim essa parte do range 😅 Ainda nem demos isso na aula ahah Preferia resolver usando o meu método para puder compreender.
Já deram while loops mas ainda não deram for loops? Esse for loop simplesmente vai de 0 até 5 e chama a função em cada loop...
Anyways o resto da minha explicação "não tem nada que não tenhas dado na aula". Fazes o teu while loop de pedir numeros fora da função cinco(), porque o objetivo da função (pelo enunciado) é só retornar True se o argumento for 5 ou False otherwise.
Post automatically merged:

Also se queres ajuda a resolver o teu código, manda o código dentro de code blocks, pelo teu código não se percebe identação (fator importante em python)
O problema no teu código é a maneira de como estás a utilizar os while loops.

E reparei agora se meter 5, mudar para diferente de 5, e voltar a meter 5, o programa não me responde mais... alguém sabe como resolver isto?
Isto acontece porque, quando metes 5, ele entra no primeiro loop e diz que é verdade sim, depois quando metes diferente de 5 ele sai do 1º loop e entra no segundo, e depois quando metes 5 outra vez ele sai do loop e a função acaba...
 
Última edição:
  • Like
Reactions: Pedro D. Jesus

Pedro D. Jesus

O Revoltado
Matrícula
18 Julho 2018
Mensagens
1,111
Curso
Matemática
Instituição
UMa
Also se queres ajuda a resolver o teu código, manda o código dentro de code blocks, pelo teu código não se percebe identação (fator importante em python)
O problema no teu código é a maneira de como estás a utilizar os while loops.
O que é isso?
Já deram while loops mas ainda não deram for loops?
Demos for mas tipo, for e in i, nos tuplos; range e isso ainda não.
 

André!

Membro Veterano
Matrícula
4 Março 2021
Mensagens
318
Curso
Eng. Informática
Instituição
Faculdade da Vida
O que é isso?
Indentação é a maneira como o teu código está formatado, os espaçamentos, a estrutura e esse tipo de coisas, que no python é muito importante.
Por exemplo, isto é um código com uma indentação:
Python:
def funcao():
    while numero < 10
        fazQualquercoisa = fazQualquercoisa + 1
        print("Olá")
    print("Adeus")

Já isto, é uma horrível indentação, que provavelmente dará erro no python:
Python:
def funcao():
while numero < 10
fazQualquercoisa = fazQualquercoisa + 1
print("Olá")
print("Adeus")

E os code blocks é precisamente isto que fiz em cima, meter o código dentro dessas caixinhas, que para isso basta vires aqui:
1635368791574.png
 

dariodias97

Membro
Matrícula
6 Janeiro 2021
Mensagens
68
Curso
(L) Eng Mec Auto
Instituição
ISEP
@Pedro D. Jesus
Tenta perceber o que acontece a cada momento no teu código. Nas primeiras vezes que escreves programas nem sabes bem o que fazem, dá jeito ir vendo passo a passo. Mais tarde vais percebendo melhor os códigos que escreves.
No teu código fazes um while que decide que quando n for diferente de 5 avanças para o 2º while e neste quando n for igual a 5 o programa acaba. Acho que procuras um while que inclua todo o programa ou toda a função.
Mas neste caso o enunciado pede que a função retorne True ou False, não pede print. A repetição só faz sentido com input + print. A função cinco(n) seria simplesmente:
Python:
def cinco(n):
    return n == 5

Se queres repetir prints podes fazer algo como:
Python:
def cinco(n):
    return n == 5

while True:
    print(cinco(int(input(""))))
Se quiseres que este último programa pare em algum momento, precisas de inventar uma maneira de interromper o while (ou fazer um for loop).
 
  • Fabulous
Reactions: Pedro D. Jesus

Pedro D. Jesus

O Revoltado
Matrícula
18 Julho 2018
Mensagens
1,111
Curso
Matemática
Instituição
UMa
@Pedro D. Jesus
Tenta perceber o que acontece a cada momento no teu código. Nas primeiras vezes que escreves programas nem sabes bem o que fazem, dá jeito ir vendo passo a passo. Mais tarde vais percebendo melhor os códigos que escreves.
No teu código fazes um while que decide que quando n for diferente de 5 avanças para o 2º while e neste quando n for igual a 5 o programa acaba. Acho que procuras um while que inclua todo o programa ou toda a função.
Mas neste caso o enunciado pede que a função retorne True ou False, não pede print. A repetição só faz sentido com input + print. A função cinco(n) seria simplesmente:
Python:
def cinco(n):
    return n == 5

Se queres repetir prints podes fazer algo como:
Python:
def cinco(n):
    return n == 5

while True:
    print(cinco(int(input(""))))
Se quiseres que este último programa pare em algum momento, precisas de inventar uma maneira de interromper o while (ou fazer um for loop).
Eu sei o que o while faz mas ainda não sabia usar mesmo mais do que um, pensei que dois eram suficientes mas já consegui perceber, obrigado :D