sábado, 3 de outubro de 2009

Problema 1.20

Neste problema é-nos pedido um programa que teste se um dado inteiro é primo. Um número diz-se primo se os únicos divisores são ele próprio e o número 1. Este exemplo dá-nos a oportunidade de mostrar como as definições nos permitem usar a abstracção e estruturar o código. Na nossa abordagem começamos com a definição:


def primo(n):
conta = divisores_c(n)
if conta == 2:
return True
else:
return False


Como se vê pela solução apresentada (linha 2) delegamos noutra definição, divisores_c(n), a contagem dos divisores. Se esse número for 2 será primo, caso contrário não será. Claro que o programa estará correcto apenas se forem incluídos 1 e o próprio número na contagem, como na solução seguinte.



def divisores_c(n):
"""
Conta os divisores de um número.
"""
conta = 0
for i in range(1, n+1):
if (n % i) == 0:
conta = conta + 1
return conta


Esta solução baseia-se no uso do padrão acumulador. O acumulador do resultado conta é inicializado na linha 5 e actualizado na linha 8. Visualmente temos a seguinte dependência entre as duas definições:





Mas admitamos que queremos optimizar o programa que conta os divisores deixando de fora o caso óbvio dos divisores próprios. Podemos então optar por:


def divisores_c(n):
"""
Conta os divisores de um número.
"""
conta = 0
for i in range(2, n/2 + 1):
if (n % i) == 0:
conta = conta + 1
return conta


Só precisámos mexer na linha 6 do código! Agora necessitamos alterar o nosso programa principal.


def primo(n):
conta = divisores_c(n)
if conta == 0:
return True
else:
return False


E já está!

8 comentários:

  1. Olá, peço desculpa por estar a fazer um comentário off topic mas caso fosse possível gostaria que me respondessem onde estou a errar no exercício 1.18.

    Estou a usar o módulo random para gerar números inteiros e 0 a 100 e foi este código que escrevi.

    ------------------------------------------------
    import random
    def numero(n):
    p = random.randint(0, 100)
    if (n == p):
    print "Acertou! O numero ",p,"Parabéns!"
    else:
    print "Não acertou!"
    print "O numero é",p,"."

    ------------------------------------------------
    O código está devidamente indentado, poderá não aparecer aqui no comentário.

    Na Python Shell não me dá erro nenhum, apenas não devolve resultado ficando "..."

    Obrigado

    ResponderEliminar
  2. Caro Ângelo,

    O programa está bem DEFINIDO. Mas tem que o USAR. Tem que colocar uma chamada ao programa:
    numero(25)
    por exemplo.

    Também podia alterar a instrução de impressão. Nas aulas ainda falaremos disso. Aqui lhe deixo o código.

    import random

    def numero(n):
    p = random.randint(0, 100)
    if (n == p):
    print "Acertou! O número era: %d. Parabéns!" % p
    else:
    print "Não acertou!"
    print "O número era: %d." % p

    numero(25)

    Divirta-se!
    Ernesto Costa

    ResponderEliminar
  3. Obrigado pela resposta, esqueci-me de fazer referencia a isso mesmo. O resultado de "..." dava-me após eu utilizar o programa em questão, apenas não introduzia a 'utilização' no código do programa, e fazia directamente da python shell, ou seja... Corria apenas o programa e de seguida com ele executado, utilizava o programa com um numero qualquer entre 0 e 100 e aí sim não me devolvia resultado e ficava apenas com os tais "..."
    Fiz agora com a solução que o senhor me deu e com a minha novamente e desta vez devolveu resultado!

    ResponderEliminar
  4. Olá de novo.

    fico satisfeito por ter resolvido o problema. Podia fazer do modo que disse, isto é colocar a utilização no shell do Python. Mas para que funcionasse mesmo tinha que fazer importação do seu programa como se faz para os módulos. Imagine que chamou ao seu programa adivinha.py. Admitindo que guardou o programa num local que o Python conhece só tinha que fazer:

    >>> import adivinha
    >>> numero(25)

    Repare que não se coloca a extensão py do progrma.
    EC

    ResponderEliminar
  5. Boa tarde.

    Peço desculpa por estar a comentar no sitio errado, mas a verdade é que não sabia onde o fazer.

    Tenho uma sugestão a fazer. Porque é que o professor não disponibiliza a resolução dos exercícios, ou seja, o professor poderia dar a resolução dos exercícios das semanas passadas.

    Sei que isto irá dar trabalho ao professor mas penso que isto iria ajudar muito os alunos.

    Obrigado.

    ResponderEliminar
  6. Parte dos exercícios são resolvidos nas aulas. Outros encontrarão neste espaço a sua solução. Caso tenha dúvida sobre alguns dos exemplos do passado, deve perguntar nas aulas TP ou PL, comentar aqui no blogue, aparecer no horário de atendimento na quarta de tarde. Deste modo ficam asseguradas as condições para aapfrendizagem.

    O trabalho que eu tenho está feito pois para dar os exercícios das folhas tive que os preparar e resolver. A minha opção é puramente guiada por princípios de pedagogia.

    ResponderEliminar
  7. Oi sou um iniciante em python. Na verdade comecei ontem e estou tentando ser um autodidata. Achei o seu blog e estou gostando muito! Exelente! Estou comentando para pedir que verifique o código da função divisores_c(), pois ela retorna conta=0 para n=4 o que na minha visão está errado. O erro está no uso da função range(2, n/2) que deveria ser range(2, n/2+1) ou range(2, (n/2)+1). Se tudo que falei foi bobagem desculpe o iniciante. Obrigado pela atenção.

    ResponderEliminar
  8. Tem razão! A função range tem três modos de ser usada: range(n), range(n1,n2) e range(n1,n2,n3). O elemento indicado como limite superior nunca é usado.

    Problemas destes acontecem quando achamos que o problema é tão fácil que não merece ser testado :-((.

    ResponderEliminar