<commit_before>"""
    bux_grader_framework.worker
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~

    This module defines worker processes for handling submissions.
"""

import logging
import multiprocessing
import threading
import time

from multiprocessing.dummy import Pool

from string import Template
from statsd import statsd

from .exceptions import XQueueException

log = logging.getLogger(__name__)

FAIL_RESPONSE = Template("""

The external grader was unable to process this submission.
Please contact course staff.

Reason:

$reason

""")

class XQueueWorker(multiprocessing.Process):
    """ Polls XQueue for submissions.

        :param str queue_name: XQueue queue name
        :param Grader grader: a configured grader instance

        Submissions pulled down from XQueue are transferred to an internal work
        queue for evaluation by an :class:`EvaluatorWorker`.
    """

    def __init__(self, queue_name, grader):
        super(XQueueWorker, self).__init__()

        self.queue_name = queue_name
        self.grader = grader

        self.xqueue = grader.xqueue()
        self.queue = grader.producer()

        self._xqueue_pool_size = grader.config['XQUEUE_POOL_SIZE']
        self._poll_interval = grader.config['XQUEUE_POLL_INTERVAL']
        self._default_evaluator = grader.config['DEFAULT_EVALUATOR']

        # The underyling pika BlockingConnection used for the work queue is not
        # thread safe. We utilize a lock to prevent concurrent access while
        # fetching and enqueuing submissions.
        self._queue_lock = threading.Lock()

        # For stopping of the run loop from the main process
        self._stop = multiprocessing.Event()
        self.xqueue.login()

    def run(self):
        """ Polls XQueue for submissions. """
        log.info("XQueue worker (PID=%s) is polling for submissions...",
                 self.pid)

        self.queue.connect()
        self.pool = Pool(processes=self._xqueue_pool_size)

        try:
            while not self._stop.is_set():
                # Pop any pending submissions and transfer to work queue
                submit_count = self.xqueue.get_queuelen(self.queue_name)

                if submit_count:
                    self.get_submissions(submit_count)
                else:
                    # Sleep if no submissions are present
                    # Uses queue.sleep which pings RabbitMQ to prevent
                    # heartbeat_interval-related timeouts.
                    with self._queue_lock:
                        self.queue.sleep(self._poll_interval)
        except (KeyboardInterrupt, SystemExit):
            pass

        self.pool.close()
        self.pool.join()
        self.queue.close()

    def get_submissions(self, submit_count):
        """ Fetches submission from XQueue asynchronously """
        fetched = 0
        while fetched < submit_count:
            self.pool.apply_async(self.xqueue.get_submission,
                                  (self.queue_name,),
                                  callback=self.enqueue_submission)
            fetched += 1

    def enqueue_submission(self, submission):
        """ Adds a submision popped from XQueue to an internal work queue.

        This method is called by ``apply_async`` when an XQueue submission
        request has completed.

        """

        # Bail early if no submission was received
        if not submission:
            return

        received_time = time.time()
        submit_time = submission['xqueue_body']['student_info']['submission_time']

        # For load testing:
        #
        #   The load test suite uses timestamps for submission_time. The LMS uses
        #   a formatted date string. This block only logs submission delays when the
        #   former is being used as the date string resolution isn't high enough to
        #   be useful.
        #
        if isinstance(submit_time, float):
            delay = int((received_time - submit_time)*1000.0)
            log.info("Submitted: %d Received: %d Delay: %d", submit_time, received_time, delay)
            statsd.timing('bux_grader_framework.get_submission_delay', delay)

        frame = {"received_by": self.pid, "received_time": received_time}
        header = submission['xqueue_header']
        payload = submission['xqueue_body']['grader_payload']

        log.info("Submission #%d received from XQueue", header['submission_id'])

        # Assert the grader payload is a dict
        if not isinstance(payload, dict):
            self.push_failure("Grader payload could not be parsed", submission)
            return False

        # Determine which evaluator queue the submission should be routed to
        evaluator = payload.get('evaluator', self._default_evaluator)

        # Tempory back compat for edge grader
        if not evaluator:
            evaluator = payload.get('grader')

        # Ensure evaluator is registered with this grader
        if evaluator and self.grader.is_registered_evaluator(evaluator):
            frame["submission"] = submission
            # Push to evaluator work queue
            lock_before = time.time()
            with self._queue_lock:
                lock_elapsed = int((time.time() - lock_before)*1000.0)
                statsd.timing('bux_grader_framework.xqueue_lock_wait', lock_elapsed)

                # Enqueue submission for EvaluationWorker
                self.queue.put(evaluator, frame)
        else:
            # Notify LMS that the submission could not be handled
            self.push_failure("Evaluator could not be found: {}".format(
                              evaluator), submission)

    def push_failure(self, reason, submission):
        """ Sends a failing response to XQueue

            :param str reason: the reason for the failure
            :param dict submission: the submission that could not be handled

        """
        submit_id = submission['xqueue_header']['submission_id']
        response = {
            "correct": False,
            "score": 0,
            "msg": FAIL_RESPONSE.substitute(reason=reason)
        }
        log.error("Could not handle submission #%d: %s", submit_id, reason)
        self.xqueue.put_result(submission, response)

    def status(self):
        log.info("Checking XQueue status...")
        try:
            status = self.xqueue.status()
        except XQueueException:
            return False
        return status

    def stop(self):
        """ Gracefully shuts down worker process """
        self._stop.set()

class EvaluatorWorker(multiprocessing.Process):
    """ Evaluates submissions pulled from the internal work queue.

        :param str evaluator: name of the evaluator class for this worker
        :param Grader grader: a configured grader instance

        If the evaluation is successful, the result is posted to XQueue.

        If the grader is unable to process the submission the submission is
        requeued.

    """
    def __init__(self, evaluator, grader):
        super(EvaluatorWorker, self).__init__()

        self.grader = grader

        self.evaluator = self.grader.evaluator(evaluator)
        self.xqueue = self.grader.xqueue()
        self.queue = self.grader.consumer()

        self._eval_thread_count = self.grader.config['EVAL_THREAD_COUNT']

        # For stopping of the run loop from the main process
        self._stop = multiprocessing.Event()

    def run(self):
        """ Polls submission queue. """
        log.info("Evaluator worker '%s' (PID=%s) awaiting submissions...",
                 self.evaluator.name, self.pid)

        # Start consuming in a separate thread
        consumer_thread = threading.Thread(target=self.queue.consume,
                                           args=(self.evaluator.name,
                                                 self.handle_submission,
                                                 self._eval_thread_count))
        consumer_thread.daemon = True
        consumer_thread.start()

        # Blocks until stop event is set by main grader process
        try:
            self._stop.wait()
        except (KeyboardInterrupt, SystemExit):
            pass

        # Stop consumer thread by cancelling queue consumer and
        # closing RabbitMQ connection
        self.queue.stop()

        # Wait for consumer thread to exit cleanly
        consumer_thread.join()

    def handle_submission(self, frame, on_complete):
        """ Handles a submission popped off the internal work queue.

        Invokes ``self.evaluator.evaluate()`` to generate a response.

        """
        submission = frame["submission"]
        submission_id = submission['xqueue_header']['submission_id']
        success = True
        log.info("Evaluating submission #%d", submission_id)

        try:
            with statsd.timer('bux_grader_framework.evaluate'):
                result = self.evaluator.evaluate(submission)
        except Exception:
            log.exception("Could not evaluate submission: %s", submission)
            success = False

        # Note time spent in grader (between /xqueue/get_submission/ and
        # /xqueue/put_result/)
        elapsed_time = int((time.time() - frame["received_time"])*1000.0)
        statsd.timing('bux_grader_framework.total_time_spent', elapsed_time)
        log.info("Submission #%d evaluated in %0.3fms",
                 submission_id, elapsed_time)

        if success and result:
            try:
                success = self.xqueue.put_result(submission, result)
            except Exception:
                log.exception("Could not post reply to XQueue.")
                success = False

        # Notifies queue to ack / nack message
        on_complete(success)

    def status(self):
        log.info("Checking Evaluator status...")
        return self.evaluator.status()

    def stop(self):
        """ Gracefully shuts down worker process """
        self._stop.set()
<commit_msg>Cleanup in XQueueWorker status method.<commit_after>"""
    bux_grader_framework.worker
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~

    This module defines worker processes for handling submissions.
"""

import logging
import multiprocessing
import threading
import time

from multiprocessing.dummy import Pool

from string import Template
from statsd import statsd

from .exceptions import XQueueException

log = logging.getLogger(__name__)

FAIL_RESPONSE = Template("""

The external grader was unable to process this submission.
Please contact course staff.

Reason:

$reason

""")

