Somar output de uma função

Secção dedicada à linguagem de programação favorita dos quarkianos: Python!

Somar output de uma função

Mensagempor ruifm em Quinta Fev 02, 2012 4:18 pm

Estava a resolver problemas do PE, mas só consegui alguns copiando o output para o EXCEL e somando (função SUM), o que é por vezes penoso quando o output tem cerca de 1000 parcelas.
Quando falo do out put de uma função é algo do estilo:
Código: Seleccionar Todos
def count(n):
if n<100:
    count(n+1)
    print n
count(0)

Tentei usar a built-in function SUM no python mas ela só funciona para strings e listas. Tentei transformar o output da função numa lista, o que também não funcionou.
Ao que parece:
Código: Seleccionar Todos
type(count())
<Non Type>

alguem tem uma forma de somar o output de uma função sem ser não usar uma função (e.g. usar um while block)?

Ah, mais uma coisa. O python dá-me um Runtime Error cada quando uso recursion um certo número de vezes. Ao que parece esse número de vezes é exactamente 977, ou seja, ele funciona sem erro se fizer recursion 977 vezes, e dá-me Runtime error se eu lhe mandar fazer 978 vezes. (O meu PC não é da idade da Pedra, tenho um Quadcore 2.3, e 2 GB de RAM livres)
"Everything is determined, the beginning as well as the end, by forces over which we have no control." - Albert Einstein
Avatar do utilizador
ruifm
down-Quark!
down-Quark!
 
Mensagens: 205
Registado: Segunda Jan 16, 2012 12:04 am
Localização: Lisboa - IST

Re: Somar output de uma função

Mensagempor Bruno Oliveira em Quinta Fev 02, 2012 4:49 pm

Depende da forma como montares a chamada recursiva da função e como a interligas com o resto do código!

Mas, se dizes que a função sum pode (e tens toda a razão!) ser usada em listas, então porque não metes o output da tua função numa lista? :roll:

Se quiseres mete aqui a função em causa, pode ser mais fácil ajudar!

Bruno

PS: Qual é o problema do Project Euler?
e^{ix}=cos x + i\,sin x
Avatar do utilizador
Bruno Oliveira
top-Quark!
top-Quark!
 
Mensagens: 1553
Registado: Quarta Nov 14, 2007 10:19 pm
Localização: Lisboa

Re: Somar output de uma função

Mensagempor ruifm em Quinta Fev 02, 2012 5:00 pm

Bruno Oliveira Escreveu:Depende da forma como montares a chamada recursiva da função e como a interligas com o resto do código!

Mas, se dizes que a função sum pode (e tens toda a razão!) ser usada em listas, então porque não metes o output da tua função numa lista? :roll:

Se quiseres mete aqui a função em causa, pode ser mais fácil ajudar!

Bruno

PS: Qual é o problema do Project Euler?

são os 2 primeiros. Eu já os resolvi, mas queria faze-los sem exportar o output para o EXCEL...
Código: Seleccionar Todos
def count(n):
    if n<=977:
        count(n+1)
        if n%3==0 or n%5==0:
            print n
count(0)
def count2(n):
    if 977<n<=999:
        count2(n+1)
        if n%3==0 or n%5==0:
            print n
count2(978)

aqui eu fiz a mesma função 2 vezes para resolver aquele problema do overflow.
para transformar em string eu tentei fazer str(count(0)) mas não funcionou, quando fiz type(count(0)) continuou a aparecer non type. Que outras formas ha de passar algo para string?
"Everything is determined, the beginning as well as the end, by forces over which we have no control." - Albert Einstein
Avatar do utilizador
ruifm
down-Quark!
down-Quark!
 
Mensagens: 205
Registado: Segunda Jan 16, 2012 12:04 am
Localização: Lisboa - IST

Re: Somar output de uma função

Mensagempor jap em Quinta Fev 02, 2012 5:41 pm

Hum??? :roll:
Não percebi bem o teu problema. Acho que complicaste aquilo que é muito simples:

Código: Seleccionar Todos

