Trabalhando com ARRAY em vez de DBFCDX
Moderador: Moderadores
-
Ladinilson Sousa
- Usuário Nível 1

- Mensagens: 35
- Registrado em: 09 Fev 2015 11:41
- Localização: Belém/PA
Trabalhando com ARRAY em vez de DBFCDX
Boa noite caros,
Possuo um software de sorteio de bingos e para quantidades de cartelas baixo até 30.000 esta tudo muito bom. Mas agora me vejo diante de um desafio muito maior e 500.000 cartelas de teste se tornou lento para trabalhar com DBFCDX diretamente e já testados vários tipo de soluções como:
ORDWILDSEEK()
SET FILTER MEMORY ADDITIVE
SEEK
SET RELATION
ORDSCOPE()
Então tive a última cartada para array na esperança de ser mais rápida e me deparei com algumas dificuldades neste setor que pouco uso.
A ideia é pegar informações do banco de dado original e somente retornar ao mesmo quando alguma cartela já sorteada acontecer.
Comecei com...
PRIVATE aCartelas := {" "," "," "}
SELECT Cartelas
Cartelas->(DBGOTOP())
DbEVal({||AADD(aCartelas,{ALLTRIM(STR(Cartelas->numero)),Cartelas->seqcar,STR(Cartelas->falta)})})
com informações por exemplo...
NUMERO______SEQUENCIA__________________________________________________FALTA
33349________04 07 08 09 11 12 20 22 24 25 33 34 35 40 46 50 51 52 56 59_________20
onde:
NUMERO = Numero da cartela
SEQUENCIA = Sequencia de 20 de numeros da cartela
FALTA = Número de que iá indicar se estará armada ou sorteada (diminuir a cada número encontrado em SEQUENCIA)
A rotina é a cada bola sorteada ele procura se esta contido em SEQUENCIA, caso sim, ele diminui um valor em FALTA (ou seja o valor é substituido no array) isso em cada um elemento de aCartelas
Caso um FALTA esteja com valor 1, ele soma 1 a uma variavel ARMADAS
Caso FALTA fique 0 (zero) atribui-se .T. (verdadeiro) a uma variável GANHOU e atribui-se a uma variável GNUMERO do NUMERO e neste momento darei um SEEK gnumero no campo número do DBFCDX e marcarei o registro (cartela) como sorteada.
Rotina essa dentro de um...
FOR a := 1 TO LEN(aCartelas)
....
NEXT
Parece ser simples mas as sintaxes me fogem a lógica no momento e acredito para experts em arrays isso já deve ser bem simples.
Obrigado pela atenção
Ladinilson Sousa
FWH 13.12/xHarbour/Pelles C/DBFCDX/MySQL
Possuo um software de sorteio de bingos e para quantidades de cartelas baixo até 30.000 esta tudo muito bom. Mas agora me vejo diante de um desafio muito maior e 500.000 cartelas de teste se tornou lento para trabalhar com DBFCDX diretamente e já testados vários tipo de soluções como:
ORDWILDSEEK()
SET FILTER MEMORY ADDITIVE
SEEK
SET RELATION
ORDSCOPE()
Então tive a última cartada para array na esperança de ser mais rápida e me deparei com algumas dificuldades neste setor que pouco uso.
A ideia é pegar informações do banco de dado original e somente retornar ao mesmo quando alguma cartela já sorteada acontecer.
Comecei com...
PRIVATE aCartelas := {" "," "," "}
SELECT Cartelas
Cartelas->(DBGOTOP())
DbEVal({||AADD(aCartelas,{ALLTRIM(STR(Cartelas->numero)),Cartelas->seqcar,STR(Cartelas->falta)})})
com informações por exemplo...
NUMERO______SEQUENCIA__________________________________________________FALTA
33349________04 07 08 09 11 12 20 22 24 25 33 34 35 40 46 50 51 52 56 59_________20
onde:
NUMERO = Numero da cartela
SEQUENCIA = Sequencia de 20 de numeros da cartela
FALTA = Número de que iá indicar se estará armada ou sorteada (diminuir a cada número encontrado em SEQUENCIA)
A rotina é a cada bola sorteada ele procura se esta contido em SEQUENCIA, caso sim, ele diminui um valor em FALTA (ou seja o valor é substituido no array) isso em cada um elemento de aCartelas
Caso um FALTA esteja com valor 1, ele soma 1 a uma variavel ARMADAS
Caso FALTA fique 0 (zero) atribui-se .T. (verdadeiro) a uma variável GANHOU e atribui-se a uma variável GNUMERO do NUMERO e neste momento darei um SEEK gnumero no campo número do DBFCDX e marcarei o registro (cartela) como sorteada.
Rotina essa dentro de um...
FOR a := 1 TO LEN(aCartelas)
....
NEXT
Parece ser simples mas as sintaxes me fogem a lógica no momento e acredito para experts em arrays isso já deve ser bem simples.
Obrigado pela atenção
Ladinilson Sousa
FWH 13.12/xHarbour/Pelles C/DBFCDX/MySQL
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Trabalhando com ARRAY em vez de DBFCDX
me veio na cabeça:
UPDATE CARTELAS SET FALTA=FALTA-1 WHERE NUMEROS LIKE '%01%'
SELECT * FROM CARTELAS WHERE FALTA = 0
problemão, em SQL com solução simples... rs
UPDATE CARTELAS SET FALTA=FALTA-1 WHERE NUMEROS LIKE '%01%'
SELECT * FROM CARTELAS WHERE FALTA = 0
problemão, em SQL com solução simples... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
-
Ladinilson Sousa
- Usuário Nível 1

- Mensagens: 35
- Registrado em: 09 Fev 2015 11:41
- Localização: Belém/PA
Trabalhando com ARRAY em vez de DBFCDX
José Quintas verdade!
Mas lembrando que os mesmos comandos "varrem" o banco de dados e em se tratando de grandes volumes, a perda de performance pode ser bem significativa pois ha a atualização (COMMIT) ainda.
Em DBFCDX um "$" (está contido) e bem rápido usando-se o SET INDEX MEMORY ADDITIVE mas o problema persiste na hora da atualização dos campos de cada registro filtrado.
Um REPLACE ALL semelhante ao UPDATE no sql parace que o programa travou rsrs
Mas lembrando que os mesmos comandos "varrem" o banco de dados e em se tratando de grandes volumes, a perda de performance pode ser bem significativa pois ha a atualização (COMMIT) ainda.
Em DBFCDX um "$" (está contido) e bem rápido usando-se o SET INDEX MEMORY ADDITIVE mas o problema persiste na hora da atualização dos campos de cada registro filtrado.
Um REPLACE ALL semelhante ao UPDATE no sql parace que o programa travou rsrs
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Trabalhando com ARRAY em vez de DBFCDX
Mas 500.000 cartelas de bingo.... se for 1 real cada... isso dá meio milhão de reais.
Tem outra coisa:
Se o processamento for no terminal, a quantidade de cartelas vai ser pequena.
Se o processamento for no servidor... aí precisa demorar menos do que o sorteio de cada bola.
Se o servidor pegar o resultado pronto dos terminais, vai ter menos processamento, porque fica tudo distribuído.
E mais outra: sei lá como fazer em multithread, mas....
Se houver um processo fazendo em ordem das que faltam menos... o resultado, que é o mais importante, estaria pronto antes do processo completo terminar, e nem notariam a demora do processo restante.
Tem outra coisa:
Se o processamento for no terminal, a quantidade de cartelas vai ser pequena.
Se o processamento for no servidor... aí precisa demorar menos do que o sorteio de cada bola.
Se o servidor pegar o resultado pronto dos terminais, vai ter menos processamento, porque fica tudo distribuído.
E mais outra: sei lá como fazer em multithread, mas....
Se houver um processo fazendo em ordem das que faltam menos... o resultado, que é o mais importante, estaria pronto antes do processo completo terminar, e nem notariam a demora do processo restante.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Trabalhando com ARRAY em vez de DBFCDX
Não sei também se ir limpando o array agiliza, pra ter menos números pra processar....
Sempre daria pra pesquisar os números completos pelo número da cartela, então deixa de ser importante trabalhar sempre com todos os números.
Só não sei se o tempo do hb_ADel() vai compensar o ganho de tempo. (no caso de array), ou o tempo de limpar a string no DBF (numero $ trim( falta ) ).
Vai ter que fazer os testes.
Sempre daria pra pesquisar os números completos pelo número da cartela, então deixa de ser importante trabalhar sempre com todos os números.
Só não sei se o tempo do hb_ADel() vai compensar o ganho de tempo. (no caso de array), ou o tempo de limpar a string no DBF (numero $ trim( falta ) ).
Vai ter que fazer os testes.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Trabalhando com ARRAY em vez de DBFCDX
Também vários arrays...
Um array para as cartelas que faltam 1 número, outro pra 2, etc. e transferindo de um para o outro.
Imagino assim:
sorteou uma bola.... o urgente é analisar os que só faltavam 1 bola, os demais não tem pressa.
as cartelas que faltam 2 números nunca vão fazer bingo antes das que faltam 1 só número...
As demais... sem pressa de trazer o resultado.
Acho que vai ser impossível as 500.000 cartelas esperando um único número....
Se forem distribuídos de forma igual, poderia reduzir em 100 vezes.... 5.000 cartelas esperando um único número.
Um array para as cartelas que faltam 1 número, outro pra 2, etc. e transferindo de um para o outro.
Imagino assim:
sorteou uma bola.... o urgente é analisar os que só faltavam 1 bola, os demais não tem pressa.
as cartelas que faltam 2 números nunca vão fazer bingo antes das que faltam 1 só número...
As demais... sem pressa de trazer o resultado.
Acho que vai ser impossível as 500.000 cartelas esperando um único número....
Se forem distribuídos de forma igual, poderia reduzir em 100 vezes.... 5.000 cartelas esperando um único número.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Trabalhando com ARRAY em vez de DBFCDX
Acho que estou a 1000 por hora hoje.... kkkk
Pensei num trem doido pra última opção:
É um array geral, com um array pra cada quantidade faltante.
Cada array interno vai ter o número da cartela, e os números que faltam, por isso pula o 1 na checagem de números
Cada número acertado retira o número da lista da cartela, e move a cartela pro array "anterior"
O array 1 seria dos que fizeram bingo, então... assim que processa o array 2 dos que estão pra bater, se existir elemento no array 1 já indica que alguém bateu.
Pensei num trem doido pra última opção:
Código: Selecionar todos
PROCEDURE Main
LOCAL aList := {}
FOR EACH aFalta IN aList DESC
FOR EACH aNumeros IN aFalta DESC
lAcertou := .F.
FOR EACH nNumero IN aNumeros
IF nNumero:__EnumIndex != 1
IF nNumero == nSorteio
hb_Adel( aNumeros, nNumero:__EnumIndex, .T. )
lAcertou := .T.
EXIT
ENDIF
ENDIF
NEXT
IF lAcertou
AAdd( aFalta[ aFalta:_EnumIndex - 1 ], aNumeros )
hb_ADel( aFalta[ aFalta:_EnumIndex ], .T. )
ENDIF
NEXT
IF aFalta:__EnumIndex < 2 .AND. Len( aFalta[ 1 ] ) != 0
// alguém ganhou
ENDIF
NEXT
RETURN
Cada array interno vai ter o número da cartela, e os números que faltam, por isso pula o 1 na checagem de números
Cada número acertado retira o número da lista da cartela, e move a cartela pro array "anterior"
O array 1 seria dos que fizeram bingo, então... assim que processa o array 2 dos que estão pra bater, se existir elemento no array 1 já indica que alguém bateu.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Trabalhando com ARRAY em vez de DBFCDX
E nem precisa se preocupar com array ZERO....
Quem já acertou todos os números... não vai acertar mais nenhum.... então nunca vai mover do 1 pro ZERO.
O sorteio das primeiras bolas vai ser o mais demorado, mas vai agilizando a cada bola sorteada, porque vão ser menos números pra fazer teste.
Quem já acertou todos os números... não vai acertar mais nenhum.... então nunca vai mover do 1 pro ZERO.
O sorteio das primeiras bolas vai ser o mais demorado, mas vai agilizando a cada bola sorteada, porque vão ser menos números pra fazer teste.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Trabalhando com ARRAY em vez de DBFCDX
Outra idéia pro SQL: ter 100 campos com S ou N, um pra cada número, e índices também para os 100 campos, para o falta, e para o número da cartela
UPDATE TABELA SET FALTA = FALTA - 1, NUMERO10='X' WHERE NUMERO10 = 'S'
SELECT * FROM TABELA WHERE FALTA = 0
Desta forma, o SELECT e o UPDATE vão ser em 5.000 cartelas, e não nas 500.000
UPDATE TABELA SET FALTA = FALTA - 1, NUMERO10='X' WHERE NUMERO10 = 'S'
SELECT * FROM TABELA WHERE FALTA = 0
Desta forma, o SELECT e o UPDATE vão ser em 5.000 cartelas, e não nas 500.000
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
-
Ladinilson Sousa
- Usuário Nível 1

