Sharps.se - Sveriges bästa sportsbettingforum med rekar, spelförslag och bettingtips

Sharps.se - Sveriges bästa sportsbettingforum med rekar, spelförslag och bettingtips (https://www.sharps.se/forums/)
-   Tänkarhörnan (https://www.sharps.se/forums/taenkarhoernan/)
-   -   Python-kunnig, felsöka min kod (https://www.sharps.se/forums/taenkarhoernan/57821-python-kunnig-felsoeka-min-kod/)

odds 2023-09-17 13:50

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()


Lobo 2023-09-19 11:04

'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å.

odds 2023-09-19 17:06

Citat:

Ursprungligen postat av Lobo (Inlägg 813654)
'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 :)

Lobo 2023-09-20 12:42

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

odds 2023-09-20 17:11

Citat:

Ursprungligen postat av Lobo (Inlägg 813693)
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



Powered by vBulletin & vBadvanced CMPS
Design, Logos, etc Copyright © Sharps.se, 2010-2011. All Rights Reserved