"""
Project Euler
Problem #1
@jap 1 /1 /2012
"""


if __name__=="__main__":

    NMAX = 1000
   
    n = 1
    s = 0

    while n < NMAX:
        if not (n % 3 and n% 5):
            s += n
        n += 1
    print "The sum is",s


BTW, a tua função count não devolve nada, por isso o tipo do objecto devolvido é "None". Também por isso é que não podes transformá-lo numa string!

Ex:

Código: Seleccionar Todos
def count(n):
      print n


é uma função que não devolve qualquer objecto, apenas executa uma acção, neste caso uma "impressão". Daí que, por exemplo,

Código: Seleccionar Todos
type(count(5))


dê como resultado "None"

Já a seguinte função

Código: Seleccionar Todos
def count(n):
     return n

devolve um obecto e o tipo deste objecto é o tipo de n (se n for um inteiro será um inteiro).

Além disso a tua função recursiva "count" não funciona porque está errada, não é problema do limite de recursão do Python! :lol:

Diz-me o que pretendes que a tua função "count" faça que eu ensino a escrever-te essa função. :wink:

Se eu bem percebi, a tua linha algorítmica pretende implementar aquilo que em pitónico se desgina de um objecto gerador (ou iterador)... :D. O python tem formas muito cool de criar geradores...
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6790
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Re: Somar output de uma função

Mensagempor ruifm em Quinta Fev 02, 2012 7:16 pm

eu queria que ela fizesse print de todos os multiplos de 3 e 5 até 1000. Funcionava bem ate 977, mas a partir dai da Runtime error.
depois queria que os somasse através da função SUM. Como ela só funciona para strings e int e float, eu tentei fazer concatenate (str()) à função, o que não resultou em nada.
Realmente essa forma é muito mais simples, arranjar uma iteration só para a soma (s += n) e depois fazer print. bem visto :hands:
eu agora ando numa "function fever" porque estou a ler um tutorial que foi recomendado aqui no forum, "Thinking like a Computer Scientist, Learning Python", e eles são muito apologistas das funções, ensinam a fazer tudo com funções, fartam-se de enumerar as suas vantagens, etc... E eu decidi experimentar no PE, só que deparei-me logo com o problema de somar o output :S.
Mas eu não percebi a diferença entre:
Código: Seleccionar Todos
print n

e
Código: Seleccionar Todos
return n

numa função. O "print" imprime o n, e o return devolve o valor de n. Não é a mesma coisa? Só com o return é que o valor de n passa a ser do tipo int?
"Everything is determined, the beginning as well as the end, by forces over which we have no control." - Albert Einstein
Avatar do utilizador
ruifm
down-Quark!
down-Quark!
 
Mensagens: 205
Registado: Segunda Jan 16, 2012 12:04 am
Localização: Lisboa - IST

Re: Somar output de uma função

Mensagempor jap em Quinta Fev 02, 2012 7:27 pm

Rui,

Sim, pode-se fazer tudo com funções, e isto até é uma boa ideia que levada ao extremo resulta naquilo que se designa de programação funcional (procura aqui no fórum por este nome que encontras vários exemplos).

Então vamos por partes.

Há uma diferença substancial entre

Código: Seleccionar Todos
def f(n):
   print n



e

Código: Seleccionar Todos
def f(n):
   return n


No primeiro caso a função executa uma acção que é a impressão (digamos no ecrã) da representação do objecto de nome n (no caso o objecto com este nome poderá ser um número). Esta função não cria nenhum objecto, apenas executa uma acção.

Já no segundo exemplo, a função cria um objecto que é devolvido para ser usado no programa principal (para aquilo que ti quiseres). Portanto há, de facto, uma grande diferença. No segundo caso há um objecto que foi criado, colocado numa zona de memória, à tua disposição (é só pedir ao gestor do armazém para o ir buscar :lol:). Já no 1º caso, a função não cria e não nos devolve objecto nenhum. Na realidade, não é bem assim.Todas as funções em Python têm de devolver um objecto, pelo que se uma função não devolve um objecto explicitamente com a instrução "return", o python devolve um objecto por defeito, mesmo sem nós pedrimos, que é o objecto nulo (None). Este objecto não aparece quando se executa a função, mas ele está lá. Queres uma prova: Vê o resultado de