class XQueueWorker(multiprocessing.Process):
    """ Polls XQueue for submissions.

        :param str queue_name: XQueue queue name
        :param Grader grader: a configured grader instance

        Submissions pulled down from XQueue are transferred to an internal work
        queue for evaluation by an :class:`EvaluatorWorker`.
    """

    def __init__(self, queue_name, grader):
        super(XQueueWorker, self).__init__()

        self.queue_name = queue_name
        self.grader = grader

        self.xqueue = grader.xqueue()
        self.queue = grader.producer()

        self._xqueue_pool_size = grader.config['XQUEUE_POOL_SIZE']
        self._poll_interval = grader.config['XQUEUE_POLL_INTERVAL']
        self._default_evaluator = grader.config['DEFAULT_EVALUATOR']

        # The underyling pika BlockingConnection used for the work queue is not
        # thread safe. We utilize a lock to prevent concurrent access while
        # fetching and enqueuing submissions.
        self._queue_lock = threading.Lock()

        # For stopping of the run loop from the main process
        self._stop = multiprocessing.Event()

    def run(self):
        """ Polls XQueue for submissions. """
        log.info("XQueue worker (PID=%s) is polling for submissions...",
                 self.pid)

        self.xqueue.login()
        self.queue.connect()
        self.pool = Pool(processes=self._xqueue_pool_size)

        try:
            while not self._stop.is_set():
                # Pop any pending submissions and transfer to work queue
                submit_count = self.xqueue.get_queuelen(self.queue_name)

                if submit_count:
                    self.get_submissions(submit_count)
                else:
                    # Sleep if no submissions are present
                    # Uses queue.sleep which pings RabbitMQ to prevent
                    # heartbeat_interval-related timeouts.
                    with self._queue_lock:
                        self.queue.sleep(self._poll_interval)
        except (KeyboardInterrupt, SystemExit):
            pass

        self.pool.close()
        self.pool.join()
        self.queue.close()

    def get_submissions(self, submit_count):
        """ Fetches submission from XQueue asynchronously """
        fetched = 0
        while fetched < submit_count:
            self.pool.apply_async(self.xqueue.get_submission,
                                  (self.queue_name,),
                                  callback=self.enqueue_submission)
            fetched += 1

    def enqueue_submission(self, submission):
        """ Adds a submision popped from XQueue to an internal work queue.

        This method is called by ``apply_async`` when an XQueue submission
        request has completed.

        """

        # Bail early if no submission was received
        if not submission:
            return

        received_time = time.time()
        submit_time = submission['xqueue_body']['student_info']['submission_time']

        # For load testing:
        #
        #   The load test suite uses timestamps for submission_time. The LMS uses
        #   a formatted date string. This block only logs submission delays when the
        #   former is being used as the date string resolution isn't high enough to
        #   be useful.
        #
        if isinstance(submit_time, float):
            delay = int((received_time - submit_time)*1000.0)
            log.info("Submitted: %d Received: %d Delay: %d", submit_time, received_time, delay)
            statsd.timing('bux_grader_framework.get_submission_delay', delay)

        frame = {"received_by": self.pid, "received_time": received_time}
        header = submission['xqueue_header']
        payload = submission['xqueue_body']['grader_payload']

        log.info("Submission #%d received from XQueue", header['submission_id'])

        # Assert the grader payload is a dict
        if not isinstance(payload, dict):
            self.push_failure("Grader payload could not be parsed", submission)
            return False

        # Determine which evaluator queue the submission should be routed to
        evaluator = payload.get('evaluator', self._default_evaluator)

        # Tempory back compat for edge grader
        if not evaluator:
            evaluator = payload.get('grader')

        # Ensure evaluator is registered with this grader
        if evaluator and self.grader.is_registered_evaluator(evaluator):
            frame["submission"] = submission
            # Push to evaluator work queue
            lock_before = time.time()
            with self._queue_lock:
                lock_elapsed = int((time.time() - lock_before)*1000.0)
                statsd.timing('bux_grader_framework.xqueue_lock_wait', lock_elapsed)

                # Enqueue submission for EvaluationWorker
                self.queue.put(evaluator, frame)
        else:
            # Notify LMS that the submission could not be handled
            self.push_failure("Evaluator could not be found: {}".format(
                              evaluator), submission)

    def push_failure(self, reason, submission):
        """ Sends a failing response to XQueue

            :param str reason: the reason for the failure
            :param dict submission: the submission that could not be handled

        """
        submit_id = submission['xqueue_header']['submission_id']
        response = {
            "correct": False,
            "score": 0,
            "msg": FAIL_RESPONSE.substitute(reason=reason)
        }
        log.error("Could not handle submission #%d: %s", submit_id, reason)
        self.xqueue.put_result(submission, response)

    def status(self):
        """ Returns whether or not XQueue / RabbitMQ are reachable. """

        # Sanity check of RabbitMQ connection
        try:
            self.queue.connect()
            self.queue.sleep(1)
            self.queue.close()
        except Exception:
            log.exception("XQueueWorker could not connect to RabbitMQ: ")
            return False

        try:
            status = self.xqueue.status()
        except XQueueException:
            return False

        return status

    def stop(self):
        """ Gracefully shuts down worker process """
        self._stop.set()

class EvaluatorWorker(multiprocessing.Process):
    """ Evaluates submissions pulled from the internal work queue.

        :param str evaluator: name of the evaluator class for this worker
        :param Grader grader: a configured grader instance

        If the evaluation is successful, the result is posted to XQueue.

        If the grader is unable to process the submission the submission is
        requeued.

    """
    def __init__(self, evaluator, grader):
        super(EvaluatorWorker, self).__init__()

        self.grader = grader

        self.evaluator = self.grader.evaluator(evaluator)
        self.xqueue = self.grader.xqueue()
        self.queue = self.grader.consumer()

        self._eval_thread_count = self.grader.config['EVAL_THREAD_COUNT']

        # For stopping of the run loop from the main process
        self._stop = multiprocessing.Event()

    def run(self):
        """ Polls submission queue. """
        log.info("Evaluator worker '%s' (PID=%s) awaiting submissions...",
                 self.evaluator.name, self.pid)

        # Start consuming in a separate thread
        consumer_thread = threading.Thread(target=self.queue.consume,
                                           args=(self.evaluator.name,
                                                 self.handle_submission,
                                                 self._eval_thread_count))
        consumer_thread.daemon = True
        consumer_thread.start()

        # Blocks until stop event is set by main grader process
        try:
            self._stop.wait()
        except (KeyboardInterrupt, SystemExit):
            pass

        # Stop consumer thread by cancelling queue consumer and
        # closing RabbitMQ connection
        self.queue.stop()

        # Wait for consumer thread to exit cleanly
        consumer_thread.join()

    def handle_submission(self, frame, on_complete):
        """ Handles a submission popped off the internal work queue.

        Invokes ``self.evaluator.evaluate()`` to generate a response.

        """
        submission = frame["submission"]
        submission_id = submission['xqueue_header']['submission_id']
        success = True
        log.info("Evaluating submission #%d", submission_id)

        try:
            with statsd.timer('bux_grader_framework.evaluate'):
                result = self.evaluator.evaluate(submission)
        except Exception:
            log.exception("Could not evaluate submission: %s", submission)
            success = False

        # Note time spent in grader (between /xqueue/get_submission/ and
        # /xqueue/put_result/)
        elapsed_time = int((time.time() - frame["received_time"])*1000.0)
        statsd.timing('bux_grader_framework.total_time_spent', elapsed_time)
        log.info("Submission #%d evaluated in %0.3fms",
                 submission_id, elapsed_time)

        if success and result:
            try:
                success = self.xqueue.put_result(submission, result)
            except Exception:
                log.exception("Could not post reply to XQueue.")
                success = False

        # Notifies queue to ack / nack message
        on_complete(success)

    def status(self):
        log.info("Checking Evaluator status...")
        return self.evaluator.status()

    def stop(self):
        """ Gracefully shuts down worker process """
        self._stop.set()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""Qt dock window."""

# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------

from collections import defaultdict
from functools import partial
import logging

from .qt import (
    QApplication, QWidget, QDockWidget, QStatusBar, QMainWindow, QMessageBox, Qt,
    QSize, QMetaObject, _wait, _prompt, _show_box)
from .state import GUIState, _gui_state_path, _get_default_state_path
from .actions import Actions, Snippets
from phylib.utils import emit, connect

logger = logging.getLogger(__name__)

# -----------------------------------------------------------------------------
# GUI main window
# -----------------------------------------------------------------------------

def _try_get_matplotlib_canvas(view):
    # Get the Qt widget from a matplotlib figure.
    try:
        from matplotlib.pyplot import Figure
        from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
        if isinstance(view, Figure):
            view = FigureCanvasQTAgg(view)
        # Case where the view has a .figure property which is a matplotlib figure.
        elif isinstance(getattr(view, 'figure', None), Figure):
            view = FigureCanvasQTAgg(view.figure)
    except ImportError as e:  # pragma: no cover
        logger.warning("Import error: %s", e)
    return view

def _try_get_opengl_canvas(view):
    """Convert from QOpenGLWindow to QOpenGLWidget."""
    from phy.plot.base import BaseCanvas
    if isinstance(view, BaseCanvas):
        return QWidget.createWindowContainer(view)
    elif isinstance(getattr(view, 'canvas', None), BaseCanvas):
        return QWidget.createWindowContainer(view.canvas)
    return view

class DockWidget(QDockWidget):
    def closeEvent(self, e):
        """Qt slot when the window is closed."""
        emit('close_dock_widget', self)
        super(DockWidget, self).closeEvent(e)

def _create_dock_widget(widget, name, closable=True, floatable=True):
    # Create the gui widget.
    dock_widget = DockWidget()
    dock_widget.setObjectName(name)
    dock_widget.setWindowTitle(name)
    dock_widget.setWidget(widget)

    # Set gui widget options.
    options = QDockWidget.DockWidgetMovable
    if closable:
        options = options | QDockWidget.DockWidgetClosable
    if floatable:
        options = options | QDockWidget.DockWidgetFloatable

    dock_widget.setFeatures(options)
    dock_widget.setAllowedAreas(Qt.LeftDockWidgetArea |
                                Qt.RightDockWidgetArea |
                                Qt.TopDockWidgetArea |
                                Qt.BottomDockWidgetArea
                                )

    return dock_widget

def _get_dock_position(position):
    return {'left': Qt.LeftDockWidgetArea,
            'right': Qt.RightDockWidgetArea,
            'top': Qt.TopDockWidgetArea,
            'bottom': Qt.BottomDockWidgetArea,
            }[position or 'right']

def _prompt_save():  # pragma: no cover
    """Show a prompt asking the user whether he wants to save or not.

    Output is 'save', 'cancel', or 'close'

    """
    b = _prompt(
        "Do you want to save your changes before quitting?",
        buttons=['save', 'cancel', 'close'], title='Save')
    return _show_box(b)

class GUI(QMainWindow):
    """A Qt main window holding docking Qt.

    `GUI` derives from `QMainWindow`.

    Events
    ------

    close
    show
    add_view
    close_view

    """
    def __init__(self,
                 position=None,
                 size=None,
                 name=None,
                 subtitle=None,
                 view_creator=None,
                 view_count=None,
                 default_views=None,
                 config_dir=None,
                 **kwargs
                 ):
        # HACK to ensure that closeEvent is called only twice (seems like a
        # Qt bug).
        self._closed = False
        if not QApplication.instance():  # pragma: no cover
            raise RuntimeError("A Qt application must be created.")
        super(GUI, self).__init__()
        QMetaObject.connectSlotsByName(self)
        self.setDockOptions(QMainWindow.AllowTabbedDocks |
                            QMainWindow.AllowNestedDocks
                            )
        self.setAnimated(False)

        logger.debug("Creating GUI.")

        self._set_name(name, str(subtitle))
        position = position or (200, 200)
        size = size or (800, 600)
        self._set_pos_size(position, size)

        # Registered functions.
        self._registered = {}

        # List of attached Actions instances.
        self.actions = []

        # Mapping {name: menuBar}.
        self._menus = {}
        self.file_actions = Actions(self, name='File', menu='&File')
        self.edit_actions = Actions(self, name='Edit', menu='&Edit')
        self.view_actions = Actions(self, name='View', menu='&View')
        self.help_actions = Actions(self, name='Help', menu='&Help')

        # Views,
        self._views = []
        self._view_class_indices = defaultdict(int)  # Dictionary {view_name: next_usable_index}

        # Create the GUI state.
        state_path = _gui_state_path(self.name, config_dir=config_dir)
        default_state_path = kwargs.pop('default_state_path', _get_default_state_path(self))
        self.state = GUIState(state_path, default_state_path=default_state_path, **kwargs)

        # View creator: dictionary {view_class: function_that_adds_view}
        self.view_creator = view_creator or {}
        # View count: take the requested one, or the GUI state one.
        self._requested_view_count = (
            view_count if view_count is not None else self.state.get('view_count', {}))
        # If there is still no view count, use a default one.
        self._requested_view_count = self._requested_view_count or {
            view_name: 1 for view_name in default_views or ()}

        # Status bar.
        self._lock_status = False
        self._status_bar = QStatusBar(self)
        self.setStatusBar(self._status_bar)

        # Create and attach snippets.
        self.snippets = Snippets(self)

        @connect(sender=self)
        def on_show(sender):
            logger.debug("Load the geometry state.")
            gs = self.state.get('geometry_state', None)
            self.restore_geometry_state(gs)

    def _set_name(self, name, subtitle):
        if name is None:
            name = self.__class__.__name__
        title = name if not subtitle else name + ' - ' + subtitle
        self.setWindowTitle(title)
        self.setObjectName(name)
        # Set the name in the GUI.
        self.name = name

    def _set_pos_size(self, position, size):
        if position is not None:
            self.move(position[0], position[1])
        if size is not None:
            self.resize(QSize(size[0], size[1]))

    def set_default_actions(self):
        # File menu.
        @self.file_actions.add(shortcut='ctrl+s')
        def save():
            emit('request_save', self)

        @self.file_actions.add(shortcut='ctrl+q')
        def exit():
            """Close the GUI."""
            self.close()

        # Add "Add view" action.
        print(self.view_creator)
        for view_name in sorted(self.view_creator.keys()):
            self.view_actions.add(
                partial(self._create_and_add_view, view_name),
                submenu='&New view',
                name='Add %s' % view_name,
                show_shortcut=False)
        self.view_actions.separator()

        # Help menu.
        @self.help_actions.add(shortcut=('HelpContents', 'h'))
        def show_all_shortcuts():
            """Show the shortcuts of all actions."""
            for actions in self.actions:
                actions.show_shortcuts()

        @self.help_actions.add(shortcut='?')
        def about():  # pragma: no cover
            """Display an about dialog."""
            from phy import __version_git__
            msg = "phy {} v{}".format(self.name, __version_git__)
            try:
                from phylib import __version__
                msg += "\nphylib v{}".format(__version__)
            except ImportError:
                pass
            QMessageBox.about(self, "About", msg)

    # Events
    # -------------------------------------------------------------------------

    def closeEvent(self, e):
        """Qt slot when the window is closed."""
        if self._closed:
            return
        _wait(250)
        res = emit('close', self)
        # Discard the close event if False is returned by one of the callback
        # functions.
        if False in res:  # pragma: no cover
            e.ignore()
            return
        super(GUI, self).closeEvent(e)
        self._closed = True

        # Save the state to disk when closing the GUI.
        logger.debug("Save the geometry state.")
        gs = self.save_geometry_state()
        self.state['geometry_state'] = gs
        self.state['view_count'] = self.view_count
        self.state.save()

    def show(self):
        """Show the window."""
        emit('show', self)
        super(GUI, self).show()

    # Views
    # -------------------------------------------------------------------------

    @property
    def views(self):
        return self._views

    @property
    def view_count(self):
        """Dictionary {view_class: n_views}."""
        vc = defaultdict(int)
        for v in self.views:
            vc[v.__class__.__name__] += 1
        return dict(vc)

    def list_views(self, cls):
        """Return the list of views from a given class."""
        return [view for view in self._views if view.__class__ == cls]

    def get_view(self, cls, index=0):
        """Return a view from a given class."""
        views = self.list_views(cls)
        if index <= len(views) - 1:
            return views[index]

    def _set_view_name(self, view):
        """Set a unique name for a view: view class name, followed by the view index."""
        assert view not in self._views
        # Get all views of the same class.
        cls = view.__class__
        basename = cls.__name__
        views = self.list_views(view.__class__)
        if not views:
            # If the view is the first of its class, just use the base name.
            name = basename
        else:
            # index is the next usable index for the view's class.
            index = self._view_class_indices.get(cls, 0)
            assert index >= 1
            name = '%s (%d)' % (basename, index)
        view.name = name
        return name

    def _create_and_add_view(self, view_name):
        fn = self.view_creator.get(view_name, None)
        if fn is None:
            return
        # Create the view with the view creation function.
        view = fn()
        if view is None:  # pragma: no cover
            logger.warning("Could not create view %s.", view_name)
            return
        # Attach the view to the GUI if it has an attach(gui) method,
        # otherwise add the view.
        if hasattr(view, 'attach'):
            view.attach(self)
        else:
            self.add_view(view)
        return view

    def create_views(self):
        """view_count is a dictionary {view_name: n_views}."""
        self.view_actions.separator()
        req_view_count = self._requested_view_count.items()
        for view_name, n_views in req_view_count:
            if n_views <= 0:
                continue
            assert n_views >= 1
            for i in range(n_views):
                self._create_and_add_view(view_name)

    def add_view(self, view, position=None, closable=True, floatable=True, floating=None):
        """Add a widget to the main window."""

        logger.debug("Add view %s to GUI.", view.__class__.__name__)

        name = self._set_view_name(view)
        self._views.append(view)
        self._view_class_indices[view.__class__] += 1

        # Get the Qt canvas for matplotlib/OpenGL views.
        widget = _try_get_matplotlib_canvas(view)
        widget = _try_get_opengl_canvas(widget)

        dock_widget = _create_dock_widget(widget, name, closable=closable, floatable=floatable)
        self.addDockWidget(_get_dock_position(position), dock_widget, Qt.Horizontal)
        if floating is not None:
            dock_widget.setFloating(floating)
        dock_widget.view = view
        view.dock_widget = dock_widget

        # Emit the close_view event when the dock widget is closed.
        @connect(sender=dock_widget)
        def on_close_dock_widget(sender):
            self._views.remove(view)
            emit('close_view', self, view)

        dock_widget.show()
        emit('add_view', self, view)
        logger.log(5, "Add %s to GUI.", name)
        return dock_widget

    # Menu bar
    # -------------------------------------------------------------------------

    def get_menu(self, name):
        """Return or create a menu."""
        if name not in self._menus:
            self._menus[name] = self.menuBar().addMenu(name)
        return self._menus[name]

    def get_submenu(self, menu, name):
        """Return or create a submenu."""
        if name not in self._menus:
            self._menus[name] = self.get_menu(menu).addMenu(name)
        return self._menus[name]

    def remove_menu(self, name):
        """Remove a menu."""
        if name in self._menus:
            menu = self._menus[name]
            menu.clear()
            menu.setVisible(False)
            self.menuBar().removeAction(menu.menuAction())

    def dialog(self, message):
        """Show a message in a dialog box."""
        box = QMessageBox(self)
        box.setText(message)
        return box

    # Status bar
    # -------------------------------------------------------------------------

    @property
    def status_message(self):
        """The message in the status bar."""
        return str(self._status_bar.currentMessage())

    @status_message.setter
    def status_message(self, value):
        if self._lock_status:
            return
        self._status_bar.showMessage(str(value))

    def lock_status(self):
        self._lock_status = True

    def unlock_status(self):
        self._lock_status = False

    # State
    # -------------------------------------------------------------------------

    def save_geometry_state(self):
        """Return picklable geometry and state of the window and docks.

        This function can be called in `on_close()`.

        """
        return {
            'geometry': self.saveGeometry(),
            'state': self.saveState(),
        }

    def restore_geometry_state(self, gs):
        """Restore the position of the main window and the docks.

        The gui widgets need to be recreated first.

        This function can be called in `on_show()`.

        """
        if not gs:
            return
        if gs.get('geometry', None):
            self.restoreGeometry((gs['geometry']))
        if gs.get('state', None):
            self.restoreState((gs['state']))
<commit_msg>Remove leftover print statement<commit_after># -*- coding: utf-8 -*-

"""Qt dock window."""

# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------

from collections import defaultdict
from functools import partial
import logging

from .qt import (
    QApplication, QWidget, QDockWidget, QStatusBar, QMainWindow, QMessageBox, Qt,
    QSize, QMetaObject, _wait, _prompt, _show_box)
from .state import GUIState, _gui_state_path, _get_default_state_path
from .actions import Actions, Snippets
from phylib.utils import emit, connect

logger = logging.getLogger(__name__)

# -----------------------------------------------------------------------------
# GUI main window
# -----------------------------------------------------------------------------

def _try_get_matplotlib_canvas(view):
    # Get the Qt widget from a matplotlib figure.
    try:
        from matplotlib.pyplot import Figure
        from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
        if isinstance(view, Figure):
            view = FigureCanvasQTAgg(view)
        # Case where the view has a .figure property which is a matplotlib figure.
        elif isinstance(getattr(view, 'figure', None), Figure):
            view = FigureCanvasQTAgg(view.figure)
    except ImportError as e:  # pragma: no cover
        logger.warning("Import error: %s", e)
    return view

def _try_get_opengl_canvas(view):
    """Convert from QOpenGLWindow to QOpenGLWidget."""
    from phy.plot.base import BaseCanvas
    if isinstance(view, BaseCanvas):
        return QWidget.createWindowContainer(view)
    elif isinstance(getattr(view, 'canvas', None), BaseCanvas):
        return QWidget.createWindowContainer(view.canvas)
    return view

class DockWidget(QDockWidget):
    def closeEvent(self, e):
        """Qt slot when the window is closed."""
        emit('close_dock_widget', self)
        super(DockWidget, self).closeEvent(e)

def _create_dock_widget(widget, name, closable=True, floatable=True):
    # Create the gui widget.
    dock_widget = DockWidget()
    dock_widget.setObjectName(name)
    dock_widget.setWindowTitle(name)
    dock_widget.setWidget(widget)

    # Set gui widget options.
    options = QDockWidget.DockWidgetMovable
    if closable:
        options = options | QDockWidget.DockWidgetClosable
    if floatable:
        options = options | QDockWidget.DockWidgetFloatable

    dock_widget.setFeatures(options)
    dock_widget.setAllowedAreas(Qt.LeftDockWidgetArea |
                                Qt.RightDockWidgetArea |
                                Qt.TopDockWidgetArea |
                                Qt.BottomDockWidgetArea
                                )

    return dock_widget

def _get_dock_position(position):
    return {'left': Qt.LeftDockWidgetArea,
            'right': Qt.RightDockWidgetArea,
            'top': Qt.TopDockWidgetArea,
            'bottom': Qt.BottomDockWidgetArea,
            }[position or 'right']

def _prompt_save():  # pragma: no cover
    """Show a prompt asking the user whether he wants to save or not.

    Output is 'save', 'cancel', or 'close'

    """
    b = _prompt(
        "Do you want to save your changes before quitting?",
        buttons=['save', 'cancel', 'close'], title='Save')
    return _show_box(b)

class GUI(QMainWindow):
    """A Qt main window holding docking Qt.

    `GUI` derives from `QMainWindow`.

    Events
    ------

    close
    show
    add_view
    close_view

    """
    def __init__(self,
                 position=None,
                 size=None,
                 name=None,
                 subtitle=None,
                 view_creator=None,
                 view_count=None,
                 default_views=None,
                 config_dir=None,
                 **kwargs
                 ):
        # HACK to ensure that closeEvent is called only twice (seems like a
        # Qt bug).
        self._closed = False
        if not QApplication.instance():  # pragma: no cover
            raise RuntimeError("A Qt application must be created.")
        super(GUI, self).__init__()
        QMetaObject.connectSlotsByName(self)
        self.setDockOptions(QMainWindow.AllowTabbedDocks |
                            QMainWindow.AllowNestedDocks
                            )
        self.setAnimated(False)

        logger.debug("Creating GUI.")

        self._set_name(name, str(subtitle))
        position = position or (200, 200)
        size = size or (800, 600)
        self._set_pos_size(position, size)

        # Registered functions.
        self._registered = {}

        # List of attached Actions instances.
        self.actions = []

        # Mapping {name: menuBar}.
        self._menus = {}
        self.file_actions = Actions(self, name='File', menu='&File')
        self.edit_actions = Actions(self, name='Edit', menu='&Edit')
        self.view_actions = Actions(self, name='View', menu='&View')
        self.help_actions = Actions(self, name='Help', menu='&Help')

        # Views,
        self._views = []
        self._view_class_indices = defaultdict(int)  # Dictionary {view_name: next_usable_index}

        # Create the GUI state.
        state_path = _gui_state_path(self.name, config_dir=config_dir)
        default_state_path = kwargs.pop('default_state_path', _get_default_state_path(self))
        self.state = GUIState(state_path, default_state_path=default_state_path, **kwargs)

        # View creator: dictionary {view_class: function_that_adds_view}
        self.view_creator = view_creator or {}
        # View count: take the requested one, or the GUI state one.
        self._requested_view_count = (
            view_count if view_count is not None else self.state.get('view_count', {}))
        # If there is still no view count, use a default one.
        self._requested_view_count = self._requested_view_count or {
            view_name: 1 for view_name in default_views or ()}

        # Status bar.
        self._lock_status = False
        self._status_bar = QStatusBar(self)
        self.setStatusBar(self._status_bar)

        # Create and attach snippets.
        self.snippets = Snippets(self)

        @connect(sender=self)
        def on_show(sender):
            logger.debug("Load the geometry state.")
            gs = self.state.get('geometry_state', None)
            self.restore_geometry_state(gs)

    def _set_name(self, name, subtitle):
        if name is None:
            name = self.__class__.__name__
        title = name if not subtitle else name + ' - ' + subtitle
        self.setWindowTitle(title)
        self.setObjectName(name)
        # Set the name in the GUI.
        self.name = name

    def _set_pos_size(self, position, size):
        if position is not None:
            self.move(position[0], position[1])
        if size is not None:
            self.resize(QSize(size[0], size[1]))

    def set_default_actions(self):
        # File menu.
        @self.file_actions.add(shortcut='ctrl+s')
        def save():
            emit('request_save', self)

        @self.file_actions.add(shortcut='ctrl+q')
        def exit():
            """Close the GUI."""
            self.close()

        # Add "Add view" action.
        for view_name in sorted(self.view_creator.keys()):
            self.view_actions.add(
                partial(self._create_and_add_view, view_name),
                submenu='&New view',
                name='Add %s' % view_name,
                show_shortcut=False)
        self.view_actions.separator()

        # Help menu.
        @self.help_actions.add(shortcut=('HelpContents', 'h'))
        def show_all_shortcuts():
            """Show the shortcuts of all actions."""
            for actions in self.actions:
                actions.show_shortcuts()

        @self.help_actions.add(shortcut='?')
        def about():  # pragma: no cover
            """Display an about dialog."""
            from phy import __version_git__
            msg = "phy {} v{}".format(self.name, __version_git__)
            try:
                from phylib import __version__
                msg += "\nphylib v{}".format(__version__)
            except ImportError:
                pass
            QMessageBox.about(self, "About", msg)

    # Events
    # -------------------------------------------------------------------------

    def closeEvent(self, e):
        """Qt slot when the window is closed."""
        if self._closed:
            return
        _wait(250)
        res = emit('close', self)
        # Discard the close event if False is returned by one of the callback
        # functions.
        if False in res:  # pragma: no cover
            e.ignore()
            return
        super(GUI, self).closeEvent(e)
        self._closed = True

        # Save the state to disk when closing the GUI.
        logger.debug("Save the geometry state.")
        gs = self.save_geometry_state()
        self.state['geometry_state'] = gs
        self.state['view_count'] = self.view_count
        self.state.save()

    def show(self):
        """Show the window."""
        emit('show', self)
        super(GUI, self).show()

    # Views
    # -------------------------------------------------------------------------

    @property
    def views(self):
        return self._views

    @property
    def view_count(self):
        """Dictionary {view_class: n_views}."""
        vc = defaultdict(int)
        for v in self.views:
            vc[v.__class__.__name__] += 1
        return dict(vc)

    def list_views(self, cls):
        """Return the list of views from a given class."""
        return [view for view in self._views if view.__class__ == cls]

    def get_view(self, cls, index=0):
        """Return a view from a given class."""
        views = self.list_views(cls)
        if index <= len(views) - 1:
            return views[index]

    def _set_view_name(self, view):
        """Set a unique name for a view: view class name, followed by the view index."""
        assert view not in self._views
        # Get all views of the same class.
        cls = view.__class__
        basename = cls.__name__
        views = self.list_views(view.__class__)
        if not views:
            # If the view is the first of its class, just use the base name.
            name = basename
        else:
            # index is the next usable index for the view's class.
            index = self._view_class_indices.get(cls, 0)
            assert index >= 1
            name = '%s (%d)' % (basename, index)
        view.name = name
        return name

    def _create_and_add_view(self, view_name):
        fn = self.view_creator.get(view_name, None)
        if fn is None:
            return
        # Create the view with the view creation function.
        view = fn()
        if view is None:  # pragma: no cover
            logger.warning("Could not create view %s.", view_name)
            return
        # Attach the view to the GUI if it has an attach(gui) method,
        # otherwise add the view.
        if hasattr(view, 'attach'):
            view.attach(self)
        else:
            self.add_view(view)
        return view

    def create_views(self):
        """view_count is a dictionary {view_name: n_views}."""
        self.view_actions.separator()
        req_view_count = self._requested_view_count.items()
        for view_name, n_views in req_view_count:
            if n_views <= 0:
                continue
            assert n_views >= 1
            for i in range(n_views):
                self._create_and_add_view(view_name)

    def add_view(self, view, position=None, closable=True, floatable=True, floating=None):
        """Add a widget to the main window."""

        logger.debug("Add view %s to GUI.", view.__class__.__name__)

        name = self._set_view_name(view)
        self._views.append(view)
        self._view_class_indices[view.__class__] += 1

        # Get the Qt canvas for matplotlib/OpenGL views.
        widget = _try_get_matplotlib_canvas(view)
        widget = _try_get_opengl_canvas(widget)

        dock_widget = _create_dock_widget(widget, name, closable=closable, floatable=floatable)
        self.addDockWidget(_get_dock_position(position), dock_widget, Qt.Horizontal)
        if floating is not None:
            dock_widget.setFloating(floating)
        dock_widget.view = view
        view.dock_widget = dock_widget

        # Emit the close_view event when the dock widget is closed.
        @connect(sender=dock_widget)
        def on_close_dock_widget(sender):
            self._views.remove(view)
            emit('close_view', self, view)

        dock_widget.show()
        emit('add_view', self, view)
        logger.log(5, "Add %s to GUI.", name)
        return dock_widget

    # Menu bar
    # -------------------------------------------------------------------------

    def get_menu(self, name):
        """Return or create a menu."""
        if name not in self._menus:
            self._menus[name] = self.menuBar().addMenu(name)
        return self._menus[name]

    def get_submenu(self, menu, name):
        """Return or create a submenu."""
        if name not in self._menus:
            self._menus[name] = self.get_menu(menu).addMenu(name)
        return self._menus[name]

    def remove_menu(self, name):
        """Remove a menu."""
        if name in self._menus:
            menu = self._menus[name]
            menu.clear()
            menu.setVisible(False)
            self.menuBar().removeAction(menu.menuAction())

    def dialog(self, message):
        """Show a message in a dialog box."""
        box = QMessageBox(self)
        box.setText(message)
        return box

    # Status bar
    # -------------------------------------------------------------------------

    @property
    def status_message(self):
        """The message in the status bar."""
        return str(self._status_bar.currentMessage())

    @status_message.setter
    def status_message(self, value):
        if self._lock_status:
            return
        self._status_bar.showMessage(str(value))

    def lock_status(self):
        self._lock_status = True

    def unlock_status(self):
        self._lock_status = False

    # State
    # -------------------------------------------------------------------------

    def save_geometry_state(self):
        """Return picklable geometry and state of the window and docks.

        This function can be called in `on_close()`.

        """
        return {
            'geometry': self.saveGeometry(),
            'state': self.saveState(),
        }

    def restore_geometry_state(self, gs):
        """Restore the position of the main window and the docks.

        The gui widgets need to be recreated first.

        This function can be called in `on_show()`.

        """
        if not gs:
            return
        if gs.get('geometry', None):
            self.restoreGeometry((gs['geometry']))
        if gs.get('state', None):
            self.restoreState((gs['state']))
<|endoftext|>


<commit_before>

import random
import sys
import math

class Player:
    VERSION = "Fuck pogacsa 1.4"

    def chen_calculator(self,game_state):
        current_val = 0
        team =  game_state['players'][game_state['in_action']]
        suite_value = { 'A' : 10, 'K' : 8 , 'Q' : 7 , 'J' : 6 , '10': 5 , '9' : 4.5 , '8' : 4, '7' : 3.5, '6': 3 , '5' : 2.5 , '4' :2 , '3' :1.5 , '2' : 1 }
        suite_order = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
        hole_cards_rank_0 = team['hole_cards'][0]["rank"]
        hole_cards_rank_1 = team['hole_cards'][1]["rank"]
        card_0_value = suite_value[hole_cards_rank_0]
        #print(card_0_value)
        card_1_value = suite_value[hole_cards_rank_1]
        #print(card_1_value)
        if card_0_value > card_1_value:
            #print('first is bigger')
            current_val += card_0_value
        elif card_0_value < card_1_value:
            #print('second is bigger')
            current_val += card_1_value
        else:
            current_val += card_0_value * 2
            if current_val < 5:
                current_val += 5
        #print("chen value is now" + str(current_val))
        hole_cards_suit_0 = team['hole_cards'][0]["suit"]
        hole_cards_suit_1 = team['hole_cards'][1]["suit"]
        if hole_cards_suit_0 == hole_cards_suit_1:
            current_val += 2

        card_gap = abs(suite_order.index(hole_cards_rank_0) -  suite_order.index(hole_cards_rank_1))-1
        #print(suite_order.index(hole_cards_rank_0))
        #print(card_gap)
        cards_lower_than_Q = False
        if suite_order.index(hole_cards_rank_0) < 10 and suite_order.index(hole_cards_rank_1) < 10:
            cards_lower_than_Q = True
        if card_gap  < 1:
            current_val += 0
            if cards_lower_than_Q == True:
                current_val += 1
        elif card_gap < 2 :
            current_val += -1
            if cards_lower_than_Q == True:
                current_val += 1
        elif card_gap < 3:
            current_val += -2
        elif card_gap < 4:
            current_val += -3
        elif card_gap > 4:
            current_val += -4
        print(card_gap)
        print("chen value is now" + str(current_val))
        current_val = math.ceil(current_val)
        return current_val

    def chen_evaluator(self,game_state):
        chen_val = self.chen_calculator(game_state)
        team =  game_state['players'][game_state['in_action']]

        to_call = game_state['current_buy_in'] - team['bet']
        to_raise = to_call + game_state['minimum_raise'] + 100

        if chen_val > 8:
            return to_raise
        if chen_val >= 10:
            return to_raise + 50
        else:
            return 0

    def get_cards_back(self,game_state):
        # if random.randint(0,10) > 2:
        #     return 150

        useful_ranks = ['8','9','10','J','Q','K','A']
        team =  game_state['players'][game_state['in_action']]
        hole_cards_rank_0 = team['hole_cards'][0]["rank"]
        hole_cards_rank_1 = team['hole_cards'][1]["rank"]

        hole_cards_suit_0 = team['hole_cards'][0]["suit"]
        hole_cards_suit_1 = team['hole_cards'][1]["suit"]

        to_call = game_state['current_buy_in'] - team['bet']
        if hole_cards_rank_0 == hole_cards_rank_1 and hole_cards_rank_0 in useful_ranks:
            current_bet = 10000
        elif hole_cards_rank_0 in ['J','Q','K','A'] and hole_cards_rank_1 in ['J','Q','K','A'] and hole_cards_suit_0 == hole_cards_suit_1:
            current_bet = to_call
        elif team['bet'] > 0 and team['bet'] > to_call:
            current_bet = to_call
        else:
            current_bet = 0
        return  current_bet

    def get_number_of_active_players(self, game_state):
        active_players = 0
        for player in game_state['players']:
            if player['active'] != 'out':
                active_players += 1

        return active_players

    def betRequest(self, game_state):

            current_bet_in_betReq = 1
            comm_cards = game_state['community_cards']
            if not comm_cards:
                current_bet_in_betReq =  self.chen_evaluator(game_state)
            else:
                current_bet_in_betReq = self.get_cards_back(game_state)
                current_bet_in_betReq = int(current_bet_in_betReq)

            if current_bet_in_betReq < 0:
                current_bet_in_betReq = 2

            return current_bet_in_betReq

            current_bet_in_betReq = 3
            return current_bet_in_betReq

    def showdown(self, game_state):
        pass

<commit_msg>even more intolerance<commit_after>

import random
import sys
import math

class Player:
    VERSION = "Fuck pogacsa 1.4"

    def chen_calculator(self,game_state):
        current_val = 0
        team =  game_state['players'][game_state['in_action']]
        suite_value = { 'A' : 10, 'K' : 8 , 'Q' : 7 , 'J' : 6 , '10': 5 , '9' : 4.5 , '8' : 4, '7' : 3.5, '6': 3 , '5' : 2.5 , '4' :2 , '3' :1.5 , '2' : 1 }
        suite_order = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
        hole_cards_rank_0 = team['hole_cards'][0]["rank"]
        hole_cards_rank_1 = team['hole_cards'][1]["rank"]
        card_0_value = suite_value[hole_cards_rank_0]
        #print(card_0_value)
        card_1_value = suite_value[hole_cards_rank_1]
        #print(card_1_value)
        if card_0_value > card_1_value:
            #print('first is bigger')
            current_val += card_0_value
        elif card_0_value < card_1_value:
            #print('second is bigger')
            current_val += card_1_value
        else:
            current_val += card_0_value * 2
            if current_val < 5:
                current_val += 5
        #print("chen value is now" + str(current_val))
        hole_cards_suit_0 = team['hole_cards'][0]["suit"]
        hole_cards_suit_1 = team['hole_cards'][1]["suit"]
        if hole_cards_suit_0 == hole_cards_suit_1:
            current_val += 2

        card_gap = abs(suite_order.index(hole_cards_rank_0) -  suite_order.index(hole_cards_rank_1))-1
        #print(suite_order.index(hole_cards_rank_0))
        #print(card_gap)
        cards_lower_than_Q = False
        if suite_order.index(hole_cards_rank_0) < 10 and suite_order.index(hole_cards_rank_1) < 10:
            cards_lower_than_Q = True
        if card_gap  < 1:
            current_val += 0
            if cards_lower_than_Q == True:
                current_val += 1
        elif card_gap < 2 :
            current_val += -1
            if cards_lower_than_Q == True:
                current_val += 1
        elif card_gap < 3:
            current_val += -2
        elif card_gap < 4:
            current_val += -3
        elif card_gap > 4:
            current_val += -4
        print(card_gap)
        print("chen value is now" + str(current_val))
        current_val = math.ceil(current_val)
        return current_val

    def chen_evaluator(self,game_state):
        chen_val = self.chen_calculator(game_state)
        team =  game_state['players'][game_state['in_action']]

        to_call = game_state['current_buy_in'] - team['bet']
        to_raise = to_call + game_state['minimum_raise'] + 100

        if chen_val > 10:
            return to_raise
        if chen_val > 15:
            return to_raise + 50
        else:
            return 0

    def get_cards_back(self,game_state):
        # if random.randint(0,10) > 2:
        #     return 150

        useful_ranks = ['8','9','10','J','Q','K','A']
        team =  game_state['players'][game_state['in_action']]
        hole_cards_rank_0 = team['hole_cards'][0]["rank"]
        hole_cards_rank_1 = team['hole_cards'][1]["rank"]

        hole_cards_suit_0 = team['hole_cards'][0]["suit"]
        hole_cards_suit_1 = team['hole_cards'][1]["suit"]

        to_call = game_state['current_buy_in'] - team['bet']
        if hole_cards_rank_0 == hole_cards_rank_1 and hole_cards_rank_0 in useful_ranks:
            current_bet = 10000
        elif hole_cards_rank_0 in ['J','Q','K','A'] and hole_cards_rank_1 in ['J','Q','K','A'] and hole_cards_suit_0 == hole_cards_suit_1:
            current_bet = to_call
        elif team['bet'] > 0 and team['bet'] > to_call:
            current_bet = to_call
        else:
            current_bet = 0
        return  current_bet

    def get_number_of_active_players(self, game_state):
        active_players = 0
        for player in game_state['players']:
            if player['active'] != 'out':
                active_players += 1

        return active_players

    def betRequest(self, game_state):

            current_bet_in_betReq = 1
            comm_cards = game_state['community_cards']
            if not comm_cards:
                current_bet_in_betReq =  self.chen_evaluator(game_state)
            else:
                current_bet_in_betReq = self.get_cards_back(game_state)
                current_bet_in_betReq = int(current_bet_in_betReq)

            if current_bet_in_betReq < 0:
                current_bet_in_betReq = 2

            return current_bet_in_betReq

            current_bet_in_betReq = 3
            return current_bet_in_betReq

    def showdown(self, game_state):
        pass

<|endoftext|>


<commit_before>"""
byceps.services.news.service
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2018 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from typing import Dict, Optional

from flask_sqlalchemy import Pagination

from ...database import db
from ...typing import BrandID, UserID

from ..brand.models.brand import Brand

from .models.item import CurrentVersionAssociation, Item, ItemVersion
from .transfer.models import ItemID, ItemVersionID

def create_item(brand_id: BrandID, slug: str, creator_id: UserID, title: str,
                body: str, *, image_url_path: Optional[str]=None) -> Item:
    """Create a news item, a version, and set the version as the item's
    current one.
    """
    item = Item(brand_id, slug)
    db.session.add(item)

    version = _create_version(item, creator_id, title, body,
                              image_url_path=image_url_path)
    db.session.add(version)

    current_version_association = CurrentVersionAssociation(item, version)
    db.session.add(current_version_association)

    db.session.commit()

    return item

def update_item(item: Item, creator_id: UserID, title: str, body: str, *,
                image_url_path: Optional[str]=None) -> None:
    """Update a news item by creating a new version of it and setting
    the new version as the current one.
    """
    version = _create_version(item, creator_id, title, body,
                              image_url_path=image_url_path)
    db.session.add(version)

    item.current_version = version

    db.session.commit()

def _create_version(item: Item, creator_id: UserID, title: str, body: str, *,
                    image_url_path: Optional[str]=None) -> ItemVersion:
    version = ItemVersion(item, creator_id, title, body)

    if image_url_path:
        version.image_url_path = image_url_path

    return version

def find_item(item_id: ItemID) -> Optional[Item]:
    """Return the item with that id, or `None` if not found."""
    return Item.query.get(item_id)

def find_item_by_slug(brand_id: BrandID, slug: str) -> Optional[Item]:
    """Return the news item identified by that slug, or `None` if not found."""
    return Item.query \
        .for_brand(brand_id) \
        .with_current_version() \
        .filter_by(slug=slug) \
        .first()

def get_items_paginated(brand_id: BrandID, page: int, items_per_page: int,
                        published_only: bool=False
                       ) -> Pagination:
    """Return the news items to show on the specified page."""
    query = Item.query \
        .for_brand(brand_id) \
        .with_current_version()

    if published_only:
        query = query.published()

    return query \
        .order_by(Item.published_at.desc()) \
        .paginate(page, items_per_page)

def find_item_version(version_id: ItemVersionID) -> ItemVersion:
    """Return the item version with that ID, or `None` if not found."""
    return ItemVersion.query.get(version_id)

def count_items_for_brand(brand_id: BrandID) -> int:
    """Return the number of news items for that brand."""
    return Item.query \
        .for_brand(brand_id) \
        .count()

def get_item_count_by_brand_id() -> Dict[BrandID, int]:
    """Return news item count (including 0) per brand, indexed by brand ID."""
    brand_ids_and_item_counts = db.session \
        .query(
            Brand.id,
            db.func.count(Item.brand_id)
        ) \
        .outerjoin(Item) \
        .group_by(Brand.id) \
        .all()

    return dict(brand_ids_and_item_counts)
