# Taken from Python cookbook
def xuniqueCombinations(items, n):
if n==0: yield []
else:
for i in xrange(len(items)-n+1):
for cc in xuniqueCombinations(items[i+1:],n-1):
yield [items[i]]+cc
# Taken from Python cookbook
def histogram(seq,h_d={}):
for x in seq:
h_d[x]=h_d.setdefault(x,0)+1
return h_d
def histlist(pastHist, newNums):
h = histogram(newNums,pastHist)
l = zip( h.values(), h.keys() )
l.sort()
l.reverse()
return h,l
def checkConfig(config):
if not os.path.exists(config.input_file):
sys.stderr.write("Input file ('%s') doesn't exist!\n"%(config.input_file,))
sys.exit(4)
if config.nums>config.max_nums:
sys.stderr.write("Nums (%d) can not be bigger than Max_Nums (%d)!\n"%(config.nums,config.max_nums))
sys.exit(4)
def getGroupBounds(cfg):
from math import ceil
bounds=[cfg.nums]
bounds.append( cfg.max_nums - int( ceil (cfg.max_nums * 0.50) ) )
return bounds
def readInputData(cfg):
inFile = open(cfg.input_file,'ra')
data = inFile.readlines()
inFile.close()
allLines = [ map(int,y) for y in [ x.split() for x in data ] ]
if cfg.top_recent:
allLines.reverse()
return allLines
def main():
if len(sys.argv) != 2:
usage()
sys.exit(1)
confFile = sys.argv[1]
if not os.path.exists(confFile):
usage()
sys.stderr.write("Config file supplied doesn't exist\n")
sys.exit(2)
allNums = []
for line in allLines[:-1*cfg.look_back]:
allNums += [x for x in line]
histHits = []
histReport = []
h = histogram(allNums,{})
for i in xrange(-1*cfg.look_back,-1,1):
line = allLines[i]
line.sort()
h,l = histlist(h, line )
g1 = [ y for (x, y) in l[ 0:bounds[0] ] ]
g1.sort()
g1l = len(g1)
g1h = hitCount(g1, allLines[i+1])
g2 = [ y for (x, y) in l[ bounds[0]:bounds[1] ] ]
g2.sort()
g2l = len(g2)
g2h = hitCount(g2, allLines[i+1])
g3 = [ y for (x, y) in l[ bounds[1]: ] ]
g3.sort()
g3l = len(g3)
g3h = hitCount(g3, allLines[i+1])
tmp=" ".join([str(d) for d in [g1h,g2h,g3h]] )
histHits.append(tmp)
tmp = " ".join([ "%-3d"%(abs(i),),"\t"," ".join([ "%02d"%(x,) for x in line]),"\t",tmp,"\t\t", "%12d"%(comb(g1l,g1h)*comb(g2l,g2h)*comb(g3l,g3h),)])+_N
histReport.append(tmp)
outFile.write(_N)
outFile.write(_N)
outFile.write(_N)
outFile.write("\tHits per Group Histogram\n")
outFile.write("-"*30+_N)
outFile.write("\tHits\tGrouping\n")
outFile.write("-"*30+_N)
outFile.write('\n'.join(["\t%02d \t%s" % (count, num) for (count, num) in lout])+_N)
h,l = histlist(h,allLines[-1])
g1 = [ y for (x, y) in l[ 0:bounds[0] ] ]
g1.sort()
g1l = len(g1)
g2 = [ y for (x, y) in l[ bounds[0]:bounds[1] ] ]
g2.sort()
g2l = len(g2)
g3 = [ y for (x, y) in l[ bounds[1]: ] ]
g3.sort()
outFile.write(_N)
outFile.write(_N)
outFile.write(_N)
outFile.write("\tGroups:\n")
outFile.write("-"*30+_N)
outFile.write(' '.join([ str(x) for x in g1])+_N)
outFile.write(' '.join([ str(x) for x in g2])+_N)
outFile.write(' '.join([ str(x) for x in g3])+_N)
Paste it into a file named for example HitTable.py (NOTE spaces/tabs matter); download and install Python (if you don't have it yet) and run this with something like:
Quote:
HitTable.py config.ini
I have tested this on Windows XP + Python 2.5; but it should work with any version of Python and OS.
I don't exclude the possibility that there might be some unfound bugs...
Have fun and ask feel free to ask questions.... _________________ Just ME here....
Great job, man! Your frequency report looks very clear. Somehow you use a different terminology. Nevertheless, the report should be very clear to most computer users.
I am not investing any time in learning Python, or any other language in addition to BASIC. I think I figured out the parpaluck in your program (number of drawings for determining the 3 frequency groups). It should be calculated here in your sample code:
max_nums * 0.50 (e.g. 49 * .5 = 25 draws for parpaluck)
You could add another parameter in the config file for the parpaluck.
Those should be the frequency groups for drawing #100. The frequency groups change — not from draw to draw, but they change several times within 100 drawings analyzed.
Now, you can write the code for decades!!! It is much simpler.
And THEN! You write code to look for strategies; e.g. 1-2-3 for frequency and 1-1-2-1-1 for decades.
Many people will be even more thankful to you. I am sure many people are already thankful for your code and programming lessons. I know, you are a system engineer not a programmer (two different computing jobs). But you know how to program very clearly. My source code is badly formatted and largely undocumented! I want it that way, because a good programmer should be paranoid as well!
You already wrote the code to generate the combinations. You can write a command-and-control program to put together the report generators, strategy checking, and combinations generators.
I was going to post a executive summary of the script, but I think that a reply to marcher is in order first....
marcher wrote:
I think I figured out the parpaluck in your program (number of drawings for determining the 3 frequency groups). It should be calculated here in your sample code:
max_nums * 0.50 (e.g. 49 * .5 = 25 draws for parpaluck)
You could add another parameter in the config file for the parpaluck.
I don't use the concept of "parpaluck" in this program; the frequency is calculated on all draws of the history file given. I might add the concept in the future once I have looked at it carefully.
marcher wrote:
You have this at the end:
(...)
Those should be the frequency groups for drawing #100. The frequency groups change — not from draw to draw, but they change several times within 100 drawings analyzed.
The idea here is that one can copy&paste these into a new file and feed it to the other script I posted....
marcher wrote:
Now, you can write the code for decades!!! It is much simpler.
And THEN! You write code to look for strategies; e.g. 1-2-3 for frequency and 1-1-2-1-1 for decades.
Maybe, who knows... it all depends on my available time.
marcher wrote:
Boa suerte!
Thanks.... but I think you mixed Portuguese and Spanish on the same sentence... it should be "Boa sorte" (PT) , "Buena suerte" (SP) or better yet "Buona fortuna" (IT) [although Italians actually use a different expression which I refuse to use for environmental reasons!]
marcher wrote:
How about a new programming language: BOA?
Don't know that one.... I googled it but didn't find anything special!
Basically this new script goes back "look_back" draws in the "input_file", calculates the the histogram/frequency table for all draws up to then and then starts calculating groups, hits per group and updating the histogram up to the last draw (most recent). For this last draw the corresponding groups are reported.
The rationale being that you look at how the distribution looked like for the past draws (summarized in the histogram/frequency table) and given the next groups decide what could be the next distribution..... _________________ Just ME here....
My frequency system is founded on the parpaluck. Every draw generates a specific frequency grouping based on the parpaluck. I wrote more about it in Ommni’s thread, where you also participate.
I take Chelmi’s configuration file for his Euromillions game. He only considers the 5 regular numbers out of 50. p = 5/50 = 1/10. The parpaluck can be 10, or 20, or 15, or even 50. I would add a ‘parpaluck’ line in the config file:
Changing the parpaluck will change the bias of the 1-2-3 frequency strings. The bias towards the smaller frequency groups is the most favorable for the player.
I dimension the arrays in my software this way:
ReDim Lotto_1(look_back+parpaluck), Lotto_2(look_back+parpaluck), etc.
(Lotto_1 is the lotto number 1 in the draw, Lotto_2 is the 2nd lotto number, etc.)
Then, the program takes each drawing analyzed and calculates the frequency groups for the specific parpaluck. Sometimes I calculate the frequency ‘tables’ for the previous drawing, instead of the current one.
The generator dimensions data the same way, but generates the frequency groups only for lotto draw #1 (the top line) in the data file. The parpaluck must be the same in the report generator and the combination generator.
For Powerball and Euromillions the frequency groups are calculated only for the last 1 (or 2) numbers in the draw.
Code:
-----------------------------------------------------------------
D.Back Numbers Reg Groups Star Groups Combinations
-----------------------------------------------------------------
1 2 2 0 2 0
It is likely that the generator will not generate the winning combination even if the correct 1-2-3 frequency string would hit. The 1-2-3 groups are specific to each lotto drawing. Actually, you don’t know when a 1-2-3 hits because the frequency ‘tables’ are not draw-dependent (in the Python report generator).
I don’t know if I am clear in this regard. I just did a test for my lotto 6/49 game. I ran the ‘Check strategy hits’ function with various parpalucks. You can look at the SkipDecades.EXE programs. So, I see the strategy report (‘Check strategy’ function). I know that the strategy hit in, say, 5 drawings. I know exactly the drawings. I run the ‘Check strategy hits’ function and generate the winning combination in every winning situation. That is true only if I use the same parpaluck as in the ‘Check strategy’ function. If I change the parpaluck, the ‘Check strategy hits’ function will miss the winning combination — more often than not.
I disabled the combination generation in the SkipDecades.EXE programs. But the code is still in there (commented out). I always test the winning combinations whenever I make changes to my software. I remember all too well the MDIEditor headaches of the 2006 summer!
Posted: Mar 03, 2007 15:58 Post subject: Hit Table generation......
marcher wrote:
Cristi:
My frequency system is founded on the parpaluck. Every draw generates a specific frequency grouping based on the parpaluck. I wrote more about it in Ommni’s thread, where you also participate.
I take Chelmi’s configuration file for his Euromillions game. He only considers the 5 regular numbers out of 50. p = 5/50 = 1/10. The parpaluck can be 10, or 20, or 15, or even 50. I would add a ‘parpaluck’ line in the config file:
In case you add the parpaluck function into your latest python, I suggest this can be done as a variable input (at the keyboard), not a fixed value in the config file.
Chelmi
ps: The Boa and the python belong both to the same reptile specie.
Posted: Mar 03, 2007 18:00 Post subject: Re: Hit Table generation......
chelmi wrote:
marcher wrote:
Cristi:
My frequency system is founded on the parpaluck. Every draw generates a specific frequency grouping based on the parpaluck. I wrote more about it in Ommni’s thread, where you also participate.
I take Chelmi’s configuration file for his Euromillions game. He only considers the 5 regular numbers out of 50. p = 5/50 = 1/10. The parpaluck can be 10, or 20, or 15, or even 50. I would add a ‘parpaluck’ line in the config file:
In case you add the parpaluck function into your latest python, I suggest this can be done as a variable input (at the keyboard), not a fixed value in the config file.
Chelmi
ps: The Boa and the python belong both to the same reptile specie.
ps2
Changing the loop_back value does NOT produce different groups of frequency.
I made various trials with different values from 2 to 100 and always obtained the same 3 groups composition.
Any explanation?
Regards
Posted: Mar 03, 2007 19:44 Post subject: Re: Hit Table generation......
chelmi wrote:
Changing the loop_back value does NOT produce different groups of frequency.
I made various trials with different values from 2 to 100 and always obtained the same 3 groups composition.
Any explanation?
No, the loop_back simply indicates how many draws to produce the report for.... you should see a change in the histogram and that's it! I will consider adding a parameter to select how many draws to use for the hit table calculation!
PS: What did you think about the eclipse today? Pretty nice isn't it, it's the reason why I am still here to post at this time. _________________ Just ME here....
Posted: Mar 04, 2007 03:42 Post subject: Re: Hit Table generation......
thornc wrote:
chelmi wrote:
Changing the loop_back value does NOT produce different groups of frequency.
I made various trials with different values from 2 to 100 and always obtained the same 3 groups composition.
Any explanation?
No, the loop_back simply indicates how many draws to produce the report for.... you should see a change in the histogram and that's it! I will consider adding a parameter to select how many draws to use for the hit table calculation!
PS: What did you think about the eclipse today? Pretty nice isn't it, it's the reason why I am still here to post at this time.
Understood!
Thanks for your help.
I did'nt see the eclipse; probably local for your place.
http://www.chez.com/lepithec/eclipse/ is a french site dedicated to eclipses. Nice photos.
Well it was visible almost allover the world... at least that's what for example bbc says.
It was visible from 23:20 to 2:10 last night in Paris
Back to your last code:
Instead of printing the combination number for each past draw line (which is repeating the same information numerous times, I suggest to print it on each line of the histogram. I tried to modify your code; without success. Which lines would you modify? (if you have time, now that the eclipse is gone!)
Regards
Thornc’s software works with a configuration file. A config file has the advantage of expediting the process. The user doesn’t have to type the parameters at the screen prompt. This approach works well when the parameters do not change.
More often than not, the parameters change. I prefer the approach of typing at a logical series of prompts. The most obvious case here is the parpaluck, a parameter that can change from run to run. Also, total number of drawings used can change from run to run. Furthermore, different data files can be loaded from run to run. It is inconvenient to terminate the program, edit the configuration file, then run the program again…and so on.
Lately, my software tries to make it easy for the user. The programs offer default entries that can be edited as well. The parameters can be changed and run with the same data file; or, a different data file can be loaded.
Now, again, the very important parpaluck.
Thornc’s Python code is a worthy achievement. But, in its current format, it cannot be applied to my lotto system based on three frequency groups. The software is correct only for draw #1 in the data file and a parpaluck = 100. To get correct results for other drawings, the user must exit the program, then delete line #1 in the data file. Run the program again still for 100 ‘look backs’. The new results are correct only for the new line #1, which represents the draw #2 in the actual lotto file. It becomes tedious for 100 draws…
The combination generator is correct for a parpaluck = 100. But the user still needs the skips of a particular strategy. The program can do still better by replacing the ‘parpaluck = 100’ with N (e.g. 49 for lotto 6/49; or 50 in Euromillions): ‘look_back=49’.
The report generator displays the number of possible combinations for every 1-2-3 frequency situation. That’s the method I prefer. It is repetitious, but the user does not have to memorize the number of possible combinations or to look up a frequency table. You can see immediately how many combinations to expect.
Even one more approach in functionality I came up with lately. There should be three output options: to screen, to file, and ‘count combinations only’. The latter option is similar to the ‘Check strategy hits’ in the SkipDecades.EXE programs. The ‘count only’ function is much faster and doesn’t gobble up a disk. MDIEditor and Lotto WE would have greatly benefited from such an option.
I updated the page to give Cristiano Lopes (a.k.a. thornc, a.k.a. Critser) the credit he deserves. I know for sure that many programmers have devoured Cristi’s source code! Yet, no other programmers are contributing. That’s the sad reality of open-source software: Take-it-all but give-nothing! I won’t be surprised to see or hear about software that generates lotto combinations based on frequency groups. It’s gonna happen sooner rather than later — and it’ll cost an arm and a leg.
.
Last edited by marcher on Mar 04, 2007 12:57; edited 1 time in total
# Taken from Python cookbook
def xuniqueCombinations(items, n):
if n==0: yield []
else:
for i in xrange(len(items)-n+1):
for cc in xuniqueCombinations(items[i+1:],n-1):
yield [items[i]]+cc
# Taken from Python cookbook
def histogram(seq,h_d={}):
for x in seq:
h_d[x]=h_d.setdefault(x,0)+1
return h_d
def histlist(pastHist, newNums):
h = histogram(newNums,pastHist)
l = zip( h.values(), h.keys() )
l.sort()
l.reverse()
return h,l
def checkConfig(config):
if not os.path.exists(config.input_file):
sys.stderr.write("Input file ('%s') doesn't exist!\n"%(config.input_file,))
sys.exit(4)
if config.nums>config.max_nums:
sys.stderr.write("Nums (%d) can not be bigger than Max_Nums (%d)!\n"%(config.nums,config.max_nums))
sys.exit(4)
def getGroupBounds(cfg):
from math import ceil
bounds=[cfg.nums]
bounds.append( cfg.max_nums - int( ceil (cfg.max_nums * 0.50) ) )
return bounds
def readInputData(cfg):
inFile = open(cfg.input_file,'ra')
data = inFile.readlines()
inFile.close()
allLines = [ map(int,y) for y in [ x.split() for x in data ] ]
if cfg.top_recent:
allLines.reverse()
return allLines
def getNumsLines(lines,i,j):
nums=[]
for line in lines[i:j]:
nums += [x for x in line]
return nums
histHits = []
histReport = []
for i in xrange(-1*cfg.look_back,-1,1):
line = allLines[i]
line.sort()
allNums = getNumsLines(allLines,-1*cfg.look_at+i,i)
h,l = histlist(getEmpyHist(cfg),allNums)
g1 = [ y for (x, y) in l[ 0:bounds[0] ] ]
g1.sort()
g1l = len(g1)
g1h = hitCount(g1, allLines[i+1])
g2 = [ y for (x, y) in l[ bounds[0]:bounds[1] ] ]
g2.sort()
g2l = len(g2)
g2h = hitCount(g2, allLines[i+1])
g3 = [ y for (x, y) in l[ bounds[1]: ] ]
g3.sort()
g3l = len(g3)
g3h = hitCount(g3, allLines[i+1])
tmp=" ".join([str(d) for d in [g1h,g2h,g3h]] )
histHits.append(tmp)
tmp = " ".join([ "%-3d"%(abs(i),),"\t"," ".join([ "%02d"%(x,) for x in line]),"\t",tmp,"\t\t", "%12d"%(comb(g1l,g1h)*comb(g2l,g2h)*comb(g3l,g3h),)])+_N
histReport.append(tmp)
outFile.write(_N)
outFile.write(_N)
outFile.write(_N)
outFile.write("\tHits per Group Histogram\n")
outFile.write("-"*30+_N)
outFile.write("\tHits\tGrouping\n")
outFile.write("-"*30+_N)
outFile.write('\n'.join(["\t%02d \t%s" % (count, num) for (count, num) in lout])+_N)
g1 = [ y for (x, y) in l[ 0:bounds[0] ] ]
g1.sort()
g1l = len(g1)
g2 = [ y for (x, y) in l[ bounds[0]:bounds[1] ] ]
g2.sort()
g2l = len(g2)
g3 = [ y for (x, y) in l[ bounds[1]: ] ]
g3.sort()
outFile.write(_N)
outFile.write(_N)
outFile.write(_N)
outFile.write("\tGroups:\n")
outFile.write("-"*30+_N)
outFile.write(' '.join([ str(x) for x in g1])+_N)
outFile.write(' '.join([ str(x) for x in g2])+_N)
outFile.write(' '.join([ str(x) for x in g3])+_N)
This should solve one of the problems... the look_at parameter is the number of draws the program will use to calculate the histogram/frequency table on. _________________ Just ME here....
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum