Jump to content

Contar posições onde obtive valores máximos, erro 'float' object has no attribute 'count'


jonhhy

Recommended Posts

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

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?
Link to comment
Share on other sites

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:

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

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

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:

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.

Link to comment
Share on other sites

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

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

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 (printinput, etc.) com computação.  Resumindo, esquece esse código, e volta ao código que devolve o resultado.

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.