jonhhy Posted August 7, 2022 at 12:18 PM Report Share #626758 Posted August 7, 2022 at 12:18 PM Boa tarde caríssimos membros da comunidade P@P, vou apresentar-vos o problema e o esboço de código na tentativa de resolução: Desafio 78 Faça um programa que leia 5 valores numéricos e guarde-os em uma lista. No final, mostre qual foi o maior e o menor valor digitado e as suas respectivas posições na lista. def countPos(extreme, values): for ind, values in enumerate(values): pos = [] oc = values.count(extreme) pst=values.index(extreme) if oc > 1: pos.append(pst) oc -= 1 values = values[oc+1:] countPos(extreme, values) else: return pst if oc == len(values-1): return pos values = [] maxi=mini=0.0 im = iM = [] for i in range(0,5): n = float(input(f'Digit num[{i+1}]: ')) # int(input) também dá erro values.append(n) if i == 0 or values[i] < mini: #mini, im = values[i], i mini = values[i] #im.append(i+1) if i == 0 or float(values[i]) >= maxi: #maxi, iM = values[i], i maxi = values[i] #iM.append(i+1) print('-=' *20) print(f'You digit: {values}') print(f'Maximum is: {maxi} in position {countPos(maxi, values)}') #iM} ') print(f'Minimum is: {mini} in position {countPos(mini, values)}') #im}') O que devo alterar? Link to comment Share on other sites More sharing options...
Rui Carlos Posted August 7, 2022 at 05:23 PM Report Share #626759 Posted August 7, 2022 at 05:23 PM Quando obténs erros e pretendes ajuda a resolvê-los, convém colocar no tópico um exemplo completo dos erros que obténs. Podes colocar a mensagem de erro no título como fizestes, mas no tópico convém colocar um exemplo completo do erro. Dito isto, algumas questões: Sabes em que linha(s) é que o erro está a ocorrer? O que é que é suposto fazeres com isto for ind, values in enumerate(values)? (Repara que values aparece duas vezes.) Por que razão tens uma chamada recursiva em countPos, se ignoras o resultado? Precisas mesmo de um ciclo e de recursividade para implementar a função? Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
jonhhy Posted August 7, 2022 at 09:17 PM Author Report Share #626761 Posted August 7, 2022 at 09:17 PM Em 07/08/2022 às 19:23, Rui Carlos disse: Quando obténs erros e pretendes ajuda a resolvê-los, convém colocar no tópico um exemplo completo dos erros que obténs. Podes colocar a mensagem de erro no título como fizestes, mas no tópico convém colocar um exemplo completo do erro. Dito isto, algumas questões: Sabes em que linha(s) é que o erro está a ocorrer? O que é que é suposto fazeres com isto for ind, values in enumerate(values)? (Repara que values aparece duas vezes.) Por que razão tens uma chamada recursiva em countPos, se ignoras o resultado? Precisas mesmo de um ciclo e de recursividade para implementar a função? Boa tarde Rui Carlos, muito obrigado pela recomendações, Sabes em que linha(s) é que o erro está a ocorrer? No link que contém a imagem do código e do output quando coloquei a correr: Y5kNyzg_1 Y5kNyzg_2 Y5kNyzg_3 Sim o erro ocorre na (1a) linha em que ocorre a chamada à função countPos(): print(f'Maximum is: {maxi} in position {countPos(maxi, values)}'). O que é que é suposto fazeres com isto for ind, values in enumerate(values)? (Repara que values aparece duas vezes.) O objectivo é iterar a a lista de forma a conseguir percorrê-la para todos os valores máximos ou mínimos, quando é um basta retornar, se aparece múltiplas vezes tenho de saber a posição (através do indexes), como retorna a primeira ocorrência, para percorrer as restantes recorro ao slicing de listas. Por que razão tens uma chamada recursiva em countPos, se ignoras o resultado? O interesse é saber as posições onde ocorrem os extremos, se for mais que um retorno a lista de posições, senão retorno o valor isolado da posição (única) Precisas mesmo de um ciclo e de recursividade para implementar a função? Como não sei o número de vezes que o número pode aparecer, fiz recursivamente. Contudo sei que este se limita ao número máximo de pedidos de valores , podia de facto fazer um ciclo a confirmar max==values[i] abraço, jonhhy Link to comment Share on other sites More sharing options...
jonhhy Posted August 8, 2022 at 09:49 AM Author Report Share #626762 Posted August 8, 2022 at 09:49 AM Bom dia Rui Carlos e mais membros da Comunidade P@P , refiz o programa, usando em vez do slicing a remoção dos elementos da lista (remove() para remover a primeira ocorrência do máximo e verificar o seguinte, se houver) e fiz tudo num programa corrido em vez de fazer a função auxiliar.. De confusão quando peguei estava a operar as posições dos mínimos, pois a lista e a variavél i já estava alterada do uso dos máximos, tive de criar uma cópia das listas. copy = values[:] values = [] maxi=mini=0.0 #im = iM = [] # é aquil que o G G disse, não é cópia é ligação uma à outra, então não devo... declarar as listas juntas uma da outra! iM = [] im = [] for i in range(0,5): n = float(input(f'Digit num[{i+1}]: ')) # instead of float values.append(n) if i == 0 or values[i] < mini: #mini, im = values[i], i mini = values[i] #im.append(i+1) if i == 0 or float(values[i]) >= maxi: #maxi, iM = values[i], i maxi = values[i] #iM.append(i+1) print('-=' *20) print(f'You digit: {values}') copy = values[:] # muitas nuances, a ser usada pelo ... mínimos i=0 ############### para o Máximo nMax = values.count(maxi) while nMax > 0: #values.index(maxi) iM.append(values.index(maxi)+1+i) #maxi == values...[] # if nMax == 1: # break values.remove(maxi) nMax-=1 i+=1 print(f'Maximum is: {maxi} in position: {[iM]}') #iM} ') ################ para o Mínimo i=0 nMin = copy.count(mini) while nMin > 0: #values.index(maxi) im.append(copy.index(mini)+1+i) #maxi == values...[] # if nMax == 1: # break copy.remove(mini) nMin -=1 i+=1 print(f'Minimum is: {mini} in position: {[im]}') #iM} ') o output está disponível em: https://files.portugal-a-programar.org/uploads/attach/imgur/MJPrFA6.png Link to comment Share on other sites More sharing options...
Rui Carlos Posted August 8, 2022 at 06:56 PM Report Share #626776 Posted August 8, 2022 at 06:56 PM Em 07/08/2022 às 23:17, jonhhy disse: Sabes em que linha(s) é que o erro está a ocorrer? No link que contém a imagem do código e do output quando coloquei a correr: Y5kNyzg_1 Y5kNyzg_2 Y5kNyzg_3 Sim o erro ocorre na (1a) linha em que ocorre a chamada à função countPos(): print(f'Maximum is: {maxi} in position {countPos(maxi, values)}'). Podias fazer copy & paste do erro, mas ok. Como mostra na imagem, o erro ocorre na linha oc = values.count(extreme). A mensagem de erro está basicamente a dizer-te que values é um float, e que um float não tem método count. A pergunta seguinte é por que razão aquilo é um float, e não uma lista de floats, como provavelmente estavas a espera? Em 07/08/2022 às 23:17, jonhhy disse: O que é que é suposto fazeres com isto for ind, values in enumerate(values)? (Repara que values aparece duas vezes.) O objectivo é iterar a a lista de forma a conseguir percorrê-la para todos os valores máximos ou mínimos, quando é um basta retornar, se aparece múltiplas vezes tenho de saber a posição (através do indexes), como retorna a primeira ocorrência, para percorrer as restantes recorro ao slicing de listas. Portanto, não achas estranho teres uma variável values duas vezes? Qual vai ser o tipo de values dentro do ciclo? Em 07/08/2022 às 23:17, jonhhy disse: Por que razão tens uma chamada recursiva em countPos, se ignoras o resultado? O interesse é saber as posições onde ocorrem os extremos, se for mais que um retorno a lista de posições, senão retorno o valor isolado da posição (única) Ou me estar a escapar algo, ou chamares aquela função de forma recursiva sem usares o resultado da chamada recursiva torna aquela linha completamente inútil (se a removeres, o código dá precisamente o mesmo resultado). Um outro comentário: ter uma função que tanto devolve um valor escalar, como uma lista é pedir problemas. Recomendo-te que no futuro uses sempre lista em caso similares. Em 07/08/2022 às 23:17, jonhhy disse: Precisas mesmo de um ciclo e de recursividade para implementar a função? Como não sei o número de vezes que o número pode aparecer, fiz recursivamente. Contudo sei que este se limita ao número máximo de pedidos de valores , podia de facto fazer um ciclo a confirmar max==values[i] Acho que misturares as duas coisas só complica. Podias fazer aquilo de forma recursiva ou iterativa. ------------------------------- Tendo em conta que já resolveste o problema, ficam aqui soluções, iterativa, recursiva, e funcional: def countPos(x: float, values: list[float]) -> list[float]: result: list[float] = [] for i, value in enumerate(values): if value == x: result.append(i + 1) return result def countPosRec(v: float, values: float, base: int = 1) -> list[float]: if len(values) == 0: return [] if v == values[0]: return [base] + countPosRec(v, values[1:], base + 1) else: return countPosRec(v, values[1:], base + 1) def countPosFunctional(v: float, valus: list[float]) -> list[float]: return list(map(lambda entry: entry[1] + 1, filter(lambda entry: entry[0] == v, zip(values, range(len(values)))))) Não sou especialista em Python. Por isso é provável que isto ainda possa ser mais simplificado. Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
jonhhy Posted August 9, 2022 at 04:49 PM Author Report Share #626801 Posted August 9, 2022 at 04:49 PM Em 08/08/2022 às 20:56, Rui Carlos disse: def countPos(x: float, values: list[float]) -> list[float]: result: list[float] = [] for i, value in enumerate(values): if value == x: result.append(i + 1) return result def countPosRec(v: float, values: float, base: int = 1) -> list[float]: if len(values) == 0: return [] if v == values[0]: return [base] + countPosRec(v, values[1:], base + 1) else: return countPosRec(v, values[1:], base + 1) def countPosFunctional(v: float, valus: list[float]) -> list[float]: return list(map(lambda entry: entry[1] + 1, filter(lambda entry: entry[0] == v, zip(values, range(len(values)))))) Não sou especialista em Python. Por isso é provável que isto ainda possa ser mais simplificado. Boa tarde Rui Carlos, já experimentei as funções, a versão functional tenho de estudar as funções Faz lembrar Haskell (com o cabeçalho a indicar o tipo das funções) talvez seja recomendado fazer isso, para melhorar a legibilidade do mesmo. Impecável, já percebi, é para ter a noção da tipagem do que estou a fazer, contudo é possível correr o código assim? Por acaso ter alguém bem mais experiente a rever o código, dá muito jeito até para rever pequenos e outros grandes erros. E optimizar o código claro, Citação O que é que é suposto fazeres com isto for ind, values in enumerate(values)? (Repara que values aparece duas vezes.) no primeiro values passei a value antes do enumerate e o código já corre Link to comment Share on other sites More sharing options...
jonhhy Posted August 12, 2022 at 05:06 PM Author Report Share #626879 Posted August 12, 2022 at 05:06 PM Olá, Caros membros da comunidade P@P, tinha uma dúvida, que tem haver com funções, o retorno e as chamadas às funções: def countPosPrint(x, values): for i, value in enumerate(values): if value == x: print(f'{i+1}' ,end=' ') return Com a função a não retornar nada, a função ao ser chamada {countPosPrint(7, [3,7,-4,7,0])} retorna-me None no programa, mas fora retorna-me as posições 2 e 4 porque (ver imagem no link)? https://files.portugal-a-programar.org/uploads/attach/imgur/dNHyznq.png (exemplo na imagem) Em 07/08/2022 às 14:18, jonhhy disse: print(f'Maximum is: {maxi} in position {countPos(maxi, values)}') #iM} ') Obrigado pela vossa atenção, são uma excelente ajuda 🙂🙏 💪 Link to comment Share on other sites More sharing options...
Rui Carlos Posted August 12, 2022 at 05:51 PM Report Share #626880 Posted August 12, 2022 at 05:51 PM Evita usar imagens para conteúdos textuais. Coloca directamente o código na mensagem. Essa função nunca retorna o valor. Quando a executas directamente, o que vez são os valores são os valores impressos, e não os valores devolvidos pela função. Em geral, é muito má prática misturar interacção com o utilizador (print, input, etc.) com computação. Resumindo, esquece esse código, e volta ao código que devolve o resultado. Rui Carlos Gonçalves Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now