<commit_msg>Prefix imported database models in news service<commit_after>"""
byceps.services.news.service
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2018 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from typing import Dict, Optional

from flask_sqlalchemy import Pagination

from ...database import db
from ...typing import BrandID, UserID

from ..brand.models.brand import Brand as DbBrand

from .models.item import \
    CurrentVersionAssociation as DbCurrentVersionAssociation, \
    Item as DbItem, ItemVersion as DbItemVersion
from .transfer.models import ItemID, ItemVersionID

def create_item(brand_id: BrandID, slug: str, creator_id: UserID, title: str,
                body: str, *, image_url_path: Optional[str]=None) -> DbItem:
    """Create a news item, a version, and set the version as the item's
    current one.
    """
    item = DbItem(brand_id, slug)
    db.session.add(item)

    version = _create_version(item, creator_id, title, body,
                              image_url_path=image_url_path)
    db.session.add(version)

    current_version_association = DbCurrentVersionAssociation(item, version)
    db.session.add(current_version_association)

    db.session.commit()

    return item

def update_item(item: DbItem, creator_id: UserID, title: str, body: str, *,
                image_url_path: Optional[str]=None) -> None:
    """Update a news item by creating a new version of it and setting
    the new version as the current one.
    """
    version = _create_version(item, creator_id, title, body,
                              image_url_path=image_url_path)
    db.session.add(version)

    item.current_version = version

    db.session.commit()

def _create_version(item: DbItem, creator_id: UserID, title: str, body: str, *,
                    image_url_path: Optional[str]=None) -> DbItemVersion:
    version = DbItemVersion(item, creator_id, title, body)

    if image_url_path:
        version.image_url_path = image_url_path

    return version

def find_item(item_id: ItemID) -> Optional[DbItem]:
    """Return the item with that id, or `None` if not found."""
    return DbItem.query.get(item_id)

def find_item_by_slug(brand_id: BrandID, slug: str) -> Optional[DbItem]:
    """Return the news item identified by that slug, or `None` if not found."""
    return DbItem.query \
        .for_brand(brand_id) \
        .with_current_version() \
        .filter_by(slug=slug) \
        .first()

def get_items_paginated(brand_id: BrandID, page: int, items_per_page: int,
                        published_only: bool=False
                       ) -> Pagination:
    """Return the news items to show on the specified page."""
    query = DbItem.query \
        .for_brand(brand_id) \
        .with_current_version()

    if published_only:
        query = query.published()

    return query \
        .order_by(DbItem.published_at.desc()) \
        .paginate(page, items_per_page)

def find_item_version(version_id: ItemVersionID) -> DbItemVersion:
    """Return the item version with that ID, or `None` if not found."""
    return DbItemVersion.query.get(version_id)

def count_items_for_brand(brand_id: BrandID) -> int:
    """Return the number of news items for that brand."""
    return DbItem.query \
        .for_brand(brand_id) \
        .count()

def get_item_count_by_brand_id() -> Dict[BrandID, int]:
    """Return news item count (including 0) per brand, indexed by brand ID."""
    brand_ids_and_item_counts = db.session \
        .query(
            DbBrand.id,
            db.func.count(DbItem.brand_id)
        ) \
        .outerjoin(DbItem) \
        .group_by(DbBrand.id) \
        .all()

    return dict(brand_ids_and_item_counts)
<|endoftext|>


<commit_before>"""
This interfaces with MasterOverwatch to download stats.
"""
from kyokai.context import HTTPRequestContext
import aiohttp

# Constants.
from owapi import util

BASE_URL = "https://masteroverwatch.com/"
PROFILE_URL = BASE_URL + "profile/pc/"

# This will break if Master Overwatch changes layout
# Make sure to change it if it does
heroes_xpath = "/html/body[@class='player']/main[@class='player-data']/div[@class='container']" \
               "/div[@class='row']/div[@class='col-md-4']/div[@class='data-heroes']/div[@class='heroes-list']"
stats_xpath = "/html/body[@class='player']/main[@class='player-data']/div[@class='container']/div[@class='row']" \
              "/div[@class='col-md-8']/div[@class='data-stats']/div[@class='stats-list']/div"

session = aiohttp.ClientSession(headers={"User-Agent": "OWAPI Scraper/1.0.0"})

async def get_page_body(ctx: HTTPRequestContext, url: str) -> str:
    """
    Downloads page body from MasterOverwatch and caches it.
    """
    async def _real_get_body(url: str):
        # Real function.
        async with session.get(url) as req:
            assert isinstance(req, aiohttp.ClientResponse)
            return await req.read()

    return await util.with_cache(ctx, _real_get_body, url)

<commit_msg>Add _parse_page and get_user_page helper methods.<commit_after>"""
This interfaces with MasterOverwatch to download stats.
"""
import functools

import asyncio
from lxml import etree

from kyokai.context import HTTPRequestContext
import aiohttp

# Constants.
from owapi import util

BASE_URL = "https://masteroverwatch.com/"
PROFILE_URL = BASE_URL + "profile/pc/"
PAGE_URL = PROFILE_URL + "{region}/{btag}"

# This will break if Master Overwatch changes layout
# Make sure to change it if it does
heroes_xpath = "/html/body[@class='player']/main[@class='player-data']/div[@class='container']" \
               "/div[@class='row']/div[@class='col-md-4']/div[@class='data-heroes']/div[@class='heroes-list']"
stats_xpath = "/html/body[@class='player']/main[@class='player-data']/div[@class='container']/div[@class='row']" \
              "/div[@class='col-md-8']/div[@class='data-stats']/div[@class='stats-list']/div"

session = aiohttp.ClientSession(headers={"User-Agent": "OWAPI Scraper/1.0.0"})

async def get_page_body(ctx: HTTPRequestContext, url: str) -> str:
    """
    Downloads page body from MasterOverwatch and caches it.
    """

    async def _real_get_body(url: str):
        # Real function.
        async with session.get(url) as req:
            assert isinstance(req, aiohttp.ClientResponse)
            return await req.read()

    return await util.with_cache(ctx, _real_get_body, url)

def _parse_page(content: str) -> etree._Element:
    """
    Internal function to parse a page and return the data.
    """
    data = etree.HTML(content)
    return data

async def get_user_page(ctx: HTTPRequestContext, battletag: str, region: str="eu") -> etree._Element:
    """
    Downloads the MO page for a user, and parses it.
    """
    built_url = PAGE_URL.format(region, battletag.replace("#", "-"))
    page_body = await get_page_body(ctx, built_url)

    # parse the page
    parse_partial = functools.partial(_parse_page, page_body)
    loop = asyncio.get_event_loop()
    parsed = await loop.run_in_executor(None, parse_partial)

    return parsed

<|endoftext|>


<commit_before>import logging

RPL_WELCOME = 1
RPL_WHOISUSER = 311
RPL_ENDOFWHO = 315
RPL_LISTSTART = 321
RPL_LIST = 322
RPL_LISTEND = 323
RPL_TOPIC = 332
RPL_WHOREPLY = 352
RPL_NAMREPLY = 353
RPL_ENDOFNAMES = 366
RPL_MOTD = 372
RPL_MOTDSTART = 375
RPL_ENDOFMOTD = 376

logger = logging.getLogger(__name__)

class Client(object):

    def __init__(self, reader, writer):
        self.reader = reader
        self.writer = writer

        self.nickname = None
        self.sent_messages = []

    def readline(self):
        return self.reader.readline()

    def write(self, sender, command, *args):
        """Sends a message to the client on behalf of another client."""
        if not isinstance(command, str):
            command = '{:03}'.format(command)
        params = ' '.join('{}'.format(arg) for arg in args)
        line = ':{} {} {}\r\n'.format(sender, command, params)
        logger.info('Sent: %r', line)
        self.writer.write(line.encode('utf-8'))

    def swrite(self, command, *args):
        """Sends a message from the server to the client."""
        self.write('pickups', command, self.nickname, *args)

    def uwrite(self, command, *args):
        """Sends a message on behalf of the client."""
        self.write(self.nickname, command, *args)

    # IRC Stuff

    def welcome(self):
        """Tells the client a welcome message."""
        self.swrite(RPL_WELCOME, self.nickname, ':Welcome to pickups!')

    def list_channels(self, info):
        """Tells the client what channels are available."""
        self.swrite(RPL_LISTSTART)
        for channel, num_users, topic in info:
            self.swrite(RPL_LIST, channel, num_users, ':{}'.format(topic))
        self.swrite(RPL_LISTEND, ':End of /LIST')

    def join(self, channel):
        """Tells the client to join a channel."""
        self.write(self.nickname, 'JOIN', ':{}'.format(channel))

    def list_nicks(self, channel, nicks):
        """Tells the client what nicks are in channel."""
        self.swrite(RPL_NAMREPLY, '=', channel, ':{}'.format(' '.join(nicks)))
        self.swrite(RPL_ENDOFNAMES, channel, ':End of NAMES list')

    def who(self, query, responses):
        """Tells the client a list of information matching a query."""
        for response in responses:
            self.swrite(
                RPL_WHOREPLY, response['channel'],
                '~{}'.format(response['user']), 'localhost', 'pickups',
                response['nick'], 'H', ':0', response['real_name']
            )
        self.swrite(RPL_ENDOFWHO, query, ':End of WHO list')

    def topic(self, channel, topic):
        """Tells the client the topic of the channel."""
        self.swrite(RPL_TOPIC, channel, ':{}'.format(topic))

    def privmsg(self, sender, target, message):
        """Sends the client a message from someone."""
        self.write(sender, 'PRIVMSG', target, ':{}'.format(message))

    def tell_nick(self, nickname):
        """Tells the client its actual nick."""
        self.uwrite('NICK', nickname)
        self.nickname = nickname
<commit_msg>Send new lines as new messages<commit_after>import logging

RPL_WELCOME = 1
RPL_WHOISUSER = 311
RPL_ENDOFWHO = 315
RPL_LISTSTART = 321
RPL_LIST = 322
RPL_LISTEND = 323
RPL_TOPIC = 332
RPL_WHOREPLY = 352
RPL_NAMREPLY = 353
RPL_ENDOFNAMES = 366
RPL_MOTD = 372
RPL_MOTDSTART = 375
RPL_ENDOFMOTD = 376

logger = logging.getLogger(__name__)

class Client(object):

    def __init__(self, reader, writer):
        self.reader = reader
        self.writer = writer

        self.nickname = None
        self.sent_messages = []

    def readline(self):
        return self.reader.readline()

    def write(self, sender, command, *args):
        """Sends a message to the client on behalf of another client."""
        if not isinstance(command, str):
            command = '{:03}'.format(command)
        params = ' '.join('{}'.format(arg) for arg in args)
        line = ':{} {} {}\r\n'.format(sender, command, params)
        logger.info('Sent: %r', line)
        self.writer.write(line.encode('utf-8'))

    def swrite(self, command, *args):
        """Sends a message from the server to the client."""
        self.write('pickups', command, self.nickname, *args)

    def uwrite(self, command, *args):
        """Sends a message on behalf of the client."""
        self.write(self.nickname, command, *args)

    # IRC Stuff

    def welcome(self):
        """Tells the client a welcome message."""
        self.swrite(RPL_WELCOME, self.nickname, ':Welcome to pickups!')

    def list_channels(self, info):
        """Tells the client what channels are available."""
        self.swrite(RPL_LISTSTART)
        for channel, num_users, topic in info:
            self.swrite(RPL_LIST, channel, num_users, ':{}'.format(topic))
        self.swrite(RPL_LISTEND, ':End of /LIST')

    def join(self, channel):
        """Tells the client to join a channel."""
        self.write(self.nickname, 'JOIN', ':{}'.format(channel))

    def list_nicks(self, channel, nicks):
        """Tells the client what nicks are in channel."""
        self.swrite(RPL_NAMREPLY, '=', channel, ':{}'.format(' '.join(nicks)))
        self.swrite(RPL_ENDOFNAMES, channel, ':End of NAMES list')

    def who(self, query, responses):
        """Tells the client a list of information matching a query."""
        for response in responses:
            self.swrite(
                RPL_WHOREPLY, response['channel'],
                '~{}'.format(response['user']), 'localhost', 'pickups',
                response['nick'], 'H', ':0', response['real_name']
            )
        self.swrite(RPL_ENDOFWHO, query, ':End of WHO list')

    def topic(self, channel, topic):
        """Tells the client the topic of the channel."""
        self.swrite(RPL_TOPIC, channel, ':{}'.format(topic))

    def privmsg(self, hostmask, target, message):
        """Sends the client a message from someone."""
        for line in message.splitlines():
            if line:
                self.write(hostmask, 'PRIVMSG', target, ':{}'.format(line))

    def tell_nick(self, nickname):
        """Tells the client its actual nick."""
        self.uwrite('NICK', nickname)
        self.nickname = nickname
<|endoftext|>


<commit_before>import pprint
from utils import getHandPower
import requests

ALL_IN = 99999
MAX_SACRIFICE_RATE = 0.7

class Player:
    VERSION = "Default Python folding player"

    def get_hand(self, game_state):
        player = [elem['hole_cards'] for elem in game_state['players'] if elem['version'] == self.VERSION]
        return player

    def get_own_stack(self, game_state):
        stack = [elem['stack'] for elem in game_state['players'] if elem['version'] == self.VERSION]
        return stack

    def bets_per_round(self, game_state):
        bets = [(elem['name'], elem['bet']) for elem in game_state['players']]
        return bets

    def get_community_card(self, game_state):
        return game_state["community_cards"]

    def hold(self, game_state, intended_bet, ownStack):
        bets = self.bets_per_round(game_state)
        maxbet = intended_bet

        if (intended_bet == ALL_IN):
            for bet in bets:
                if bet[1] > maxbet:
                    maxbet = bet[1]
        else:
            for bet in bets:
                if bet[1] > maxbet and bet[1] < int(ownStack * MAX_SACRIFICE_RATE):
                    maxbet = bet[1]

        return maxbet

    def get_active_players(self, game_state):
        active_players = [1 for elem in game_state['players'] if elem['status'] == 'active']
        return sum(active_players)

    def only_high_cards(self, game_state):
        try:
            isOnlyHigh = False;
            hand = self.get_hand(game_state)
            card_1 = hand[0][0]
            card_2 = hand[0][1]
            if (card_1['rank'] in 'JQKA' and card_2['rank'] in 'JQKA'):
                isOnlyHigh = True
            return isOnlyHigh
        except:
            return False

    def betRequest(self, game_state):
        try:
            print("#######################################")
            print("#######################################")
            print("                 GAME STATE                       ")
            pprint.pprint(game_state, width=1)
            print("#######################################")
            print("#######################################")
            print("                 PLAYER BETS                       ")
            bets = self.bets_per_round(game_state)
            pprint.pprint(bets, width=1)
            print("#######################################")
            print("#######################################")
            hand = self.get_hand(game_state)
            community_cards = self.get_community_card(game_state)
            hand_power = getHandPower(hand)

            ownStack = self.get_own_stack(game_state)

            if hand_power >= 35:
                bet = self.hold(game_state, ALL_IN, ownStack)
            elif hand_power >= 21:
                if (self.only_high_cards(game_state)):
                    bet = self.hold(game_state, int(ownStack/3), ownStack)
                else:
                    bet = 300
            elif hand_power >= 19:
                bet = 200
            elif hand_power > 10:
                bet = 0
            else:
                bet = 0

            print("#######################################")
            print("                 OUR HAND                       ")
            print(hand)
            print("#######################################")
            print("#######################################")
            print("                 COMMUNITY CARDS                ")
            print(community_cards)
            print("#######################################")
            print("#######################################")
            print("                 HAND POWER                      ")
            print(hand_power)
            print("#######################################")
            print("#######################################")
            print("                 OUR BET               ")
            print(bet)
            return bet

        except:
            return 90000

    def get_winner_stats(self, game_state):
        winner = [{'winner': elem} for elem in game_state['players'] if elem['status'] == 'active']
        try:
            winner_hand = winner[0]['winner']['hole_cards']
            winner_hand_power = getHandPower([winner_hand])
        except:
            winner_hand = 'HAND NOT SHOWN'
            winner_hand_power = 'HAND NOT SHOWN'
        return {'winner': winner[0]['winner']['name'],
                'hand': winner_hand,
                'hand_power': winner_hand_power}

    def showdown(self, game_state):
        print("#######################################")
        print("#######################################")
        print("        SHOWDOWN GAME STATE             ")
        pprint.pprint(game_state, width=1)
        print("#######################################")
        print("#######################################")
        print(self.get_winner_stats(game_state))
        print("#######################################")
        print("#######################################")
        print("                 PLAYERS ON SHOWDOWN            ")
        pprint.pprint(game_state['players'])
        print("#######################################")
        print("#######################################")
        print("            COMMUNITY CARDS IN SHOWDOWN         ")
        print(self.get_community_card(game_state))
        print("#######################################")
        print("#######################################")
        print("                WINNER STATS                          ")
        print(self.get_winner_stats(game_state))
        print("#######################################")
        print("#######################################")
        requests.post("https://lean-poker-db.herokuapp.com/add", json=self.get_winner_stats(game_state))

<commit_msg>back revert<commit_after>import pprint
from utils import getHandPower
import requests

ALL_IN = 99999
MAX_SACRIFICE_RATE = 0.7

class Player:
    VERSION = "Default Python folding player"

    def get_hand(self, game_state):
        player = [elem['hole_cards'] for elem in game_state['players'] if elem['version'] == self.VERSION]
        return player

    def get_own_stack(self, game_state):
        stack = [elem['stack'] for elem in game_state['players'] if elem['version'] == self.VERSION]
        return stack

    def bets_per_round(self, game_state):
        bets = [(elem['name'], elem['bet']) for elem in game_state['players']]
        return bets

    def get_community_card(self, game_state):
        return game_state["community_cards"]

    def hold(self, game_state, intended_bet, ownStack):
        bets = self.bets_per_round(game_state)
        maxbet = intended_bet

        for bet in bets:
            if bet[1] > maxbet:
                maxbet = bet[1]

        return maxbet

    def get_active_players(self, game_state):
        active_players = [1 for elem in game_state['players'] if elem['status'] == 'active']
        return sum(active_players)

    def only_high_cards(self, game_state):
        try:
            isOnlyHigh = False;
            hand = self.get_hand(game_state)
            card_1 = hand[0][0]
            card_2 = hand[0][1]
            if (card_1['rank'] in 'JQKA' and card_2['rank'] in 'JQKA'):
                isOnlyHigh = True
            return isOnlyHigh
        except:
            return False

    def betRequest(self, game_state):
        try:
            print("#######################################")
            print("#######################################")
            print("                 GAME STATE                       ")
            pprint.pprint(game_state, width=1)
            print("#######################################")
            print("#######################################")
            print("                 PLAYER BETS                       ")
            bets = self.bets_per_round(game_state)
            pprint.pprint(bets, width=1)
            print("#######################################")
            print("#######################################")
            hand = self.get_hand(game_state)
            community_cards = self.get_community_card(game_state)
            hand_power = getHandPower(hand)

            ownStack = self.get_own_stack(game_state)

            if hand_power >= 35:
                bet = self.hold(game_state, ALL_IN, ownStack)
            elif hand_power >= 21:
                if (self.only_high_cards(game_state)):
                    bet = self.hold(game_state, int(ownStack/3), ownStack)
                else:
                    bet = 300
            elif hand_power >= 19:
                bet = 200
            elif hand_power > 10:
                bet = 0
            else:
                bet = 0

            print("#######################################")
            print("                 OUR HAND                       ")
            print(hand)
            print("#######################################")
            print("#######################################")
            print("                 COMMUNITY CARDS                ")
            print(community_cards)
            print("#######################################")
            print("#######################################")
            print("                 HAND POWER                      ")
            print(hand_power)
            print("#######################################")
            print("#######################################")
            print("                 OUR BET               ")
            print(bet)
            return bet

        except:
            return 90000

    def get_winner_stats(self, game_state):
        winner = [{'winner': elem} for elem in game_state['players'] if elem['status'] == 'active']
        try:
            winner_hand = winner[0]['winner']['hole_cards']
            winner_hand_power = getHandPower([winner_hand])
        except:
            winner_hand = 'HAND NOT SHOWN'
            winner_hand_power = 'HAND NOT SHOWN'
        return {'winner': winner[0]['winner']['name'],
                'hand': winner_hand,
                'hand_power': winner_hand_power}

    def showdown(self, game_state):
        print("#######################################")
        print("#######################################")
        print("        SHOWDOWN GAME STATE             ")
        pprint.pprint(game_state, width=1)
        print("#######################################")
        print("#######################################")
        print(self.get_winner_stats(game_state))
        print("#######################################")
        print("#######################################")
        print("                 PLAYERS ON SHOWDOWN            ")
        pprint.pprint(game_state['players'])
        print("#######################################")
        print("#######################################")
        print("            COMMUNITY CARDS IN SHOWDOWN         ")
        print(self.get_community_card(game_state))
        print("#######################################")
        print("#######################################")
        print("                WINNER STATS                          ")
        print(self.get_winner_stats(game_state))
        print("#######################################")
        print("#######################################")
        requests.post("https://lean-poker-db.herokuapp.com/add", json=self.get_winner_stats(game_state))

<|endoftext|>


<commit_before>import re
import sysErrorLog

def conv ( self ):

	if len(self.msg) == 5 and self.msg[4].strip() == "units":
		self.send_chan("I know: km, m, cm, mm, l, ml, yd, miles, floz, gal")
		return
	if len(self.msg) < 6:
		self.send_chan("Usage: !conv <amount> <from> <to> || !conv units")
		return
	if len(self.msg) == 6:
		try:
			amount = float(re.sub(",", ".", self.msg[4]))
		except ValueError:
			amount = 1.00
		frm = self.msg[5].strip()
		output = ""

		try:
			## Length conversions
			if frm == "mm":
				result = round(amount * 0.03937, 5)
				output = "{0} millimeters is {1} inches".format(amount, result)
			elif frm == "in":
				result = round(amount * 2.54, 2)
				if result < 100:
					output = output = "{0} inches is {1} centimeters".format(amount, result)
				else:
					result = result/100
					output = output = "{0} inches is {1} meters".format(amount, result)
			elif frm == "cm":
				result = round(amount * 0.3937, 2)
				output = "{0} centimeters is {1} inches".format(amount, result)
			elif frm == "m":
				result = round(amount * 1.0936, 2)
				output = "{0} meters is {1} yards".format(amount, result)
			elif frm == "yd":
				result = round(amount * 0.9144, 2)
				if result < 1000:
					output = "{0} yards is {1} meters".format(amount, result)
				else:
					result = result / 1000
					output = "{0} yards is {1} kilometers".format(amount, result)
			elif frm == "km":
				result = round(amount * 0.6214, 2)
				output = "{0} kilometers is {1} miles".format(amount, result)
			elif frm == "miles":
				result = round(amount * 1.6093, 2)
				if result < 1:
					result = result*1000
					output = "{0} miles is {1} meters".format(amount, result)
				else:
					output = "{0} miles is {1} kilometers".format(amount, result)
			## Volume conversions
			elif frm == "floz":
				result = round(amount * 29.574, 3)
				if result < 1000:
					output = "{0} fluid ounces is {1} milliliters".format(amount, result)
				else:
					result = round(result / 1000, 2)
					output = "{0} fluid ounces is {1} liters".format(amount, result)
			elif frm == "ml":
				result = round(amount / 29.574, 3)
				output = "{0} milliliters is {1} fluid ounces".format(amount, result)
			elif frm == "gal":
				result = round(amount * 3.7854, 4)
				output = "{0} gallons is {1} liters".format(amount, result)
			elif frm == "l":
				result = round(amount / 3.7854, 4)
				output = "{0} liters is {1} gallons".format(amount, result)
			else:
				output = "I don't know how to convert {0} {1}(s) :(".format(amount, frm)

			self.send_chan(output)

		except Exception as e:
			self.errormsg = "[ERROR]-[Conv] stating: {0}".format(e)
			sysErrorLog.log( self ) ## LOG the error
			if self.config["debug"] == "true":
				print("{0}{1}{2}".format(self.color("red"), self.errormsg, self.color("end")))
	else:
		self.send_chan("Usage: !conv <amount> <from> <to> || !conv units")
<commit_msg>fix help<commit_after>import re
import sysErrorLog

def conv ( self ):

	if len(self.msg) == 5 and self.msg[4].strip() == "units":
		self.send_chan("I know: km, m, cm, mm, l, ml, yd, miles, floz, gal")
		return
	if len(self.msg) < 6:
		self.send_chan("Usage: !conv <amount> <unit> || !conv units")
		return
	if len(self.msg) == 6:
		try:
			amount = float(re.sub(",", ".", self.msg[4]))
		except ValueError:
			amount = 1.00
		frm = self.msg[5].strip()
		output = ""

		try:
			## Length conversions
			if frm == "mm":
				result = round(amount * 0.03937, 5)
				output = "{0} millimeters is {1} inches".format(amount, result)
			elif frm == "in":
				result = round(amount * 2.54, 2)
				if result < 100:
					output = output = "{0} inches is {1} centimeters".format(amount, result)
				else:
					result = result/100
					output = output = "{0} inches is {1} meters".format(amount, result)
			elif frm == "cm":
				result = round(amount * 0.3937, 2)
				output = "{0} centimeters is {1} inches".format(amount, result)
			elif frm == "m":
				result = round(amount * 1.0936, 2)
				output = "{0} meters is {1} yards".format(amount, result)
			elif frm == "yd":
				result = round(amount * 0.9144, 2)
				if result < 1000:
					output = "{0} yards is {1} meters".format(amount, result)
				else:
					result = result / 1000
					output = "{0} yards is {1} kilometers".format(amount, result)
			elif frm == "km":
				result = round(amount * 0.6214, 2)
				output = "{0} kilometers is {1} miles".format(amount, result)
			elif frm == "miles":
				result = round(amount * 1.6093, 2)
				if result < 1:
					result = result*1000
					output = "{0} miles is {1} meters".format(amount, result)
				else:
					output = "{0} miles is {1} kilometers".format(amount, result)
			## Volume conversions
			elif frm == "floz":
				result = round(amount * 29.574, 3)
				if result < 1000:
					output = "{0} fluid ounces is {1} milliliters".format(amount, result)
				else:
					result = round(result / 1000, 2)
					output = "{0} fluid ounces is {1} liters".format(amount, result)
			elif frm == "ml":
				result = round(amount / 29.574, 3)
				output = "{0} milliliters is {1} fluid ounces".format(amount, result)
			elif frm == "gal":
				result = round(amount * 3.7854, 4)
				output = "{0} gallons is {1} liters".format(amount, result)
			elif frm == "l":
				result = round(amount / 3.7854, 4)
				output = "{0} liters is {1} gallons".format(amount, result)
			else:
				output = "I don't know how to convert {0} {1}(s) :(".format(amount, frm)

			self.send_chan(output)

		except Exception as e:
			self.errormsg = "[ERROR]-[Conv] stating: {0}".format(e)
			sysErrorLog.log( self ) ## LOG the error
			if self.config["debug"] == "true":
				print("{0}{1}{2}".format(self.color("red"), self.errormsg, self.color("end")))
	else:
		self.send_chan("Usage: !conv <amount> <unit> || !conv units")
<|endoftext|>


<commit_before>#The MIT License (MIT)
#
#Copyright (C) 2014 OpenBet Limited
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of
#this software and associated documentation files (the "Software"), to deal in
#the Software without restriction, including without limitation the rights to
#use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
#of the Software, and to permit persons to whom the Software is furnished to do
#so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all
#copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
#THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.

from shutit_module import ShutItModule
import util

class casperjs(ShutItModule):

	def is_installed(self,shutit):
		config_dict = shutit.cfg
		container_child = util.get_pexpect_child('container_child')
		res = util.file_exists(container_child,'/opt/casperjs',config_dict['expect_prompts']['root_prompt'],directory=True)
		return res

	def build(self,shutit):
		config_dict = shutit.cfg
		container_child = util.get_pexpect_child('container_child')
		util.send_and_expect(container_child,'pushd /opt',config_dict['expect_prompts']['root_prompt'])
		util.install(container_child,config_dict,'git',config_dict['expect_prompts']['root_prompt'])
		util.send_and_expect(container_child,'git clone git://github.com/n1k0/casperjs.git',config_dict['expect_prompts']['root_prompt'])
		util.send_and_expect(container_child,'pushd casperjs',config_dict['expect_prompts']['root_prompt'])
		util.send_and_expect(container_child,'git checkout tags/1.0.2',config_dict['expect_prompts']['root_prompt'])
		util.send_and_expect(container_child,'popd',config_dict['expect_prompts']['root_prompt'])
		util.send_and_expect(container_child,'popd',config_dict['expect_prompts']['root_prompt'])
		return True

	def cleanup(self,shutit):
		config_dict = shutit.cfg
		container_child = util.get_pexpect_child('container_child')
		util.send_and_expect(container_child,'pushd /opt',config_dict['expect_prompts']['root_prompt'])
		util.send_and_expect(container_child,'popd /opt',config_dict['expect_prompts']['root_prompt'])
		return True

	def remove(self,shutit):
		config_dict = shutit.cfg
		container_child = util.get_pexpect_child('container_child')
		util.send_and_expect(container_child,'rm -rf /opt/casperjs',config_dict['expect_prompts']['root_prompt'])
		return True

if not util.module_exists('shutit.tk.casperjs.casperjs'):
	obj = casperjs('shutit.tk.casperjs.casperjs',0.314,'casperjs ShutIt module. See http://casperjs.org/')
	util.get_shutit_modules().add(obj)
	ShutItModule.register(casperjs)

<commit_msg>Cleanup casperjs library<commit_after>#The MIT License (MIT)
#
#Copyright (C) 2014 OpenBet Limited
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of
#this software and associated documentation files (the "Software"), to deal in
#the Software without restriction, including without limitation the rights to
#use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
#of the Software, and to permit persons to whom the Software is furnished to do
#so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all
#copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
#THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.

from shutit_module import ShutItModule
import util

class casperjs(ShutItModule):

	def is_installed(self,shutit):
		res = shutit.file_exists('/opt/casperjs',shutit.cfg['expect_prompts']['root_prompt'],directory=True)
		return res

	def build(self,shutit):
		cfg = shutit.cfg
		container_child = util.get_pexpect_child('container_child')
		shutit.set_default_expect(cfg['expect_prompts']['root_prompt'])
		util.install(container_child,cfg,'git',cfg['expect_prompts']['root_prompt'])
		shutit.run_script("""
			pushd /opt
			git clone git://github.com/n1k0/casperjs.git
			pushd casperjs
			git checkout tags/1.0.2
			popd
			popd
		""")
		return True

	def remove(self,shutit):
		shutit.send_and_expect('rm -rf /opt/casperjs',shutit.cfg['expect_prompts']['root_prompt'])
		return True

if not util.module_exists('shutit.tk.casperjs.casperjs'):
	obj = casperjs('shutit.tk.casperjs.casperjs',0.314,'casperjs ShutIt module. See http://casperjs.org/')
	util.get_shutit_modules().add(obj)
	ShutItModule.register(casperjs)

<|endoftext|>