Visa ett inlägg
Gammal 2023-09-17, 13:50   #1
odds
 
Reg.datum: jul 2012
Inlägg: 33
Sharp$: 152
Standard

Python-kunnig, felsöka min kod


Jag har fått tag på en intressant kod, hoppas någon kan hjälpa mig då författaren inte längre kan nås och jag själv inte kan något om programmering.
Det är nog något som inte stämmer, i början av körningen så är det bra fart men ju längre man kör så tappar det fart och blir långsammare, vad beror detta på, jag har även testat att ställa ner antal workers men samma beteende, är detta något som ser fel ut som går att rätta till i koden ?

Här nedan följer koden, sätt följande värden:

3
200
0.00001
2
j

Mvh ! / O

Kod:
import requests
import re
import json
import itertools
import os
import time
from concurrent.futures import ProcessPoolExecutor
from chunkfunction import process_chunk


def fetchFallbackGames(furl):
	
	try: 
		response = requests.get(furl)
		html_content = response.text
	
	except:
		print(f"Kan inte komma hämta data från: {furl}. Avbryter.")
		quit()
	
	try:
		json_obj = json.loads(html_content)
		gd = json_obj["responses"][0]["draw"]["drawEvents"]

	except:
		print("Kunde inte extrahera data, från:")
		print (json_obj)
		quit()
	
	return gd	