Código: Seleccionar Todos
def f(n):
   print n

x = f(5)

print x


O resultado será:

Código: Seleccionar Todos
>>> x = f(5)
5
>>> print x
None
>>>


Percebeste? :roll:
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6790
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Re: Somar output de uma função

Mensagempor Bruno Oliveira em Quinta Fev 02, 2012 7:31 pm

Não necessariamente, Rui!

Existe uma distinção bem definida para a diferença entre os statement return e print.

Ao usares o statement return, podes atribuir-lhe um identificador, e guardar na memória o valor retornado, isto é:

Se tiveres uma função que te retorne um valor, podes depois usar esse valor noutra expressão, ao passo que ao usares o statement print não podes fazer isso, visto que o "argumento" que for passado ao statement print, é directamente enviado para o ecrã, e não fica disponível para mais operações!

Costuma-se chamar função, se uma função retornar efectivamente algum valor, ou procedimento, caso se limite a enviá-lo para a saída-padrão, esta distinção pode ser algo tricky no ínicio, mas, é muito importante!
e^{ix}=cos x + i\,sin x
Avatar do utilizador
Bruno Oliveira
top-Quark!
top-Quark!
 
Mensagens: 1553
Registado: Quarta Nov 14, 2007 10:19 pm
Localização: Lisboa

Re: Somar output de uma função

Mensagempor jap em Quinta Fev 02, 2012 7:33 pm

Ver meu post acima! :lol:

Tecnicamente todas as funções do Python devolvem um objecto. Se não houver uma instrução return no corpo da função, ela devolverá o objecto None! :mock:
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6790
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Re: Somar output de uma função

Mensagempor Bruno Oliveira em Quinta Fev 02, 2012 7:35 pm

jap Escreveu:Ver meu post acima! :lol:

Tecnicamente todas as funções do Python devolvem um objecto. Se não houver uma instrução return no corpo da função, ela devolverá o objecto None! :mock:


Upps! :oops:

Nem me apercebi que o prof. já tinha respondido :P

Pois, isto são as minhas más influências do C a falarem mais alto! :lol:

Mas, é excelente o fórum estar finalmente mais animado!! :D E em particular a secção Pitónica! :hands:
e^{ix}=cos x + i\,sin x
Avatar do utilizador
Bruno Oliveira
top-Quark!
top-Quark!
 
Mensagens: 1553
Registado: Quarta Nov 14, 2007 10:19 pm
Localização: Lisboa

Re: Somar output de uma função

Mensagempor jap em Quinta Fev 02, 2012 7:42 pm

Mais logo vou explicar aqui como se implementa a ideia original do Rui (julgo que percebi o que ele queria fazer! :inocent: ) que é o que tecnicamente se designa por um "gerador" - ele tentou implementá-lo de forma recursiva o que é uma ideia muito...má, em termos práticos! :lol: Mas os geradores pitónicos são a solução para o "problema de memória" que o Rui encontrou. Os geradores são muito giros e poderosos, mas são um tópico relativamente hardcore do python, muito pouco conhecidos mesmo entre os pitonistas.

Stay tuned!
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6790
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Re: Somar output de uma função

Mensagempor ruifm em Quinta Fev 02, 2012 7:42 pm

percebi :)
então quando desenvolvemos um programa convém usar os 2? o print para sabermos o que está a acontecer e o return para a funcão "funcionar"?

eu já corrigi o meu codigo, para apenas devolver o resultado:
Código: Seleccionar Todos
def count(n):
    s=0
    while n<1000:
        if n%3==0 or n%5==0:
            s += n
        n += 1
        if n>=1000:
            return s

