Página 2 de 3
Enviado: 12 Fev 2008 21:40
por Maligno
Código: Selecionar todos
nMax := 0
nMes := 0
Aeval(aMeses,{|n,i|nMax := if(n>nMax, (nMes:=i,n), nMax)})
O bloco de código de AEval contém dois argumentos. Você sabe que este bloco avalia (evalua, como dizem alguns) elemento por elemento da matriz informada. No nosso caso, n é o elemento que está sendo avaliado e i é o número de ordem desse elemento dentro da matriz.
Como o valor de nMax depende do retorno do IF(), ao testar a expressão
n > nMax, e sendo TRUE, faço o IF() retornar n, mas só depois (e tem de ser depois) de atribuir o número deste mês (i) a nMes.
Se sua dúvida ficou na sub-expressão
(nMes:=i,n), apesar de meio estranha e incomum, ela é perfeitamente válida. Mas tem um porém. Sem parênteses, é erro de sintaxe. Com parênteses é uma expressão múltipla normal que, avaliada, retornará o último valor apurado, após a última vírgula. No caso, n. Eu só aproveitei essa característica pra também fazer a atribuição de nMes. Uma carona.

Enviado: 12 Fev 2008 21:54
por Pablo César
Maligno escreveu:(evalua, como dizem alguns)
Eu por exemplo, hihihi
Maligno escreveu:Se sua dúvida ficou na sub-expressão (nMes:=i,n), apesar de meio estranha e incomum, ela é perfeitamente válida.
Sim é a esta expressão que ainda não consigo entender.
Maligno escreveu:retornará o último valor apurado, após a última vírgula. No caso, n.
E o
i para que seria ? Quê valor tem ?
Maligno escreveu:Eu só aproveitei essa característica pra também fazer a atribuição de nMes. Uma carona.