def main():
	
	gamemode = int(input("Spelform? 1= Stryktipset 2= Europatipset 3= Fullträff "))

	if not gamemode in [1,2,3]:	
		print("Endast 1-2 möjliga val. Avbryter.")
		quit()

	pgoal = float(input("Önskad summa (t.ex. 200.0) ? "))
	pdev = float(input("Tolerabel +/- avvikelse decimaltal (t.ex. 0.00001)? "))
	pmin = pgoal - pdev
	pmax = pgoal + pdev

	mde = int(input("Tryck 1 för text-fil och 2 för CSV-fil: "))

	if not mde in [1,2]:
		print("Endast 1 eller 2 möjliga val. Avbryter.")
		quit()

	
	url = urls[gamemode]
	
	outfile = outfiles[mde]

	try: 
		response = requests.get(url)
		html_content = response.text

	except:
		print(f"Kan inte komma hämta data från: {url}. Avbryter.")
		quit()

	pattern = r'_svs\.tipsen\.data\.preloadedState\s*=\s*(\{.*\});'

	try:
		match = re.search(pattern, html_content)
		json_str = match.group(1)
		json_obj = json.loads(json_str)
		gameDict = json_obj["EventTypeStatistic"]
		gameKeys = list(dict.keys(gameDict))

	except:
		print("Kunde inte extrahera data")
		quit()

	signlists = []
	rowlist = []
	fallback_mode = False

	if gamemode == 3:  # om fullträff, sätt upp lista utifrån 13 rader
		draws=json_obj["Draws"]["entities"]
	
		try:
			drawsKey = list(dict.keys(draws))[0]
			omg=draws[drawsKey]["drawNumber"] # hämta omgångsnr
		except IndexError:
			print("Inte möjligt att hämta Fullträff-omgång.")
			jn = input("Tryck J för att hämta historiska data för testberäkning: ").lower()
			if not "j" == jn:
				quit()
			
			try:
				match = re.search(r'_cmps\.data\.navigation\s*=\s*(\{.*\})', html_content)
				json_str = match.group(1)
				jobj = json.loads(json_str)
				omg = str(jobj['items'][2]['items'][2]['jackpot'][0]['drawNumber']-1) # ta fram förra omgångens nummer

			except:
				omg = fallback_omg
			
			fallback_mode = True
			gameDict = fetchFallbackGames(fallback_url)
			gameKeys = list(range(0,13))			
			
		print(f"Fullträff omgång {omg}:")	
	
	else:   # annars sätt upp lista utifrån 3 tecken
		for _ in range(0,3):
			signlists.append([])

	if (len(gameKeys) == 0):
		print("Finns ingen data att hämta. Avbryter.")
		quit()

	for gameKey in gameKeys: # iterera över alla 13 matcher
	
		numAlts=3
		if gamemode==3:  # Fullträff
			numAlts=6
	
		if fallback_mode == False:
			game = gameDict[gameKey]["odds"]["current"]["value"]  # hämtar odds-värden från Fullträff-sidan
		else:
			game = gameDict[gameKey]
		
		gamesum = 0.0
		
		floats = []
		fgame = []
		
		for i in range(0,numAlts):
			if fallback_mode == False:
				t = game[i]
			else:
				t = game["betMetrics"]["values"][i]["odds"]["odds"].replace(",",".")
			if t == None:
				print ("None-error",gameDict[gameKey])
				quit()
			#print(t)
			f = 100.0/float(t) # konvertera oddset 100/o
			floats.append(f)
		
		gamesum = sum(floats)
	
		for ix,o in enumerate(floats):
			newo = 100.0 * o / gamesum  # normalfördela fullträff-oddsen så att summan blir 100.0
			if ix<numAlts:
				fgame.append(newo)

		if gamemode==3:
			rowlist.append(fgame)
		
		else:
			for ix,perc in enumerate(fgame):
				signlists[ix].append(perc)

	if gamemode<3:
	
		P = { "1": signlists[0], "X": signlists[1], "2": signlists[2] } 
		rows = itertools.product(*(['1X2'] * 13))

		cn = 0

		with open(outfile, 'w') as f:  
			for row in rows:
				try:
					percentage = sum(P[result][n] for (n, result) in enumerate(row))
				
				except:
					print("Sum error", P)
					quit()
		
				if  pmin <= percentage <= pmax:
					cn += 1
					if mde==1:
						f.write("E,"+','.join(row)+"\n")
					if mde==2:
						f.write(','.join(row + (str(percentage),))+"\n")
	else:
	
		cn = 0
		tsts = 0
		valid_combinations = []
		
		default_workers = os.cpu_count()
		print(f"Default number of workers: {default_workers}")

		chunk_size = 500000  # You can adjust the chunk size
		total_size = 6 ** 13  # 6^13 combinations
		chunks = [(i, min(i + chunk_size, total_size)) for i in range(0, total_size, chunk_size)]
	
		print ("Length of chunks:",len(chunks))
		
		start_time = time.time()
	
		if multi_process:
			
			with ProcessPoolExecutor(max_workers=max_num_of_workers) as executor:
				print(f"Executor is using {executor._max_workers} workers")
			
				for chunk_result, chunk_tsts in executor.map(process_chunk, [start for start, end in chunks], [end for start, end in chunks], itertools.repeat(rowlist), itertools.repeat(pmin), itertools.repeat(pmax)):
   
					tsts += chunk_tsts
					valid_combinations.extend(chunk_result)
					cn += len(chunk_result)

					if tsts % 1000000 == 0:
						print(int(tsts / 1000000), "million iterations,", cn, "rows found")

					if cn >= maxcoupons:
						break
	
		else:
			
			for start, end in chunks:
				chunk_result, chunk_tsts = process_chunk(start, end, rowlist, pmin, pmax)
				tsts += chunk_tsts
				valid_combinations.extend(chunk_result)
				cn += len(chunk_result)
        
				if tsts % 1000000 == 0:
					print(int(tsts / 1000000), "million iterations,", cn, "rows found")
            
				if cn >= maxcoupons:
					break
			
		end_time = time.time()
		taken_time = round(end_time - start_time,2)
		ave_time = round(taken_time/(tsts/1000000),4)
		print(f"Time taken: {taken_time} seconds")
		print(f"Avg. time: {ave_time} sec/million iterations")
		
		
		with open(outfile, 'w') as f:
		
			f.write(f"Fulltraff,Omg={omg}\n") # första raden 
		
			for ix,comb in enumerate(valid_combinations):
			
				if mde == 1 and ix<maxcoupons: # TXT-läge
					comb=list(comb)
					comb.pop() # ta bort summa som inte används i TXT-läge
					f.write("E,"+','.join(str(nm) for nm in comb)+"\n")
				
				elif mde == 2 and ix<maxcoupons: # CSV-läge
					f.write(','.join(str(nm) for nm in comb)+"\n")

	cn=min(cn,maxcoupons)
	
	print(f"{outfile} skapad med {cn} rader!")

if __name__ == '__main__':
	# konstanter och definitioner

	maxcoupons = 10000 # högsta antal rader (100000 är Sv.Spels gränd)
	max_num_of_workers = 8 # ändras för olika antal parallella processer
	outfiles = ["", "tips.txt", "tips.csv"] # ändras för andra filnamn
	urls = ["", "https://spela.svenskaspel.se/stryktipset" , "https://spela.svenskaspel.se/europatipset", "https://spela.svenskaspel.se/fulltraff"]
	multi_process = True  # ändra till True för att köra flera processer samtidigt

	fallback_omg = "50" 
	fallback_url = f"https://api.spela.svenskaspel.se/multifetch?urls=/draw/1/fulltraff/draws/{fallback_omg}" 

	main()
odds är inte uppkopplad   Ge poäng Svara med citat