Sharps är skapad av experter inom spelbranschen och alla rankningar av operatörer på vår sida är gjorda med stor diskretion. Vi hoppas att de online spelbolagen som vi har valt ut faller dig i smaken. När du väljer att klicka på en utgående länk på vår sida, kan vi komma att erhålla provision, dock utan någon kostnad från din sida. Läs hela meddelandet här.
Logga in


Svara
 
LinkBack Ämnesverktyg
Gammal 2023-09-17, 13:50   #1
 
Reg.datum: jul 2012
Inlägg: 33
Sharp$: 151
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
Gammal 2023-09-19, 11:04   #2
 
Reg.datum: okt 2010
Inlägg: 957
Sharp$: 4927
Standard

'from chunkfunction import process_chunk'

Denna rad verkar vara en egendefinierad modul. Den är inte en del av standard biblioteket och går då inte att hämta och installera med pip install, så du får nog försöka få tag i författaren ändå.
Lobo är inte uppkopplad   Ge poäng Svara med citat
Gammal 2023-09-19, 17:06   #3
 
Reg.datum: jul 2012
Inlägg: 33
Sharp$: 151
Standard

Citat:
Ursprungligen postat av Lobo Visa inlägg
'from chunkfunction import process_chunk'

Denna rad verkar vara en egendefinierad modul. Den är inte en del av standard biblioteket och går då inte att hämta och installera med pip install, så du får nog försöka få tag i författaren ändå.
Hej Lobo, jag glömde bort chunkfunction då den ligger i en egen fil utanför, hoppas du får igång det nu då, här är den koden:

Kod:
import os
import itertools

def process_chunk(start, end, rowlist, pmin, pmax):
    
	process_id = os.getpid()
	print(f"Processing chunk from {start} to {end} with process ID: {process_id}",flush=True)
    
	 
	try:
		sub_gen = itertools.islice(itertools.product(*[enumerate(row) for row in rowlist]), start, end)
	except:
		print(f"Itertools failed at {start} - {end}")
		quit() 
	valid_combinations = []
	tss = 0
	for comb in sub_gen:
		tss += 1
		try:
			indices, values = zip(*comb)
		except:
			print("zip failed, with comb of:",len(comb))
			quit()
		s = sum(values)
		if pmin <= s <= pmax:
			valid_combinations.append(indices + (s,))
	return valid_combinations, tss
Tack på förhand
odds är inte uppkopplad   Ge poäng Svara med citat
Gammal 2023-09-20, 12:42   #4
 
Reg.datum: okt 2010
Inlägg: 957
Sharp$: 4927
Standard

Det låter som ett prestandaproblem som kan vara relaterat till hur minnet hanteras i koden.

Jag får en felaktig output, där många värden är 'None', vilket tyder på att något i mitt program inte fungerar som det ska. Det är säkert lokalt eftersom du inte har det problemet.

Mvh
Lobo är inte uppkopplad   Ge poäng Svara med citat
Gammal 2023-09-20, 17:11   #5
 
Reg.datum: jul 2012
Inlägg: 33
Sharp$: 151
Standard

Citat:
Ursprungligen postat av Lobo Visa inlägg
Det låter som ett prestandaproblem som kan vara relaterat till hur minnet hanteras i koden.

Jag får en felaktig output, där många värden är 'None', vilket tyder på att något i mitt program inte fungerar som det ska. Det är säkert lokalt eftersom du inte har det problemet.

Mvh
Jo, att det är något prestandaproblem har jag nog räknat ut, eftersom det saktar ner även när jag ställer ner antal workers till 1.

Hmm, jag får också felmeddelanden nu när jag testade, och jag kollade på SvS och ser att flera matcher inte är oddssatta ännu, där är nog problemet just nu.

Mvh ! O
odds är inte uppkopplad   Ge poäng Svara med citat
Svara



td