- Mensagens: 35
- Registrado em: 09 Fev 2015 11:41
- Localização: Belém/PA
Trabalhando com ARRAY em vez de DBFCDX
José Quintas
Fiz um estudo e a solução foi simples até depois de procurar sintaxes e sintaxes.
"As vezes o menos é mais!"
Velha e simples sintaxe mas funcional rsrsr
Bom final de semana para senhor!
Obrigado
Fiz um estudo e a solução foi simples até depois de procurar sintaxes e sintaxes.
"As vezes o menos é mais!"
Código: Selecionar todos
PRIVATE aCartelas := {" "," "," "}
SELECT Cartelas
Cartelas->(DBGOTOP())
DbEVal({||AADD(aCartelas,{ALLTRIM(STR(Cartelas->numero)),Cartelas->seqcar,STRZERO(Cartelas->falta,2)})})
Cartelas->(DBGOTOP())
FOR s := 1 TO LEN(aCartelas)
n:= aCartelas[s][1]
q:= aCartelas[s][2]
f:= VAL(aCartelas[s][3])
IF AT(STRZERO(Bolanumero,2),q) > 0
f := VAL(f)-1
aCartelas[s][3] := STRZERO(f,2)
ENDIF
IF f < vnFalta
carma++
ENDIF
IF f == 0
vbateu := .t.
SELECT Cartelas
Cartelas->(DBGOTOP())
Cartelas->(ORDSETFOCUS("numero"))
Cartelas->(DBGOTOP())
SEEK n
Cartelas->sorteou := nPremio
Cartelas->falta := f
ENDIF
NEXT
Bom final de semana para senhor!
Obrigado
- JoséQuintas
- Administrador

- Mensagens: 20267
- Registrado em: 26 Fev 2007 11:59
- Localização: São Paulo-SP
Trabalhando com ARRAY em vez de DBFCDX
se desse jeito já resolveu, pode deixar mais básico/rápido ainda e retirar os StrZero() e o At()
Os gotop são inúteis, poderia retirar também.
O at() pode ser substituído por if "texto" $ string
Os gotop são inúteis, poderia retirar também.
O at() pode ser substituído por if "texto" $ string
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
https://github.com/JoseQuintas/
- Nascimento
- Usuário Nível 4

- Mensagens: 763
- Registrado em: 19 Jul 2008 12:11
- Localização: OLINDA-PE
Trabalhando com ARRAY em vez de DBFCDX
achei um link que pode ser util
https://www.linguagemclipper.com.br/dicas/arrays
https://www.linguagemclipper.com.br/dicas/arrays
A arte de programar é simplesmente fazer seus pensamentos serem interpretados por uma maquina
clipper 5.3 /harbour/minigui