Sim, isso entendí e eu ia sugerir acrescentar ao seu exemplo inicial, mas achei que eu ia me embanar todo.
ordenar variaveis
Enviado: 12 Fev 2008 22:05
por Adalberto
Pablo César.
Sua pergunta se refere a essa linha?
LOCAL nIndice := 1 , nI
Então podemos modificar assim:
LOCAL nIndice := 1 , nI := 0
E só uma variável do tipo numérica, eu utilizo a notação Ungara, onde a primeira letra em minúscula diz o tipo da variável, neste caso nI quer dize que I e uma numérica. Assim nMaior.
anValor é: a= array, n=Numérico, Valor=Nome da variável
Perdão se exagere na explicação, foi com o propósito de deixar tudo claro respeito de este modo de nomear a variável.
Abraços e paz para você.
ordenar variaveis
Enviado: 12 Fev 2008 22:14
por Adalberto
Pablo César.
Por favor, não considere meu ultimo post, escrevi ele sem ler o post do maligno, foi um terrível descuido de minha parte, motivado pela conversação de minha mãe, com este filho seu que conversa e posta. ( já pedi perdão a minha mãe).
Perdoe Pablo César, e também perdão a todos os clippeiros do foro.
Enviado: 12 Fev 2008 22:21
por Maligno
Pablo César escreveu:Maligno escreveu:(evalua, como dizem alguns)
Eu por exemplo, hihihi
Não só você. A tradução de "evaluation" não é muito clara. Por isso há quem use a tradução "evaluar", que não está tão errada. E você está perdoado, pois em espanhol traduz-se como "evaluar" ou "avaluar".
Maligno escreveu:Se sua dúvida ficou na sub-expressão (nMes:=i,n), apesar de meio estranha e incomum, ela é perfeitamente válida.
Sim é a esta expressão que ainda não consigo entender.
É uma expressão múltipla. Um exemplo prático para entender melhor:
Um programa assim não compilaria por culpa da atribuição de x. Isso é erro de sintaxe. Mas y está sendo atribuído certinho. Ele receberá o valor 5, pois expressões múltiplas sempre retornam o último valor avaliado.
E o i para que seria ? Quê valor tem ?
A variável i no bloco de código é o índice (número de ordem) do elemento que está sendo avaliado naquele momento. Se o valor deste elemento for maior que nMax, i será utilizado para indicar o número do mês onde esse valor aparece.
Enviado: 12 Fev 2008 23:31
por Pablo César
Entendí e gostei (you are a genius !). No seu exemplo:
Código: Selecionar todos
aMeses:={12.22,33.44,55.78,11.01,66.38,23.34}
nMax := 0
nMes := 0
Aeval(aMeses,{|n,i|nMax := if(n>nMax, (nMes:=i,n), nMax)})
Pode ser traduzida em:
Código: Selecionar todos
aMeses:={12.22,33.44,55.78,11.01,66.38,23.34}
n:=0
nMax:=0
nMes:=0
FOR i=1 TO LEN(aMeses)
n:=aMeses[i]
IF n>nMax
nMax:=n
nMes:=i
ELSE
nMax:=nMax
ENDIF
NEXT
? nMes
? nMax
Interessante a questão
(nMes:=i,n) dentro do IF() além de atribuir a variável
nMes com
i o
n atribui a variável nMax da condição IF(). Entendí, essa sentença cumpre duas funções. Obrigado pelo ensinamento (your trully a expert), tks.
ordenar variaveis
Enviado: 13 Fev 2008 01:02
por Adalberto
Pablo César,
Em sua tradução: ¿que aconteceria se os valores todos foram negativos?.
Iria mostrar 0 (zero) como maior.
Enviado: 13 Fev 2008 01:10
por Maligno
Mas zero é sempre maior que qualquer valor negativo, Adalberto. O único reparo que coloco no código do colega é que o ELSE do teste é desnecessário. Mas não tem tanto problema, já que é só um exemplo. Ele deve ter feito rápido e se distraiu.
Re: ordenar variaveis
Enviado: 13 Fev 2008 09:09
por Pablo César
Muito bem Adalberto, se todos os elementos forem negativos não iria funcionar direito (conforme meu exemplo anterior), mas veja o que fiz que funcionaria em ambos casos:
Código: Selecionar todos
aMeses:={-12.22,-33.44,-55.78,-11.01,-66.38,-23.34} // tudo negativo
tAllNeg:=.T.
FOR i=1 to LEN(aMeses)
IF aMeses[i]>0
tAllNeg:=.F.
ENDIF
NEXT
nMax:=0
nMes:=0
FOR i=1 TO LEN(aMeses)
IF tAllNeg
n:=(aMeses[i])*-1
ELSE
n:=aMeses[i]
ENDIF
IF n>nMax
nMax:=n
nMes:=i
ELSE
nMax:=nMax
ENDIF
NEXT
? nMes
? nMax
Agora com este exemplo, experimente asignando valores negativos e positivos mixtos ou até mesmo somente utdo positivo e funcionará normal. Agora cómo fazer tudo numa linha só, não sei se seria possível, quem sabe o mestre Maligno consiga...
O único reparo que coloco no código do colega é que o ELSE do teste é desnecessário. Mas não tem tanto problema, já que é só um exemplo. Ele deve ter feito rápido e se distraiu.
Com certeza o meu ELSE é desnecessário. Não foi distração minha, não. Eu apenas coloquei para evidenciar o seu exemplo no qual também é atribuido a si mesmo ...if(n>nMax, (nMes:=i,n), nMax)... Fiz isso para que o pessoal entendesse o que você tinha feito Maligno.
Enviado: 13 Fev 2008 10:15
por Maligno
Agora cómo fazer tudo numa linha só, não sei se seria possível
É só seguir o raciocínio de antes:
Código: Selecionar todos
for i := 1 to Len(aMeses)
nMax := if((n:=aMeses[i]*if(tAllNeg,-1,1))>nMax,(nMes:=i,n)
next
Só não entendo porque mudar o sinal do valor, se a proposta é descobrir qual o maior valor. Se todos forem negativos e o problema for o zero inicial, é só iniciar nMax com um valor impossível. Algo do tipo -999999.
Usar o flag tAllNeg para indicar que há apenas valores negativos só para inverter os valores dos elementos não ajuda muito, porque se todos forem negativos, você inverte seus sinais, mas aí a busca deve se inverter também. Você precisará descobrir qual o menor valor. Valor este que, originalmente negativo, será o maior.

Enviado: 13 Fev 2008 10:47
por Pablo César
Quanto ao seu código: Beleza, funcionou corrigindo para:
Código: Selecionar todos
for i := 1 to Len(aMeses)
nMax := if( (n:=aMeses[i]*if(tAllNeg,-1,1))>nMax,(nMes:=i,n), nMax )
next
Só não entendo porque mudar o sinal do valor, se a proposta é descobrir qual o maior valor. Se todos forem negativos e o problema for o zero inicial, é só iniciar nMax com um valor impossível. Algo do tipo -999999
Pois é, eu fiz isso e ainda achei que o resultado estava ERRADO. Mas eu me enganei e concordo contigo que não haveria necessidade de converter sinal, ora porquê ? Porque o resultado de todos os elementos negativos, será o maior aquele que for mais próximo do ZERO e convertendo este resultado muda o critério. Portanto apresento a versão corrigida:
Código: Selecionar todos
aMeses:={-12.22,-33.44,-55.78,-11.01,-66.38,-23.34}
nMax:=aMeses[1] // Corrigido conforme sugirido por Adalberto/Maligno
nMes:=0
FOR i=1 TO LEN(aMeses)
n:=aMeses[i]
IF n>nMax
nMax:=n
nMes:=i
ENDIF
NEXT
? nMes
? nMax
ou no seu modo sintético:
Código: Selecionar todos
aMeses:={-12.22,-33.44,-55.78,-11.01,-66.38,-23.34}
nMax:=aMeses[1] // Corrigido conforme sugirido por Adalberto/Maligno
nMes:=0
Aeval(aMeses,{|n,i|nMax := if(n>nMax, (nMes:=i,n), nMax)})
? nMes
? nMax
Então podemos esquecer a razão de converter os elementos que estão como números negativos. Valeu Maligno pelo esclarecimento.
Obs.: Desculpe Maligno não ter respondido no chat, não te ví porque eu estava no Prompt de comando ocupado com os testes do número negativo e como o chat não possue recurso de avisar usuário quando está em outra sessão: acabei perdendo a oportunidade de dialogar contigo. E também não estavam ligadas as caixas de som. Sorry.
Enviado: 13 Fev 2008 10:57
por Maligno
Pablo César escreveu:Quanto ao seu código: Beleza, funcionou corrigindo para:
Pois é. Esqueci da última parte. Mas numa linha só acabou virando uma salada.

)) Ainda bem que é só por curiosidade mesmo.
Enviado: 13 Fev 2008 11:21
por marcos.gurupi
Kros colegas, obrigado a todos pelas dicas foi resolvido com o mesmo exemplo do Maligno.
Marcos Roberto.
ordenar variaveis
Enviado: 13 Fev 2008 12:06
por Adalberto
Pablo César,
Só com animo de contribuir.
Meu exemplo roda certinho encontra o valor maior sejam quaisquer tipos de valores, só negativos, positivos o misturado, e não precisa de esse valor -9999999.
Enviado: 13 Fev 2008 12:14
por Maligno
Justamente, Adalberto. O valor inicial -999999 sugerido também pode ser substituído pelo valor do primeiro elemento. Tanto o custo quanto efeito são os mesmos.