mas ainda não percebo porque é que eu tinha aquele runtime error, se fizesse a recursão 978 vezes, e não o obtia se o fizesse só 977:
Código: Seleccionar Todos
def crash(n):
    if n<=977:
        crash(n+1)
        if n%3==0 or n%5==0:
            print n

se em vez de 977 pusermos 978: erro... curioso ;)
já agora, no codigo acima, há alguma diferença entre usar if ou while? se a condição tiver sempre a ocorrer, então o if funciona como while, não?
e qual é a diferença entre um iterador do tipo n += 1 e uma recursão function(n+1)?
desculpem pelas duvidas basicas, só que não encontro nada que explique de forma clara a diferença.
"Everything is determined, the beginning as well as the end, by forces over which we have no control." - Albert Einstein
Avatar do utilizador
ruifm
down-Quark!
down-Quark!
 
Mensagens: 205
Registado: Segunda Jan 16, 2012 12:04 am
Localização: Lisboa - IST

Re: Somar output de uma função

Mensagempor jap em Quinta Fev 02, 2012 7:46 pm

ruifm Escreveu:desculpem pelas duvidas basicas, só que não encontro nada que explique de forma clara a diferença.


Há uma excelente razão para o teu crash, sim! :lol:

Vou explicar mais logo (vê o meu post anterior).

BTW o teu count fica melhor escrito assim:

Código: Seleccionar Todos
def count(n):
    s=0
    while n<1000:
        if n%3==0 or n%5==0:
            s += n
        n += 1
    return s


O if n >= 1000 não está lá a fazer nada... :lol: repara na indentação desta nova versão. Quando acaba o ciclo while, basta fazer return (se ele acabou é porque n >=1000, não é verdade?)
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6790
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Re: Somar output de uma função

Mensagempor ruifm em Quinta Fev 02, 2012 7:56 pm

good point :lol:
curiosidade: quanto mais simples/curto/conciso fica o script, mais rapido fica o programa?
"Everything is determined, the beginning as well as the end, by forces over which we have no control." - Albert Einstein
Avatar do utilizador
ruifm
down-Quark!
down-Quark!
 
Mensagens: 205
Registado: Segunda Jan 16, 2012 12:04 am
Localização: Lisboa - IST

Re: Somar output de uma função

Mensagempor Bruno Oliveira em Quinta Fev 02, 2012 8:36 pm

Acho que isso é um pouco relativo :roll:

Um programa curto, mal escrito, pode demorar mais do que um programa um pouco maior mas mais bem estruturado!!

Aqui, a questão de rapidez de execução do código, está intimamente ligada ao desenvolvimento de um algoritmo eficiente (então no PE ainda mais verdade isto se torna, sobretudo nos problemas mais avançados), mas isso não deve ser algo com que te preocupes para já. Conhecer bem as estruturas de dados de uma linguagem e o estilo de programação dessa mesma linguagem, é algo muito importante para poder escrever bom código (juntamente com uma grande capacidade de análise matemática, no caso do PE), mas tem de se começar por algum lado :wink:

Eu próprio estou curioso em aprender sobre geradores, nunca me debruçei como deve de ser sobre eles, mas sei que são memory usage friendly :P
e^{ix}=cos x + i\,sin x
Avatar do utilizador
Bruno Oliveira
top-Quark!
top-Quark!
 
Mensagens: 1553
Registado: Quarta Nov 14, 2007 10:19 pm
Localização: Lisboa

Re: Somar output de uma função

Mensagempor Tharis em Quinta Fev 02, 2012 8:48 pm

A razão do teu crash tem a ver com o abuso de memória. O Prof. jap depois deve explicar melhor, por isso digo-te apenas que a tua recursão gigante vai alocando memória da stack. Como esta é relativamente pequena, chegas a um momento que já não tens mais livre e ocorre um stack overflow.
Avatar do utilizador
Tharis
up-Quark!
up-Quark!
 
Mensagens: 387
Registado: Quinta Out 23, 2008 4:26 pm

Próximo

Voltar para Pitónica

Quem está ligado

Utilizadores a navegar neste fórum: Nenhum utilizador registado e 1 visitante

cron