Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development #4

Merged
merged 2 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
2 changes: 1 addition & 1 deletion src/datetime_test.py → helper/datetime_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from src import deadline
from helper import deadline
from datetime import datetime
from datetime import timedelta

Expand Down
File renamed without changes.
File renamed without changes.
23 changes: 10 additions & 13 deletions kicktippbb.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@
from docopt import docopt
from robobrowser import RoboBrowser

import src.prediction
from src.deadline import is_before_dealine, timedelta_tostring
from src.match import Match
import predictors.base
from helper.deadline import is_before_dealine, timedelta_tostring
from helper.match import Match

URL_BASE = 'http://www.kicktipp.de'
URL_LOGIN = URL_BASE + '/info/profil/login'
Expand Down Expand Up @@ -177,8 +177,8 @@ def place_bets(browser: RoboBrowser, communities: list, predictor, override=Fals

homebet,roadbet = predictor.predict(match)
print("{0} - betting {1}:{2}".format(match, homebet, roadbet))
submitform[field_hometeam.attrs['name']] = homebet
submitform[field_roadteam.attrs['name']] = roadbet
submitform[field_hometeam.attrs['name']] = str(homebet)
submitform[field_roadteam.attrs['name']] = str(roadbet)
if not dryrun:
browser.submit_form(submitform, submit='submitbutton')
else:
Expand All @@ -201,20 +201,17 @@ def choose_predictor(predictor_param, predictors):
else:
exit('Unknown predictor: {}'.format(predictor_param))
else:
predictor = predictors['SimplePredictor']()
# Just get the first predictor in the dict and instanciate it
predictor = next(iter(predictors.values()))()
print("Using predictor: "+type(predictor).__name__)
return predictor


def get_predictors():
return dict((name, obj) for name, obj in inspect.getmembers(sys.modules['prediction'], predicate=inspect.isclass) if 'predict' in [x for x, y in inspect.getmembers(obj, predicate=inspect.isfunction) if x == 'predict'])


def main(arguments):
browser = RoboBrowser(parser="html.parser")

validate_arguments(arguments)
predictors = get_predictors()
predictors_ = predictors.base.get_predictors()

# Log in to kicktipp and print out the login cookie value
if arguments['--get-login-token']:
Expand All @@ -224,7 +221,7 @@ def main(arguments):

# Just list the predictors at hand and exit
if arguments['--list-predictors']:
[print(key) for key in predictors.keys()]
[print(key) for key in predictors_.keys()]
exit(0)

# Use login token pass by argument or let the caller log in right here
Expand All @@ -244,7 +241,7 @@ def main(arguments):

# Which prediction method is used
predictor_param = arguments['--predictor'] if '--predictor' in arguments else None
predictor = choose_predictor(predictor_param, predictors)
predictor = choose_predictor(predictor_param, predictors_)

# Place bets
place_bets(browser, communities, predictor,
Expand Down
Empty file added predictors/__init__.py
Empty file.
27 changes: 27 additions & 0 deletions predictors/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from helper.match import Match
import pkgutil
import importlib
import os.path

class PredictorBase():
"""
Predictor base class
all actual predictors shall derive from this class and implement the predict method
"""
def predict(self, match: Match):
"""
predict a match by returning the number of goals as tuple (home_goals, road_goals)
"""
raise NotImplementedError

def explore_package():
return [sub_module_name for _, sub_module_name, _ in pkgutil.iter_modules([os.path.dirname(__file__)])]

def get_predictors():
"""
Get all predictors from all modules in this folder
return: dict{name:str, cls:class}
"""
for mod in explore_package():
importlib.import_module('.'+mod, __package__)
return {cls.__name__: cls for cls in PredictorBase.__subclasses__()}
31 changes: 4 additions & 27 deletions src/prediction.py → predictors/calculationpredictor.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
"""
This module holds all preditors used by kicktipp bet bot.
A generator is a class that defines a method 'predict' with one argument.
Simple preditor for kicktipp bet bot.
"""
from src.match import Match
from helper.match import Match
from .base import PredictorBase
import random
import math


class SimplePredictor(object):
DOMINATION_THRESHOLD = 6
DRAW_THRESHOLD = 1.2

def predict(self, match: Match):

diff = math.fabs(match.rate_home - match.rate_road)
home_wins = match.rate_home < match.rate_road

if diff < self.DRAW_THRESHOLD:
return (1, 1)

if diff >= self.DOMINATION_THRESHOLD:
result = (3, 1)
elif diff >= self.DOMINATION_THRESHOLD / 2:
result = (2, 1)
else:
result = (1, 0)

return result if home_wins else tuple(reversed(result))


class CalculationPredictor(object):
class CalculationPredictor(PredictorBase):
MAX_GOALS = 5
DOMINATION_THRESHOLD = 9
DRAW_THRESHOLD = 1.3
Expand Down
14 changes: 14 additions & 0 deletions predictors/predictors_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest
from . import base

def test_scanpreditors():
subpackages = base.explore_package()
assert len(subpackages) > 0
pass

def test_instanciatepreditors():
predictors = base.get_predictors()
assert 'SimplePredictor' in predictors.keys()
predictorobj = predictors['SimplePredictor']()
assert issubclass(type(predictorobj), base.PredictorBase)
pass
29 changes: 29 additions & 0 deletions predictors/simplepredictor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Simple preditor for kicktipp bet bot.
"""
from helper.match import Match
from .base import PredictorBase
import random
import math


class SimplePredictor(PredictorBase):
DOMINATION_THRESHOLD = 6
DRAW_THRESHOLD = 1.2

def predict(self, match: Match):

diff = math.fabs(match.rate_home - match.rate_road)
home_wins = match.rate_home < match.rate_road

if diff < self.DRAW_THRESHOLD:
return (1, 1)

if diff >= self.DOMINATION_THRESHOLD:
result = (3, 1)
elif diff >= self.DOMINATION_THRESHOLD / 2:
result = (2, 1)
else:
result = (1, 0)

return result if home_wins else tuple(reversed(result))
Loading