<commit_before># Gen v0
# A generic, JSON-based asset pipeline for heterogeneous setups and
# unusual configurations.
#
# This is free and unencumbered software released into the public domain.
# For more information, please refer to <http://unlicense.org/>

import os
import shutil
import json
import subprocess
import jinja2
import sys
import imp

def get_input_output_file(asset_root, dist_root, f):
    return os.path.join(asset_root, f), os.path.join(dist_root, f)

class WrongSourceType(Exception):
    pass

class Environment:
    def __init__(self, root, dist_root):
        """Initialize the root and the dist root with given values."""
        self.root = root
        self.dist_root = dist_root

    def _notify_transform(self, input_file, output_file):
        print(os.path.relpath(input_file) + ' => ' +
              os.path.relpath(output_file))

    def _notify_skip(self, out_file):
        print('Skipping ' + os.path.relpath(out_file))

    def _notify_command(self, args):
        sys.stdout.write('Running:')
        for part in args:
            sys.stdout.write(' ' + part)
        sys.stdout.write('\n')

    def copy_if_newer(self, input_file, output_file):
        if (not os.path.exists(output_file) or
            os.path.getmtime(input_file) > os.path.getmtime(output_file)):
            # Make sure the destination directory exists.
            os.makedirs(os.path.dirname(output_file), exist_ok=True)
            # Copy the file
            shutil.copy(input_file, output_file)
            # Notify the environment
            self._notify_transform(input_file, output_file)
        else:
            # Notify the environment we are skipping this file.
            self._notify_skip(output_file)

    def file_from_content(self, input_file, content, output_file):
        os.makedirs(os.path.dirname(output_file), exist_ok=True)
        with open(output_file, "w") as f:
            f.write(content)
        self._notify_transform(input_file, output_file)

    def subprocess_transform(self, prg, options, input_file, output_file):
        args = [prg, input_file, output_file]
        args[1:1] = options

        os.makedirs(os.path.dirname(output_file), exist_ok=True)

        self._notify_command(args)
        if subprocess.call(args):
            self._notify_transform(input_file, output_file)

class BaseContentProvider:
    def __init__(self, asset_root, dist_root, type_options, env):
        # Don't rely on the cwd directory staying as it throughout the
        # lifetime of the object. That is, make absolute paths now.
        self.asset_root = os.path.abspath(asset_root)
        self.dist_root = os.path.abspath(dist_root)
        self.options = type_options
        self.env = env
        self._sources = []

    def install_content(self):
        """Install all files necessary and return a list of those files."""
        out_files = []
        for source in self._sources:
            out_files.append(self._install(source))
        return out_files

class StaticContentProvider(BaseContentProvider):
    def add_input(self, input_obj):
        # We just expect a string here.
        if not isinstance(input_obj, str):
            raise WrongSourceType

        # If we are given a directory, use all the files in that directory.
        input_abspath = os.path.join(self.asset_root, input_obj)
        if os.path.isdir(input_abspath):
            for child in os.listdir(input_abspath):
                self.add_input(os.path.join(input_abspath, child))
        # Otherwise it's just a file, easy.
        else:
            self._sources.append(os.path.normpath(input_abspath))

    def _install(self, source):
        source_rel = os.path.relpath(source, self.asset_root)
        input_file, output_file = get_input_output_file(self.asset_root,
                                                        self.dist_root,
                                                        source_rel)
        self.env.copy_if_newer(input_file, output_file)
        return output_file

class Jinja2ContentProvider(BaseContentProvider):
    def __init__(self, asset_root, dist_root, type_options, env):
        BaseContentProvider.__init__(self, asset_root, dist_root,
                                     type_options, env)
        self._jinja2env = (
               jinja2.Environment(loader=jinja2.FileSystemLoader(asset_root)))

    def add_input(self, input_obj):
        # Here we expect an object with a filename and parameters.
        if not isinstance(input_obj, dict):
            raise WrongSourceType

        # Do some basic validation, then just add it to our list. As long as
        # we should be fine.
        if 'filename' in input_obj:
            self._sources.append(input_obj)
        else:
            raise WrongSourceType("Filename required in source object!")

    def _install(self, source):
        # Remember, our filename is relative to the asset root.
        filename = source['filename']
        template = self._jinja2env.get_template(filename)

        parameters = source.get('parameters')
        if 'parameters' in source:
            rendered_template = template.render(source['parameters'])
        else:
            rendered_template = template.render()

        input_file, output_file = get_input_output_file(self.asset_root,
                                                        self.dist_root,
                                                        filename)
        self.env.file_from_content(input_file, rendered_template, output_file)
        return output_file

class ScssContentProvider(StaticContentProvider):
    def _install(self, source):
        source_rel = os.path.relpath(source, self.asset_root)
        input_file, output_file = get_input_output_file(self.asset_root,
                                                        self.dist_root,
                                                        source_rel)
        output_file = os.path.splitext(output_file)[0] + '.css'

        # Check for search paths provided.
        search_paths = self.options.get('search_paths', [])
        command_options = []
        for path in search_paths:
            command_options.extend(['--load-path',
                                    os.path.join(self.env.dist_root, path)])

        self.env.subprocess_transform('scss', command_options,
                                      input_file, output_file)
        return output_file

if __name__ == '__main__':
    # Parse the assets.json file.
    try:
        assets_json = json.load(open('assets.json'))
    except OSError:
        sys.exit('Failed to open the assets.json file!\n' +
                 'Make sure you are running gen from the correct ' +
                 'directory.\n')

    env = Environment(os.getcwd(),
                      os.path.abspath(assets_json.get('dist', 'dist/')))

    transformations = {'static': StaticContentProvider,
                       'jinja2': Jinja2ContentProvider,
                       'scss'  : ScssContentProvider}

    # This way, plugins can import gen.py!
    sys.path.insert(0, os.path.abspath(__file__))

    # Add user-defined plugin objects.
    for plugin_object in assets_json.get('plugins', []):
        plugin_name = os.path.splitext(plugin_object['file'])[0]
        plugin_path, plugin_name = os.path.split(plugin_name)

        module_descriptor = imp.find_module(plugin_name, [plugin_path])
        module = imp.load_module(os.path.splitext(plugin_object['file'])[0],
                                 module_descriptor[0],
                                 module_descriptor[1],
                                 module_descriptor[2])

        transformations[plugin_object['type']] = (
                                      getattr(module, plugin_object['class']))

    output = []
    for asset in assets_json.get('assets', []):
        # Find the asset-specific dist dir.
        asset_dist = os.path.join(env.dist_root,
                                  asset.get('dist', asset['root']))

        # Find our class!
        provider_class = transformations.get(asset['type'])
        if provider_class:
            provider = provider_class(asset['root'], asset_dist,
                                      asset.get('type_options', {}), env)
        else:
            sys.stderr.write('No plugin available to handle ' +
                             asset['type'] + ' assets.')
            continue

        # Tell the provider about it's input.
        for i in asset['input']:
            provider.add_input(i)
        # Install everything while recording what files were produced.
        output.extend(provider.install_content())

    for dirname, dirs, files in os.walk(env.dist_root, topdown=False):
        for f in files:
            # Check if the file should be there.
            f = os.path.join(dirname, f)
            if f not in output:
                print('Removing old file: ' + os.path.relpath(f))
                os.remove(os.path.join(env.dist_root, f))

        # Also remove empty children directories.
        for d in dirs:
            d = os.path.join(dirname, d)
            if len(os.listdir(d)) == 0:
                print('Removing empty directory: ' + os.path.relpath(d))
                os.rmdir(d)
<commit_msg>Added a missing newline to the missing plugin error message.<commit_after># Gen v0
# A generic, JSON-based asset pipeline for heterogeneous setups and
# unusual configurations.
#
# This is free and unencumbered software released into the public domain.
# For more information, please refer to <http://unlicense.org/>

import os
import shutil
import json
import subprocess
import jinja2
import sys
import imp

def get_input_output_file(asset_root, dist_root, f):
    return os.path.join(asset_root, f), os.path.join(dist_root, f)

class WrongSourceType(Exception):
    pass

class Environment:
    def __init__(self, root, dist_root):
        """Initialize the root and the dist root with given values."""
        self.root = root
        self.dist_root = dist_root

    def _notify_transform(self, input_file, output_file):
        print(os.path.relpath(input_file) + ' => ' +
              os.path.relpath(output_file))

    def _notify_skip(self, out_file):
        print('Skipping ' + os.path.relpath(out_file))

    def _notify_command(self, args):
        sys.stdout.write('Running:')
        for part in args:
            sys.stdout.write(' ' + part)
        sys.stdout.write('\n')

    def copy_if_newer(self, input_file, output_file):
        if (not os.path.exists(output_file) or
            os.path.getmtime(input_file) > os.path.getmtime(output_file)):
            # Make sure the destination directory exists.
            os.makedirs(os.path.dirname(output_file), exist_ok=True)
            # Copy the file
            shutil.copy(input_file, output_file)
            # Notify the environment
            self._notify_transform(input_file, output_file)
        else:
            # Notify the environment we are skipping this file.
            self._notify_skip(output_file)

    def file_from_content(self, input_file, content, output_file):
        os.makedirs(os.path.dirname(output_file), exist_ok=True)
        with open(output_file, "w") as f:
            f.write(content)
        self._notify_transform(input_file, output_file)

    def subprocess_transform(self, prg, options, input_file, output_file):
        args = [prg, input_file, output_file]
        args[1:1] = options

        os.makedirs(os.path.dirname(output_file), exist_ok=True)

        self._notify_command(args)
        if subprocess.call(args):
            self._notify_transform(input_file, output_file)

class BaseContentProvider:
    def __init__(self, asset_root, dist_root, type_options, env):
        # Don't rely on the cwd directory staying as it throughout the
        # lifetime of the object. That is, make absolute paths now.
        self.asset_root = os.path.abspath(asset_root)
        self.dist_root = os.path.abspath(dist_root)
        self.options = type_options
        self.env = env
        self._sources = []

    def install_content(self):
        """Install all files necessary and return a list of those files."""
        out_files = []
        for source in self._sources:
            out_files.append(self._install(source))
        return out_files

class StaticContentProvider(BaseContentProvider):
    def add_input(self, input_obj):
        # We just expect a string here.
        if not isinstance(input_obj, str):
            raise WrongSourceType

        # If we are given a directory, use all the files in that directory.
        input_abspath = os.path.join(self.asset_root, input_obj)
        if os.path.isdir(input_abspath):
            for child in os.listdir(input_abspath):
                self.add_input(os.path.join(input_abspath, child))
        # Otherwise it's just a file, easy.
        else:
            self._sources.append(os.path.normpath(input_abspath))

    def _install(self, source):
        source_rel = os.path.relpath(source, self.asset_root)
        input_file, output_file = get_input_output_file(self.asset_root,
                                                        self.dist_root,
                                                        source_rel)
        self.env.copy_if_newer(input_file, output_file)
        return output_file

class Jinja2ContentProvider(BaseContentProvider):
    def __init__(self, asset_root, dist_root, type_options, env):
        BaseContentProvider.__init__(self, asset_root, dist_root,
                                     type_options, env)
        self._jinja2env = (
               jinja2.Environment(loader=jinja2.FileSystemLoader(asset_root)))

    def add_input(self, input_obj):
        # Here we expect an object with a filename and parameters.
        if not isinstance(input_obj, dict):
            raise WrongSourceType

        # Do some basic validation, then just add it to our list. As long as
        # we should be fine.
        if 'filename' in input_obj:
            self._sources.append(input_obj)
        else:
            raise WrongSourceType("Filename required in source object!")

    def _install(self, source):
        # Remember, our filename is relative to the asset root.
        filename = source['filename']
        template = self._jinja2env.get_template(filename)

        parameters = source.get('parameters')
        if 'parameters' in source:
            rendered_template = template.render(source['parameters'])
        else:
            rendered_template = template.render()

        input_file, output_file = get_input_output_file(self.asset_root,
                                                        self.dist_root,
                                                        filename)
        self.env.file_from_content(input_file, rendered_template, output_file)
        return output_file

class ScssContentProvider(StaticContentProvider):
    def _install(self, source):
        source_rel = os.path.relpath(source, self.asset_root)
        input_file, output_file = get_input_output_file(self.asset_root,
                                                        self.dist_root,
                                                        source_rel)
        output_file = os.path.splitext(output_file)[0] + '.css'

        # Check for search paths provided.
        search_paths = self.options.get('search_paths', [])
        command_options = []
        for path in search_paths:
            command_options.extend(['--load-path',
                                    os.path.join(self.env.dist_root, path)])

        self.env.subprocess_transform('scss', command_options,
                                      input_file, output_file)
        return output_file

if __name__ == '__main__':
    # Parse the assets.json file.
    try:
        assets_json = json.load(open('assets.json'))
    except OSError:
        sys.exit('Failed to open the assets.json file!\n' +
                 'Make sure you are running gen from the correct ' +
                 'directory.\n')

    env = Environment(os.getcwd(),
                      os.path.abspath(assets_json.get('dist', 'dist/')))

    transformations = {'static': StaticContentProvider,
                       'jinja2': Jinja2ContentProvider,
                       'scss'  : ScssContentProvider}

    # This way, plugins can import gen.py!
    sys.path.insert(0, os.path.abspath(__file__))

    # Add user-defined plugin objects.
    for plugin_object in assets_json.get('plugins', []):
        plugin_name = os.path.splitext(plugin_object['file'])[0]
        plugin_path, plugin_name = os.path.split(plugin_name)

        module_descriptor = imp.find_module(plugin_name, [plugin_path])
        module = imp.load_module(os.path.splitext(plugin_object['file'])[0],
                                 module_descriptor[0],
                                 module_descriptor[1],
                                 module_descriptor[2])

        transformations[plugin_object['type']] = (
                                      getattr(module, plugin_object['class']))

    output = []
    for asset in assets_json.get('assets', []):
        # Find the asset-specific dist dir.
        asset_dist = os.path.join(env.dist_root,
                                  asset.get('dist', asset['root']))

        # Find our class!
        provider_class = transformations.get(asset['type'])
        if provider_class:
            provider = provider_class(asset['root'], asset_dist,
                                      asset.get('type_options', {}), env)
        else:
            sys.stderr.write('No plugin available to handle ' +
                             asset['type'] + ' assets.\n')
            continue

        # Tell the provider about it's input.
        for i in asset['input']:
            provider.add_input(i)
        # Install everything while recording what files were produced.
        output.extend(provider.install_content())

    for dirname, dirs, files in os.walk(env.dist_root, topdown=False):
        for f in files:
            # Check if the file should be there.
            f = os.path.join(dirname, f)
            if f not in output:
                print('Removing old file: ' + os.path.relpath(f))
                os.remove(os.path.join(env.dist_root, f))

        # Also remove empty children directories.
        for d in dirs:
            d = os.path.join(dirname, d)
            if len(os.listdir(d)) == 0:
                print('Removing empty directory: ' + os.path.relpath(d))
                os.rmdir(d)
<|endoftext|>


<commit_before>import random
import sys

import pygame
from pygame.locals import *

def gen_map(width=500, height=500):
    """ Returns a map of width x height tiles. """
    map = [[None for x in range(width)] for y in range(height)]
    for row in range(height):
        for col in range(width):
            # Choose a random color, for now
            map[row][col] = (random.randint(0, 255), random.randint(0, 255),
                             random.randint(0, 255))
    return map

def render(map):
    screen_size = len(map), len(map[0])
    surf = pygame.display.set_mode(screen_size, RESIZABLE)

    pygame.display.set_caption('Pyland Gen 1.0')

    BG_COLOR = (00, 00, 00)
    surf.fill(BG_COLOR)

    # Draw tiles
    for i in range(screen_size[0]):
        for j in range(screen_size[1]):
            size = (3, 3)
            px = pygame.Surface(size)
            color = map[i][j]
            px.fill(color)
            pos = (i * size[0], j * size[1])
            surf.blit(px, pos)

    pygame.display.flip()

def get_input():
    """ Wait for input. """
    for event in pygame.event.get():
        if event.type == QUIT:
            terminate()
        elif event.type == KEYDOWN:
            if event.key in (K_q, K_ESCAPE):
                terminate()
            elif event.key == K_SPACE:
                # TODO: regenerate planet
                pass

def terminate():
    pygame.quit()
    sys.exit()

def main():
    print('Pyland Gen 1.0')
    pygame.init()
    map = gen_map()
    render(map)
    while True:
        get_input()

if __name__ == '__main__':
    main()

<commit_msg>Try to build island border 1D perlin noise<commit_after>import random
import sys

import pygame
from noise import pnoise1, pnoise2, snoise2
from pygame.locals import *

def gen_border():
    """ Generate a border to apply to our island to build shoreline. """
    points = 360
    span = 5.0
    octaves = 1
    base = 0
    border = []
    for i in range(points):
        x = float(i) * span / points
        y = pnoise1(x + base, octaves)
        border.append(y)
    print(len(border))
    return border

def gen_shore(border, radius=300, scale=75):
    """ Apply our border to our island. """
    return [radius + y * scale for y in border]

def gen_map(width=500, height=500):
    """ Returns a map of width x height tiles. """
    # Initialize map to matrix of None
    map = [[None for x in range(width)] for y in range(height)]

    octaves = 2
    freq = 16.0 * octaves
    for row in range(height):
        for col in range(width):
            # Choose a random color, for now
            map[row][col] = (random.randint(0, 255), random.randint(0, 255),
                             random.randint(0, 255))
            # snoise?
            #shade1 = int(pnoise2(row/freq, col/freq, octaves) * 127.0 + 128.0)
            #shade2 = int(snoise2(row/freq, col/freq, octaves) * 127.0 + 128.0)
            #shade = (shade1 + shade2) % 255
            #map[row][col] = (shade, shade, shade)
    return map

def render(map):
    screen_size = len(map), len(map[0])
    surf = pygame.display.set_mode(screen_size, RESIZABLE)

    pygame.display.set_caption('Pyland Gen 1.0')

    BG_COLOR = (00, 00, 00)
    surf.fill(BG_COLOR)

    # Draw tiles
    for i in range(screen_size[0]):
        for j in range(screen_size[1]):
            size = (3, 3)
            px = pygame.Surface(size)
            color = map[i][j]
            px.fill(color)
            pos = (i * size[0], j * size[1])
            surf.blit(px, pos)

    pygame.display.flip()

def get_input():
    """ Wait for input. """
    for event in pygame.event.get():
        if event.type == QUIT:
            terminate()
        elif event.type == KEYDOWN:
            if event.key in (K_q, K_ESCAPE):
                terminate()
            elif event.key == K_SPACE:
                # TODO: regenerate planet
                pass

def terminate():
    pygame.quit()
    sys.exit()

def main():
    print('Pyland Gen 1.0')
    pygame.init()
    border = gen_border()
    map = gen_map()
    render(map)
    while True:
        get_input()

if __name__ == '__main__':
    main()

<|endoftext|>


<commit_before># Created By: Virgil Dupras
# Created On: 2011-02-01
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
# http://www.gnu.org/licenses/gpl-3.0.html

import sys
import io
import os.path as op
import os
import logging

from hscommon.util import first

from PyQt5.QtCore import QStandardPaths
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtWidgets import QDesktopWidget, QSpacerItem, QSizePolicy, QAction, QHBoxLayout

def moveToScreenCenter(widget):
    frame = widget.frameGeometry()
    frame.moveCenter(QDesktopWidget().availableGeometry().center())
    widget.move(frame.topLeft())

def verticalSpacer(size=None):
    if size:
        return QSpacerItem(1, size, QSizePolicy.Fixed, QSizePolicy.Fixed)
    else:
        return QSpacerItem(1, 1, QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)

def horizontalSpacer(size=None):
    if size:
        return QSpacerItem(size, 1, QSizePolicy.Fixed, QSizePolicy.Fixed)
    else:
        return QSpacerItem(1, 1, QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)

def horizontalWrap(widgets):
    """Wrap all widgets in `widgets` in a horizontal layout.

    If, instead of placing a widget in your list, you place an int or None, an horizontal spacer
    with the width corresponding to the int will be placed (0 or None means an expanding spacer).
    """
    layout = QHBoxLayout()
    for widget in widgets:
        if widget is None or isinstance(widget, int):
            layout.addItem(horizontalSpacer(size=widget))
        else:
            layout.addWidget(widget)
    return layout

def createActions(actions, target):
    # actions = [(name, shortcut, icon, desc, func)]
    for name, shortcut, icon, desc, func in actions:
        action = QAction(target)
        if icon:
            action.setIcon(QIcon(QPixmap(':/' + icon)))
        if shortcut:
            action.setShortcut(shortcut)
        action.setText(desc)
        action.triggered.connect(func)
        setattr(target, name, action)

def setAccelKeys(menu):
    actions = menu.actions()
    titles = [a.text() for a in actions]
    available_characters = {c.lower() for s in titles for c in s if c.isalpha()}
    for action in actions:
        text = action.text()
        c = first(c for c in text if c.lower() in available_characters)
        if c is None:
            continue
        i = text.index(c)
        newtext = text[:i] + '&' + text[i:]
        available_characters.remove(c.lower())
        action.setText(newtext)

def getAppData():
    return QStandardPaths.standardLocations(QStandardPaths.DataLocation)[0]

class SysWrapper(io.IOBase):
    def write(self, s):
        if s.strip(): # don't log empty stuff
            logging.warning(s)

def setupQtLogging(level=logging.WARNING, log_to_stdout=False):
    # Under Qt, we log in "debug.log" in appdata. Moreover, when under cx_freeze, we have a
    # problem because sys.stdout and sys.stderr are None, so we need to replace them with a
    # wrapper that logs with the logging module.
    appdata = getAppData()
    if not op.exists(appdata):
        os.makedirs(appdata)
    # For basicConfig() to work, we have to be sure that no logging has taken place before this call.
    filename = op.join(appdata, 'debug.log') if not log_to_stdout else None
    logging.basicConfig(
        filename=filename, level=level,
        format='%(asctime)s - %(levelname)s - %(message)s'
    )
    if sys.stderr is None: # happens under a cx_freeze environment
        sys.stderr = SysWrapper()
    if sys.stdout is None:
        sys.stdout = SysWrapper()

def escapeamp(s):
    # Returns `s` with escaped ampersand (& --> &&). QAction text needs to have & escaped because
    # that character is used to define "accel keys".
    return s.replace('&', '&&')
<commit_msg>Set encoding on Log file<commit_after># Created By: Virgil Dupras
# Created On: 2011-02-01
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "GPLv3" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
# http://www.gnu.org/licenses/gpl-3.0.html

import sys
import io
import os.path as op
import os
import logging

from hscommon.util import first

from PyQt5.QtCore import QStandardPaths
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtWidgets import QDesktopWidget, QSpacerItem, QSizePolicy, QAction, QHBoxLayout

def moveToScreenCenter(widget):
    frame = widget.frameGeometry()
    frame.moveCenter(QDesktopWidget().availableGeometry().center())
    widget.move(frame.topLeft())

def verticalSpacer(size=None):
    if size:
        return QSpacerItem(1, size, QSizePolicy.Fixed, QSizePolicy.Fixed)
    else:
        return QSpacerItem(1, 1, QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)

def horizontalSpacer(size=None):
    if size:
        return QSpacerItem(size, 1, QSizePolicy.Fixed, QSizePolicy.Fixed)
    else:
        return QSpacerItem(1, 1, QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)

def horizontalWrap(widgets):
    """Wrap all widgets in `widgets` in a horizontal layout.

    If, instead of placing a widget in your list, you place an int or None, an horizontal spacer
    with the width corresponding to the int will be placed (0 or None means an expanding spacer).
    """
    layout = QHBoxLayout()
    for widget in widgets:
        if widget is None or isinstance(widget, int):
            layout.addItem(horizontalSpacer(size=widget))
        else:
            layout.addWidget(widget)
    return layout

def createActions(actions, target):
    # actions = [(name, shortcut, icon, desc, func)]
    for name, shortcut, icon, desc, func in actions:
        action = QAction(target)
        if icon:
            action.setIcon(QIcon(QPixmap(':/' + icon)))
        if shortcut:
            action.setShortcut(shortcut)
        action.setText(desc)
        action.triggered.connect(func)
        setattr(target, name, action)

def setAccelKeys(menu):
    actions = menu.actions()
    titles = [a.text() for a in actions]
    available_characters = {c.lower() for s in titles for c in s if c.isalpha()}
    for action in actions:
        text = action.text()
        c = first(c for c in text if c.lower() in available_characters)
        if c is None:
            continue
        i = text.index(c)
        newtext = text[:i] + '&' + text[i:]
        available_characters.remove(c.lower())
        action.setText(newtext)

def getAppData():
    return QStandardPaths.standardLocations(QStandardPaths.DataLocation)[0]

class SysWrapper(io.IOBase):
    def write(self, s):
        if s.strip(): # don't log empty stuff
            logging.warning(s)

def setupQtLogging(level=logging.WARNING, log_to_stdout=False):
    # Under Qt, we log in "debug.log" in appdata. Moreover, when under cx_freeze, we have a
    # problem because sys.stdout and sys.stderr are None, so we need to replace them with a
    # wrapper that logs with the logging module.
    appdata = getAppData()
    if not op.exists(appdata):
        os.makedirs(appdata)
    # Setup logging
    # Have to use full configuration over basicConfig as FileHandler encoding was not being set.
    filename = op.join(appdata, 'debug.log') if not log_to_stdout else None
    log = logging.getLogger()
    handler = logging.FileHandler(filename, 'a', 'utf-8')
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    log.addHandler(handler)
    if sys.stderr is None: # happens under a cx_freeze environment
        sys.stderr = SysWrapper()
    if sys.stdout is None:
        sys.stdout = SysWrapper()

def escapeamp(s):
    # Returns `s` with escaped ampersand (& --> &&). QAction text needs to have & escaped because
    # that character is used to define "accel keys".
    return s.replace('&', '&&')
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""Generator for model"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from builtins import range

import argparse
import os
import sys
import random
import pickle

import torch
from torch.autograd import Variable
# Import my own cleaning lib, use jieba for other user
try:
    from purewords import clean_sentence as clean
except ImportError:
    from jieba import lcut as clean
import model
import utils
from utils import check_cuda_for_var, check_directory

parser = argparse.ArgumentParser(description=\
        "Generator for HRNN/Seq2seq")
parser.add_argument('--data', type=str,
        help="location of the data corpus(json file)")
parser.add_argument('--type', type=str,
        help="generate dialog with hrnn/seq2seq model")
parser.add_argument('--save', type=str, default='model/',
        help='path to load the final model\'s directory')
parser.add_argument('--seed', type=int, default=55665566,
        help='random seed')
parser.add_argument('--beam', type=int, default=1,
        help='beam size for beam search(default 1 will be greedy search)')
args = parser.parse_args()

torch.manual_seed(args.seed)
random.seed(args.seed)

if args.type != "hrnn" and args.type != "seq2seq":
    raise ValueError("args.type should be hrnn or seq2seq, but got %s" % (args.type))
if not os.path.isfile('dict.pkl'):
    my_lang, _ = utils.build_lang(args.data)
    with open('dict.pkl', 'wb') as filename:
        pickle.dump(my_lang, filename)
else:
    print("Load dict.pkl")
    with open('dict.pkl', 'rb') as filename:
        my_lang = pickle.load(filename)
if args.type == "hrnn":
    # Load last HRNN model
    number = torch.load(os.path.join(args.save, 'checkpoint.pt'))
    encoder = torch.load(os.path.join(args.save, 'encoder'+str(number)+'.pt'))
    context = torch.load(os.path.join(args.save, 'context'+str(number)+'.pt'))
    decoder = torch.load(os.path.join(args.save, 'decoder'+str(number)+'.pt'))
    if torch.cuda.is_available():
        encoder = encoder.cuda()
        context = context.cuda()
        decoder = decoder.cuda()
    def gen(sentence):
        encoder.eval()
        context.eval()
        decoder.eval()

        # Inference
        gen_sentence = []
        talking_history = []
        context_hidden = context.init_hidden()
        counter = 0
        beam_size = args.beam
        while counter < 10:
            decoder_input = Variable(torch.LongTensor([[my_lang.word2index["SOS"]]]))
            decoder_input = check_cuda_for_var(decoder_input)
            encoder_hidden = encoder.init_hidden()
            decoder_hidden = decoder.init_hidden()
            if len(gen_sentence) > 0:
                for ei in range(len(gen_sentence)):
                    _, encoder_hidden = encoder(gen_sentence[ei], encoder_hidden)
                # Clean generated sentence list
                gen_sentence = []
            else:
                for ei in range(len(sentence)):
                    _, encoder_hidden = encoder(sentence[ei], encoder_hidden)
            context_output, context_hidden = context(encoder_hidden, context_hidden)
            # TODO Beam search
            # Take care of decoder_hidden
            scores = check_cuda_for_var(torch.FloatTensor(beam_size).zero_())
            while True:
                gen_sentence.append(decoder_input.data[0][0])
                if gen_sentence[-1] == my_lang.word2index["EOS"] or len(gen_sentence) > 15:
                    break
                decoder_output, decoder_hidden = decoder(context_hidden,\
                        decoder_input, decoder_hidden)
                _, topi = decoder_output.data.topk(1)
                ni = topi[0][0]
                decoder_input = Variable(torch.LongTensor([[ni]]))
                decoder_input = check_cuda_for_var(decoder_input)
            gen_sentence = Variable(torch.LongTensor(gen_sentence))
            gen_sentence = check_cuda_for_var(gen_sentence)
            string = ' '.join([my_lang.index2word[word.data[0]] for word in gen_sentence])
            print(string)
            talking_history.append(string)
            if "EOD" in string:
                break
            counter += 1
        return talking_history
else:
    # Load last Seq2seq model
    number = torch.load(os.path.join(args.save, 'checkpoint.pt'))
    encoder = torch.load(os.path.join(args.save, 'encoder'+str(number)+'.pt'))
    decoder = torch.load(os.path.join(args.save, 'decoder'+str(number)+'.pt'))
    if torch.cuda.is_available():
        encoder = encoder.cuda()
        decoder = decoder.cuda()
    def gen(sentence):
        max_length = 16
        encoder.eval()
        decoder.eval()
        talking_history = []
        gen_sentence = []
        counter = 0
        while counter < 10:
            encoder_hidden = encoder.init_hidden()
            encoder_outputs = Variable(torch.zeros(max_length, encoder.hidden_size))
            decoder_input = Variable(torch.LongTensor([[my_lang.word2index["SOS"]]]))
            encoder_outputs = check_cuda_for_var(encoder_outputs)
            decoder_input = check_cuda_for_var(decoder_input)
            if len(gen_sentence) > 0:
                for ei in range(len(gen_sentence)):
                    encoder_output, encoder_hidden = encoder(gen_sentence[ei], encoder_hidden)
                    encoder_outputs[ei] = encoder_output[0][0]
                    # Clean generated sentence list
                gen_sentence = []
            else:
                for ei in range(len(sentence)):
                    encoder_output, encoder_hidden = encoder(sentence[ei], encoder_hidden)
                    encoder_outputs[ei] = encoder_output[0][0]
            decoder_hidden = encoder_hidden
            while True:
                gen_sentence.append(decoder_input.data[0][0])
                if gen_sentence[-1] == my_lang.word2index["EOS"] or len(gen_sentence) >= max_length - 1:
                    break
                decoder_output, decoder_hidden, decoder_attention = decoder(decoder_input, decoder_hidden, \
                        encoder_outputs)
                _, topi = decoder_output.data.topk(1)
                ni = topi[0][0]
                decoder_input = Variable(torch.LongTensor([[ni]]))
                decoder_input = check_cuda_for_var(decoder_input)
            gen_sentence = Variable(torch.LongTensor(gen_sentence))
            gen_sentence = check_cuda_for_var(gen_sentence)
            string = ' '.join([my_lang.index2word[word.data[0]] for word in gen_sentence])
            print(string)
            talking_history.append(string)
            if "EOD" in string:
                break
            counter += 1
        return talking_history
# Generating string
try:
    while True:
        start = input("[%s] >>> " % (args.type.upper()))
        clean_sentence = clean(start)
        clean_sentence_idx = my_lang.sentence2index(clean_sentence)
        clean_sentence_idx = Variable(torch.LongTensor(clean_sentence_idx))
        clean_sentence_idx = check_cuda_for_var(clean_sentence_idx)
        gen(clean_sentence_idx)
except KeyboardInterrupt:
    print()
<commit_msg>Simplified the conditional variable and loop<commit_after># -*- coding: utf-8 -*-
"""Generator for model"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from builtins import range

import argparse
import os
import sys
import random
import pickle

import torch
from torch.autograd import Variable
# Import my own cleaning lib, use jieba for other user
try:
    from purewords import clean_sentence as clean
except ImportError:
    from jieba import lcut as clean
import model
import utils
from utils import check_cuda_for_var, check_directory

parser = argparse.ArgumentParser(description=\
        "Generator for HRNN/Seq2seq")
parser.add_argument('--data', type=str,
        help="location of the data corpus(json file)")
parser.add_argument('--type', type=str,
        help="generate dialog with hrnn/seq2seq model")
parser.add_argument('--save', type=str, default='model/',
        help='path to load the final model\'s directory')
parser.add_argument('--seed', type=int, default=55665566,
        help='random seed')
parser.add_argument('--beam', type=int, default=1,
        help='beam size for beam search(default 1 will be greedy search)')
args = parser.parse_args()

torch.manual_seed(args.seed)
random.seed(args.seed)

if args.type != "hrnn" and args.type != "seq2seq":
    raise ValueError("args.type should be hrnn or seq2seq, but got %s" % (args.type))
if not os.path.isfile('dict.pkl'):
    my_lang, _ = utils.build_lang(args.data)
    with open('dict.pkl', 'wb') as filename:
        pickle.dump(my_lang, filename)
else:
    print("Load dict.pkl")
    with open('dict.pkl', 'rb') as filename:
        my_lang = pickle.load(filename)
if args.type == "hrnn":
    # Load last HRNN model
    number = torch.load(os.path.join(args.save, 'checkpoint.pt'))
    encoder = torch.load(os.path.join(args.save, 'encoder'+str(number)+'.pt'))
    context = torch.load(os.path.join(args.save, 'context'+str(number)+'.pt'))
    decoder = torch.load(os.path.join(args.save, 'decoder'+str(number)+'.pt'))
    if torch.cuda.is_available():
        encoder = encoder.cuda()
        context = context.cuda()
        decoder = decoder.cuda()
    def gen(sentence):
        encoder.eval()
        context.eval()
        decoder.eval()

        # Inference
        gen_sentence = []
        talking_history = []
        context_hidden = context.init_hidden()
        max_dialog_len = 10
        max_sentence_len = 15
        beam_size = args.beam
        for _ in range(max_dialog_len):
            decoder_input = Variable(torch.LongTensor([[my_lang.word2index["SOS"]]]))
            decoder_input = check_cuda_for_var(decoder_input)
            encoder_hidden = encoder.init_hidden()
            decoder_hidden = decoder.init_hidden()
            if len(gen_sentence) > 0:
                for ei in range(len(gen_sentence)):
                    _, encoder_hidden = encoder(gen_sentence[ei], encoder_hidden)
                # Clean generated sentence list
                gen_sentence = []
            else:
                for ei in range(len(sentence)):
                    _, encoder_hidden = encoder(sentence[ei], encoder_hidden)
            context_output, context_hidden = context(encoder_hidden, context_hidden)
            # TODO Beam search
            # Take care of decoder_hidden
            scores = check_cuda_for_var(torch.FloatTensor(beam_size).zero_())
            for sentence_pointer in range(max_sentence_len):
                gen_sentence.append(decoder_input.data[0][0])
                if gen_sentence[-1] == my_lang.word2index["EOS"]:
                    break
                decoder_output, decoder_hidden = decoder(context_hidden,\
                        decoder_input, decoder_hidden)
                _, topi = decoder_output.data.topk(1)
                ni = topi[0][0]
                decoder_input = Variable(torch.LongTensor([[ni]]))
                decoder_input = check_cuda_for_var(decoder_input)
            gen_sentence = Variable(torch.LongTensor(gen_sentence))
            gen_sentence = check_cuda_for_var(gen_sentence)
            string = ' '.join([my_lang.index2word[word.data[0]] for word in gen_sentence])
            print(string)
            talking_history.append(string)
            if "EOD" in string:
                break
        return talking_history
else:
    # Load last Seq2seq model
    number = torch.load(os.path.join(args.save, 'checkpoint.pt'))
    encoder = torch.load(os.path.join(args.save, 'encoder'+str(number)+'.pt'))
    decoder = torch.load(os.path.join(args.save, 'decoder'+str(number)+'.pt'))
    if torch.cuda.is_available():
        encoder = encoder.cuda()
        decoder = decoder.cuda()
    def gen(sentence):
        max_length = 16
        encoder.eval()
        decoder.eval()
        talking_history = []
        gen_sentence = []
        counter = 0
        while counter < 10:
            encoder_hidden = encoder.init_hidden()
            encoder_outputs = Variable(torch.zeros(max_length, encoder.hidden_size))
            decoder_input = Variable(torch.LongTensor([[my_lang.word2index["SOS"]]]))
            encoder_outputs = check_cuda_for_var(encoder_outputs)
            decoder_input = check_cuda_for_var(decoder_input)
            if len(gen_sentence) > 0:
                for ei in range(len(gen_sentence)):
                    encoder_output, encoder_hidden = encoder(gen_sentence[ei], encoder_hidden)
                    encoder_outputs[ei] = encoder_output[0][0]
                    # Clean generated sentence list
                gen_sentence = []
            else:
                for ei in range(len(sentence)):
                    encoder_output, encoder_hidden = encoder(sentence[ei], encoder_hidden)
                    encoder_outputs[ei] = encoder_output[0][0]
            decoder_hidden = encoder_hidden
            while True:
                gen_sentence.append(decoder_input.data[0][0])
                if gen_sentence[-1] == my_lang.word2index["EOS"] or len(gen_sentence) >= max_length - 1:
                    break
                decoder_output, decoder_hidden, decoder_attention = decoder(decoder_input, decoder_hidden, \
                        encoder_outputs)
                _, topi = decoder_output.data.topk(1)
                ni = topi[0][0]
                decoder_input = Variable(torch.LongTensor([[ni]]))
                decoder_input = check_cuda_for_var(decoder_input)
            gen_sentence = Variable(torch.LongTensor(gen_sentence))
            gen_sentence = check_cuda_for_var(gen_sentence)
            string = ' '.join([my_lang.index2word[word.data[0]] for word in gen_sentence])
            print(string)
            talking_history.append(string)
            if "EOD" in string:
                break
            counter += 1
        return talking_history
# Generating string
try:
    while True:
        start = input("[%s] >>> " % (args.type.upper()))
        clean_sentence = clean(start)
        clean_sentence_idx = my_lang.sentence2index(clean_sentence)
        clean_sentence_idx = Variable(torch.LongTensor(clean_sentence_idx))
        clean_sentence_idx = check_cuda_for_var(clean_sentence_idx)
        gen(clean_sentence_idx)
except KeyboardInterrupt:
    print()
<|endoftext|>


<commit_before>import re
import random
import bisect

#http://www.gefeg.com/edifact/d03a/s3/codes/cl1h.htm
#This is a terrible method, but it works for now
state_names = ['Andhra Pradesh', 'Arunachal Pradesh', 'Assam', 'Bihar', 'Chhattisgarh', 'Delhi', 'Goa', 'Gujarat', 'Haryana', 'Himachal Pradesh', 'Jammu and Kashmir', 'Jharkhand', 'Karnataka', 'Kerala', 'Madhya Pradesh', 'Maharashtra', 'Manipur', 'Meghalaya', 'Mizoram', 'Nagaland', 'Odisha', 'Punjab', 'Rajasthan', 'Sikkim', 'Tamil Nadu', 'Tripura', 'Uttar Pradesh', 'Uttarakhand', 'West Bengal']
state_abbreviations = ['AP', 'AR', 'AS', 'BR', 'CT', 'DL', 'GA', 'GJ', 'HR', 'HP', 'JK', 'JH', 'KA', 'KL', 'MP', 'MH', 'MN', 'ML', 'MZ', 'NL', 'OR', 'PB', 'RJ', 'SK', 'TN', 'TR', 'UP', 'UT', 'WB']

#Other utility methods (that aren't input/output) which multiple
#files might need go here

def clean_state_filename(filename):
    #The name is the first thing in the filename
    #it is always followed by a non-word character
    #sometimes & is in the name, so allow that
    state = re.sub(r'\.CSV', '', filename)
    state = re.sub(r'\([A-Z&]*\)', '', state)
    state = re.sub(r'[()\d]', '', state)
    return clean_state_name(state)

def clean_state_name(state):
    state = re.sub('Nct of Delhi', 'Delhi', state)
    state = re.sub('JAMMU', 'Jammu', state)
    state = re.sub('Utter', 'Uttar Pradesh', state)
    state = re.sub('Himacahl', 'Himachal', state)
    state = re.sub('&', 'and', state)
    state = state.strip()
    if state not in state_names:
        print 'Warning: state name not found while cleaning:', state

def avg(x):
    return float(sum(x)/len(x))
    return state

class FilterPopulation(object):

    def __init__(self, cost_threshold, eye_health_threshold, population):
        self.cost_threshold = cost_threshold
        self.eye_health_threshold = avg([person.eye_health for person in population])
        print 'calculated dummy threshold', self.eye_health_threshold

    def filter_all(self, person):
        return self.filter_health(person) and self.filter_money(person)

    def filter_health(self, person):
        return self.filter_eye_health(person)

    def filter_eye_health(self, person):
        return person.eye_health <= self.eye_health_threshold

    def filter_money(self, person):
        return person.money>=self.cost_threshold

class Location(object):
    def __init__(self, state_name, district_name, classification):
        self.state_name = state_name
        self.district_name = district_name
        self.classification = classification

    def is_in(self, location):
        if not self.district_name == location.district_name:
            return False
        if not self.state_name == location.state:
            return False
        if location.classification == 'total' or self.classification == location.classification:
            return True

#http://stackoverflow.com/questions/3679694/a-weighted-version-of-random-choice
#Given a set of choices and corresponding weights, choose a random option
#using the appropriate weight
def weighted_choice(choices, weights):
    #Convert the weights into cumulative weights
    cumulative_weights = []
    total = 0
    for weight in weights:
        total += weight
        cumulative_weights.append(total)
    #total should 1 if weights is a proper distribution
    rnd = random.random() * total
    i = bisect.bisect(cumulative_weights, rnd)
    return choices[i]
<commit_msg>Fix dumb typo<commit_after>import re
import random
import bisect

#http://www.gefeg.com/edifact/d03a/s3/codes/cl1h.htm
#This is a terrible method, but it works for now
state_names = ['Andhra Pradesh', 'Arunachal Pradesh', 'Assam', 'Bihar', 'Chhattisgarh', 'Delhi', 'Goa', 'Gujarat', 'Haryana', 'Himachal Pradesh', 'Jammu and Kashmir', 'Jharkhand', 'Karnataka', 'Kerala', 'Madhya Pradesh', 'Maharashtra', 'Manipur', 'Meghalaya', 'Mizoram', 'Nagaland', 'Odisha', 'Punjab', 'Rajasthan', 'Sikkim', 'Tamil Nadu', 'Tripura', 'Uttar Pradesh', 'Uttarakhand', 'West Bengal']
state_abbreviations = ['AP', 'AR', 'AS', 'BR', 'CT', 'DL', 'GA', 'GJ', 'HR', 'HP', 'JK', 'JH', 'KA', 'KL', 'MP', 'MH', 'MN', 'ML', 'MZ', 'NL', 'OR', 'PB', 'RJ', 'SK', 'TN', 'TR', 'UP', 'UT', 'WB']

#Other utility methods (that aren't input/output) which multiple
#files might need go here

def clean_state_filename(filename):
    #The name is the first thing in the filename
    #it is always followed by a non-word character
    #sometimes & is in the name, so allow that
    state = re.sub(r'\.CSV', '', filename)
    state = re.sub(r'\([A-Z&]*\)', '', state)
    state = re.sub(r'[()\d]', '', state)
    return clean_state_name(state)

def clean_state_name(state):
    state = re.sub('Nct of Delhi', 'Delhi', state)
    state = re.sub('JAMMU', 'Jammu', state)
    state = re.sub('Utter', 'Uttar Pradesh', state)
    state = re.sub('Himacahl', 'Himachal', state)
    state = re.sub('&', 'and', state)
    state = state.strip()
    if state not in state_names:
        print 'Warning: state name not found while cleaning:', state
    return state

def avg(x):
    return float(sum(x)/len(x))

class FilterPopulation(object):

    def __init__(self, cost_threshold, eye_health_threshold, population):
        self.cost_threshold = cost_threshold
        self.eye_health_threshold = avg([person.eye_health for person in population])
        print 'calculated dummy threshold', self.eye_health_threshold

    def filter_all(self, person):
        return self.filter_health(person) and self.filter_money(person)

    def filter_health(self, person):
        return self.filter_eye_health(person)

    def filter_eye_health(self, person):
        return person.eye_health <= self.eye_health_threshold

    def filter_money(self, person):
        return person.money>=self.cost_threshold

class Location(object):
    def __init__(self, state_name, district_name, classification):
        self.state_name = state_name
        self.district_name = district_name
        self.classification = classification

    def is_in(self, location):
        if not self.district_name == location.district_name:
            return False
        if not self.state_name == location.state:
            return False
        if location.classification == 'total' or self.classification == location.classification:
            return True

#http://stackoverflow.com/questions/3679694/a-weighted-version-of-random-choice
#Given a set of choices and corresponding weights, choose a random option
#using the appropriate weight
def weighted_choice(choices, weights):
    #Convert the weights into cumulative weights
    cumulative_weights = []
    total = 0
    for weight in weights:
        total += weight
        cumulative_weights.append(total)
    #total should 1 if weights is a proper distribution
    rnd = random.random() * total
    i = bisect.bisect(cumulative_weights, rnd)
    return choices[i]
<|endoftext|>


<commit_before>from __future__ import with_statement
import time
import socket
import threading
import collections

def synchronized(method):
    master_lock = threading.Lock()
    lock_name = "_synchronized_lock"

    def _method(self, *args, **keys):
        lock = getattr(self, lock_name, None)
        if lock is None:
            with master_lock:
                lock = getattr(self, lock_name, None)
                if lock is None:
                    lock = threading.RLock()
                    setattr(self, lock_name, lock)
        with lock:
            return method(self, *args, **keys)
    return _method

class LineBuffer(object):
    def __init__(self):
        self.buffer = list()
        self.pending = collections.deque()

    def feed(self, data=""):
        lines = (data + " ").splitlines()
        for line in lines[:-1]:
            self.buffer.append(line)
            self.pending.append("".join(self.buffer))
            self.buffer = list()

        data = lines[-1][:-1]
        if data:
            self.buffer.append(data)

        while self.pending:
            yield self.pending.popleft()

class TimedCache(object):
    def __init__(self, cache_time):
        self.cache = dict()
        self.queue = collections.deque()
        self.cache_time = cache_time

    def _expire(self):
        current_time = time.time()

        while self.queue:
            expire_time, key = self.queue[0]
            if expire_time > current_time:
                break
            self.queue.popleft()

            other_time, _ = self.cache[key]
            if other_time == expire_time:
                del self.cache[key]

    def get(self, key, default):
        self._expire()
        if key not in self.cache:
            return default
        _, value = self.cache[key]
        return value

    def set(self, key, value):
        self._expire()
        expire_time = time.time() + self.cache_time
        self.queue.append((expire_time, key))
        self.cache[key] = expire_time, value

def guess_encoding(text):
    if isinstance(text, unicode):
        return text

    for encoding in ["ascii", "utf-8", "latin-1"]:
        try:
            return text.decode(encoding)
        except UnicodeDecodeError:
            pass
    return text.decode("ascii", "replace")
<commit_msg>Removed util.synchronized. It was broken, slow and too easy to use without thinking. Cleaned util.py up a bit.<commit_after>import time
import collections

class LineBuffer(object):
    def __init__(self):
        self.buffer = list()
        self.pending = collections.deque()

    def feed(self, data=""):
        lines = (data + " ").splitlines()
        for line in lines[:-1]:
            self.buffer.append(line)
            self.pending.append("".join(self.buffer))
            self.buffer = list()

        data = lines[-1][:-1]
        if data:
            self.buffer.append(data)

        while self.pending:
            yield self.pending.popleft()

class TimedCache(object):
    def __init__(self, cache_time):
        self.cache = dict()
        self.queue = collections.deque()
        self.cache_time = cache_time

    def _expire(self):
        current_time = time.time()

        while self.queue:
            expire_time, key = self.queue[0]
            if expire_time > current_time:
                break
            self.queue.popleft()

            other_time, _ = self.cache[key]
            if other_time == expire_time:
                del self.cache[key]

    def get(self, key, default):
        self._expire()
        if key not in self.cache:
            return default
        _, value = self.cache[key]
        return value

    def set(self, key, value):
        self._expire()
        expire_time = time.time() + self.cache_time
        self.queue.append((expire_time, key))
        self.cache[key] = expire_time, value

def guess_encoding(text):
    if isinstance(text, unicode):
        return text

    for encoding in ["ascii", "utf-8", "latin-1"]:
        try:
            return text.decode(encoding)
        except UnicodeDecodeError:
            pass
    return text.decode("ascii", "replace")
<|endoftext|>


<commit_before>
import os
import subprocess
from contextlib import ContextDecorator

class cd(ContextDecorator):
    """Context manager/decorator for changing the current working directory."""
    def __init__(self, new_path):
        self.new_path = os.path.expanduser(new_path)

    def __enter__(self):
        self.previous_path = os.getcwd()
        os.chdir(self.new_path)
        return self

    def __exit__(self, *exc):
        os.chdir(self.previous_path)
        return False

# TODO use same context for all methods
class git:
    """Minimal git wrapper, providing only funtions to init add and commit."""
    path = ''
    def __init__(self, path):
        assert os.path.isabs(path)
        self.path = path

    @cd(path)
    def init(self):
        print('current dir: {}'.format(os.getcwd()))
        subprocess.call('git init')

    def add(self, filenames):
        for filename in filenames:
            assert os.path.isfile(filename)  # needs entire path
            subprocess.call('git add ' + filename)

    def commit(self, date, message=''):
        subprocess.call(
            "git commit -m '{m}' --date {d}".format(m=message, d=date)
        )
<commit_msg>Back to simple context manager.<commit_after>
import os
import re
import subprocess

DATE_REGEX = '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}'  # ISO 8601

class cd:
    """Context manager for changing the current working directory."""
    def __init__(self, new_path):
        self.new_path = os.path.expanduser(new_path)

    def __enter__(self):
        self.previous_path = os.getcwd()
        os.chdir(self.new_path)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.previous_path)

class git:
    """Minimal git wrapper, providing only: init, add and commit."""

    def __init__(self, path):
        # TODO create path if it does not exist?
        assert os.path.isabs(path)
        self.path = path

    def init(self):
        with cd(self.path):
            subprocess.call('git init')

    def add(self, filenames):
        with cd(self.path):
            for filename in filenames:
                assert os.path.isfile(filename)  # needs entire path
                subprocess.call('git add ' + filename)

    def commit(self, date, message=''):
        assert re.compile(DATE_REGEX).match(date)
        with cd(self.path):
            subprocess.call(
                "git commit -m '{m}' --date {d}".format(m=message, d=date)
            )
<|endoftext|>


<commit_before>import numpy
from theano import function

class StateComputer(object):
    """Convenient interface to theano function for computing states/cells
    of a trained SequenceGenerator model.

    Expects a Model instance as argument. This model must also be created
    from a SequenceGenerator.cost application. Furthermore, expects a dict
    that maps from characters to indices.
    Extracts the model's inputs and auxiliary variables into attributes
    and creates theano function from inputs to auxiliary vars.

    Finally, provides a method that wraps the output of the theano function in
    a dict keyed by auxiliary variable labels.
    """

    def __init__(self, cost_model, map_char_to_ind):
        raw_state_vars = filter(self._relevant, cost_model.auxiliary_variables)
        self.state_variables = sorted(raw_state_vars, key=lambda var: var.name)
        self.state_var_names = [var.name for var in self.state_variables]
        self.inputs = sorted(cost_model.inputs, key=lambda var: var.name)
        self.func = function(self.inputs, self.state_variables)
        self.map_char_to_ind = map_char_to_ind

    def _relevant(self, aux_var):
        not_final_value = "final_value" not in aux_var.name
        cell_or_state = "states" in aux_var.name or "cells" in aux_var.name
        return cell_or_state and not_final_value

    def read_single_sequence(self, sequence):
        """Combines list of aux var values (output from theano func) with their
        corresponding labels.

        New and improved with (I think) more convenient interface.
        - as input provide a list (or something array-like, i.e. that can be
        converted to a numpy array) of either characters or their representing
        integers. If a list of characters is provided, the conversion is done
        in this method. NOTE that a string is more or less a list of characters
        for the purpose of this method =)
        - the theano function expects a 2D input where the first dimension is
        batch_size. This "fake" dimension is added below, so don't wrap the
        input sequence yourself.
        - because the cost was originally defined with a mask, the theano
        function needs one, as well. This mask is constructed below so you
        don't have to provide it yourself.
        """
        if all(isinstance(entry, str) for entry in sequence):
            indices = [self.map_char_to_ind[char] for char in sequence]
            converted_sequence = numpy.array([indices], dtype="int32")
        elif all(isinstance(entry, int) for entry in sequence):
            converted_sequence = numpy.array([sequence], dtype="int32")
        else:
            raise ValueError("Some or all sequence elements have invalid type "
                             "(should be str or int)!")
        mask = numpy.ones(converted_sequence.shape, dtype="int8")
        return dict(zip(self.state_var_names, self.func(converted_sequence, mask)))

def mark_seq_len(seq):
    return numpy.arange(len(seq))

def mark_word_boundaries(seq):
    # define what's considered a word boundary. It's a set on purpose to permit
    # adding more character types as needed.
    wb = {
        " "
    }
    return numpy.array([1 if char in wb else 0 for char in seq])
<commit_msg>Adds func to remove batch dim from aux var output<commit_after>import numpy
from theano import function

class StateComputer(object):
    """Convenient interface to theano function for computing states/cells
    of a trained SequenceGenerator model.

    Expects a Model instance as argument. This model must also be created
    from a SequenceGenerator.cost application. Furthermore, expects a dict
    that maps from characters to indices.
    Extracts the model's inputs and auxiliary variables into attributes
    and creates theano function from inputs to auxiliary vars.

    Finally, provides a method that wraps the output of the theano function in
    a dict keyed by auxiliary variable labels.
    """

    def __init__(self, cost_model, map_char_to_ind):
        raw_state_vars = filter(self._relevant, cost_model.auxiliary_variables)
        self.state_variables = sorted(raw_state_vars, key=lambda var: var.name)
        self.state_var_names = [var.name for var in self.state_variables]
        self.inputs = sorted(cost_model.inputs, key=lambda var: var.name)
        self.func = function(self.inputs, self.state_variables)
        self.map_char_to_ind = map_char_to_ind

    def _relevant(self, aux_var):
        not_final_value = "final_value" not in aux_var.name
        cell_or_state = "states" in aux_var.name or "cells" in aux_var.name
        return cell_or_state and not_final_value

    def read_single_sequence(self, sequence):
        """Combines list of aux var values (output from theano func) with their
        corresponding labels.

        New and improved with (I think) more convenient interface.
        - as input provide a list (or something array-like, i.e. that can be
        converted to a numpy array) of either characters or their representing
        integers. If a list of characters is provided, the conversion is done
        in this method. NOTE that a string is more or less a list of characters
        for the purpose of this method =)
        - the theano function expects a 2D input where the first dimension is
        batch_size. This "fake" dimension is added below, so don't wrap the
        input sequence yourself.
        - because the cost was originally defined with a mask, the theano
        function needs one, as well. This mask is constructed below so you
        don't have to provide it yourself.
        """
        if all(isinstance(entry, str) for entry in sequence):
            indices = [self.map_char_to_ind[char] for char in sequence]
            converted_sequence = numpy.array([indices], dtype="int32")
        elif all(isinstance(entry, int) for entry in sequence):
            converted_sequence = numpy.array([sequence], dtype="int32")
        else:
            raise ValueError("Some or all sequence elements have invalid type "
                             "(should be str or int)!")
        mask = numpy.ones(converted_sequence.shape, dtype="int8")
        computed_aux_vars = self.func(converted_sequence, mask)
        flattened_aux_vars = map(drop_batch_dim, computed_aux_vars)
        return dict(zip(self.state_var_names, flattened_aux_vars))

def drop_batch_dim(array_with_single_dims):
    """When reading in one sentence at a time the batch dimension is superflous.

    Using numpy.squeeze we get rid of it. This relies on that dimension being "1".
    Moreover, `squeeze` will remove ALL dimensions that are equal to 1, so be careful
    what you pass to this function.
    """
    return numpy.squeeze(array_with_single_dims)

def mark_seq_len(seq):
    return numpy.arange(len(seq))

def mark_word_boundaries(seq):
    # define what's considered a word boundary. It's a set on purpose to permit
    # adding more character types as needed.
    wb = {
        " "
    }
    return numpy.array([1 if char in wb else 0 for char in seq])
<|endoftext|>


<commit_before>#!/usr/bin/env python

# author: Alp Sayin
# mail: alpsayin[at]gmail
# sources:
# http://www.movable-type.co.uk/scripts/latlong.html
# http://gis.stackexchange.com/questions/29239/calculate-bearing-between-two-decimal-gps-coordinates

import math
from math import sin, cos, acos, tan, atan2, sqrt, radians, degrees, asin, floor, log, pi

R = 6371 #km

def convertHMStoDecimal( hms):
	h = hms[0]
	m = hms[1]
	s = hms[2]
	if h < 0:
		sign = -1
	else:
		sign = 1
	dec = (h + (m/60.0) + (s/3600.0) ) * sign#/1000000.0;
	return round(dec, 6)

def convertDecimaltoHMS(dec):
	if dec < 0:
		sign = -1
	else:
		sign= 1

	h = floor(dec ) * sign
	m = floor(  ((dec) - floor(dec)) * 60)
	s = round( floor(((((dec) - floor(dec)) * 60) - floor(((dec) - floor(dec)) * 60)) * 100000) * 60/100000, 2)
	return (h, m, s)

class Gps(object):
	"""a simple gps class for holding lat and long and calculating distances and locations"""
	def __init__(self, lat=0.0, lon=0.0):
		super(Gps, self).__init__()
		self.lat = round(lat, 6)
		self.lon = round(lon, 6)

	def get_lattitude(self):
		return self.lat

	def get_longtitude(self):
		return self.lon

	def distanceTo(self, otherGps):
		'''result in meters'''
		deltaLatRad = radians(self.lat-otherGps.lat)
		deltaLonRad = radians(self.lon-otherGps.lon)
		lat1Rad = radians(self.lat)
		lat2Rad = radians(otherGps.lat)
		lon1Rad = radians(self.lon)
		lon2Rad = radians(otherGps.lon)

		# Spherical law of cosines
		d = acos( (sin(lat1Rad)*sin(lat2Rad)) + (cos(lat1Rad)*cos(lat2Rad)*cos(lon2Rad-lon1Rad))) * R;

		# Haversine formula
		# a = (sin(deltaLatRad/2) * sin(deltaLatRad/2)) + (sin(deltaLonRad/2) * sin(deltaLonRad/2) * cos(lat1Rad) * cos(lat2Rad))
		# c = 2 * atan2(sqrt(a), sqrt(1-a))
		# d = R * c
		return d*1000

	def bearingTo(self, otherGps):
		deltaLon = radians(otherGps.lon) - radians(self.lon)
		deltaLat = radians(otherGps.lat) - radians(self.lat)
		lat1 = radians(self.lat)
		lat2 = radians(otherGps.lat)
		# http://gis.stackexchange.com/questions/29239/calculate-bearing-between-two-decimal-gps-coordinates
		dPhi = log(tan(lat2/2.0+pi/4.0)/tan(lat1/2.0+pi/4.0))
		if abs(deltaLon) > pi:
			if deltaLon > 0.0:
				deltaLon = -(2.0 * pi - dLong)
			else:
				deltaLon = (2.0 * pi + dLong)

		bearing = (degrees(atan2(deltaLon, dPhi)) + 360.0) % 360.0
		return round(bearing, 6)

	def locationOf(self, bearing, distance):
		'''bearing in degrees, distance in meters'''
		distance_km = distance/1000.0
		bearing_r = radians(bearing)
		lat1 = radians(self.lat)
		lon1 = radians(self.lon)
		lat2 = asin( (sin(lat1)*cos(distance_km/R)) + (cos(lat1)*sin(distance_km/R)*cos(bearing_r)) )
		lon2 = lon1 + atan2( sin(bearing_r) * sin(distance_km/R) * cos(lat1), cos(distance_km/R) - (sin(lat1)*sin(lat2)) );
		return Gps(lat=degrees(lat2), lon=degrees(lon2))

	def __str__(self):
		lathms = convertDecimaltoHMS(self.lat)
		lonhms = convertDecimaltoHMS(self.lon)
		return '('+str(self.lat)+', '+str(self.lon)+') : '+str(lathms)+', '+ str(lonhms)

if __name__ == '__main__':
	coordHms1 = ( (39,52,4.35), (32,45,5.27))
	coordHms2 = ( (39,52,7.79), (32,45,11.68))
	print 'HMS 1 -> ' + str(coordHms1)
	print 'HMS 2 -> ' + str(coordHms2)
	coordDec1 = ( convertHMStoDecimal(coordHms1[0]), convertHMStoDecimal(coordHms1[1]))
	coordDec2 = ( convertHMStoDecimal(coordHms2[0]), convertHMStoDecimal(coordHms2[1]))
	print 'Dec 1 ->' + str(coordDec1)
	print 'Dec 2 ->' + str(coordDec2)
	backHms1 = ( convertDecimaltoHMS(coordDec1[0]), convertDecimaltoHMS(coordDec1[1]))
	backHms2 = ( convertDecimaltoHMS(coordDec2[0]), convertDecimaltoHMS(coordDec2[1]))
	print 'HMS 1 -> ' + str(backHms1)
	print 'HMS 2 -> ' + str(backHms2)
	loc1 = Gps( coordDec1[0], coordDec1[1] )
	loc2 = Gps( coordDec2[0], coordDec2[1] )
	distance = loc1.distanceTo(loc2)
	bearing1 = loc1.bearingTo(loc2)
	bearing2 = loc2.bearingTo(loc1)
	print 'distance: ' + str(distance)
	print 'bearing12: ' + str(bearing1)
	print 'bearing12: ' + str(convertDecimaltoHMS(bearing1))
	print 'bearing21: ' + str(bearing2)
	print 'bearing21: ' + str(convertDecimaltoHMS(bearing2))
	loc2fromDistance = loc1.locationOf(bearing1, distance)
	loc1fromDistance = loc2.locationOf(bearing2, distance)
	print loc1
	print loc1fromDistance
	print loc2
	print loc2fromDistance<commit_msg>add unicode function<commit_after>#!/usr/bin/env python

# author: Alp Sayin
# mail: alpsayin[at]gmail
# sources:
# http://www.movable-type.co.uk/scripts/latlong.html
# http://gis.stackexchange.com/questions/29239/calculate-bearing-between-two-decimal-gps-coordinates

import math
from math import sin, cos, acos, tan, atan2, sqrt, radians, degrees, asin, floor, log, pi

R = 6371 #km

def convertHMStoDecimal( hms):
	h = hms[0]
	m = hms[1]
	s = hms[2]
	if h < 0:
		sign = -1
	else:
		sign = 1
	dec = (h + (m/60.0) + (s/3600.0) ) * sign#/1000000.0;
	return round(dec, 6)

def convertDecimaltoHMS(dec):
	if dec < 0:
		sign = -1
	else:
		sign= 1

	h = floor(dec ) * sign
	m = floor(  ((dec) - floor(dec)) * 60)
	s = round( floor(((((dec) - floor(dec)) * 60) - floor(((dec) - floor(dec)) * 60)) * 100000) * 60/100000, 2)
	return (h, m, s)

class Gps(object):
	"""a simple gps class for holding lat and long and calculating distances and locations"""
	def __init__(self, lat=0.0, lon=0.0):
		super(Gps, self).__init__()
		self.lat = round(lat, 6)
		self.lon = round(lon, 6)

	def get_lattitude(self):
		return self.lat

	def get_longtitude(self):
		return self.lon

	def distanceTo(self, otherGps):
		'''result in meters'''
		deltaLatRad = radians(self.lat-otherGps.lat)
		deltaLonRad = radians(self.lon-otherGps.lon)
		lat1Rad = radians(self.lat)
		lat2Rad = radians(otherGps.lat)
		lon1Rad = radians(self.lon)
		lon2Rad = radians(otherGps.lon)

		# Spherical law of cosines
		d = acos( (sin(lat1Rad)*sin(lat2Rad)) + (cos(lat1Rad)*cos(lat2Rad)*cos(lon2Rad-lon1Rad))) * R;

		# Haversine formula
		# a = (sin(deltaLatRad/2) * sin(deltaLatRad/2)) + (sin(deltaLonRad/2) * sin(deltaLonRad/2) * cos(lat1Rad) * cos(lat2Rad))
		# c = 2 * atan2(sqrt(a), sqrt(1-a))
		# d = R * c
		return d*1000

	def bearingTo(self, otherGps):
		deltaLon = radians(otherGps.lon) - radians(self.lon)
		deltaLat = radians(otherGps.lat) - radians(self.lat)
		lat1 = radians(self.lat)
		lat2 = radians(otherGps.lat)
		# http://gis.stackexchange.com/questions/29239/calculate-bearing-between-two-decimal-gps-coordinates
		dPhi = log(tan(lat2/2.0+pi/4.0)/tan(lat1/2.0+pi/4.0))
		if abs(deltaLon) > pi:
			if deltaLon > 0.0:
				deltaLon = -(2.0 * pi - dLong)
			else:
				deltaLon = (2.0 * pi + dLong)

		bearing = (degrees(atan2(deltaLon, dPhi)) + 360.0) % 360.0
		return round(bearing, 6)

	def locationOf(self, bearing, distance):
		'''bearing in degrees, distance in meters'''
		distance_km = distance/1000.0
		bearing_r = radians(bearing)
		lat1 = radians(self.lat)
		lon1 = radians(self.lon)
		lat2 = asin( (sin(lat1)*cos(distance_km/R)) + (cos(lat1)*sin(distance_km/R)*cos(bearing_r)) )
		lon2 = lon1 + atan2( sin(bearing_r) * sin(distance_km/R) * cos(lat1), cos(distance_km/R) - (sin(lat1)*sin(lat2)) );
		return Gps(lat=degrees(lat2), lon=degrees(lon2))

	def __unicode__(self):
		return self.__str__()

	def __str__(self):
		lathms = convertDecimaltoHMS(self.lat)
		lonhms = convertDecimaltoHMS(self.lon)
		return '('+str(self.lat)+', '+str(self.lon)+') : '+str(lathms)+', '+ str(lonhms)

if __name__ == '__main__':
	coordHms1 = ( (39,52,4.35), (32,45,5.27))
	coordHms2 = ( (39,52,7.79), (32,45,11.68))
	print 'HMS 1 -> ' + str(coordHms1)
	print 'HMS 2 -> ' + str(coordHms2)
	coordDec1 = ( convertHMStoDecimal(coordHms1[0]), convertHMStoDecimal(coordHms1[1]))
	coordDec2 = ( convertHMStoDecimal(coordHms2[0]), convertHMStoDecimal(coordHms2[1]))
	print 'Dec 1 ->' + str(coordDec1)
	print 'Dec 2 ->' + str(coordDec2)
	backHms1 = ( convertDecimaltoHMS(coordDec1[0]), convertDecimaltoHMS(coordDec1[1]))
	backHms2 = ( convertDecimaltoHMS(coordDec2[0]), convertDecimaltoHMS(coordDec2[1]))
	print 'HMS 1 -> ' + str(backHms1)
	print 'HMS 2 -> ' + str(backHms2)
	loc1 = Gps( coordDec1[0], coordDec1[1] )
	loc2 = Gps( coordDec2[0], coordDec2[1] )
	distance = loc1.distanceTo(loc2)
	bearing1 = loc1.bearingTo(loc2)
	bearing2 = loc2.bearingTo(loc1)
	print 'distance: ' + str(distance)
	print 'bearing12: ' + str(bearing1)
	print 'bearing12: ' + str(convertDecimaltoHMS(bearing1))
	print 'bearing21: ' + str(bearing2)
	print 'bearing21: ' + str(convertDecimaltoHMS(bearing2))
	loc2fromDistance = loc1.locationOf(bearing1, distance)
	loc1fromDistance = loc2.locationOf(bearing2, distance)
	print loc1
	print loc1fromDistance
	print loc2
	print loc2fromDistance<|endoftext|>


<commit_before>#uses win32gui to controler recalcitrant API-less datasources >_<
#XXX broken due to inability to focus window

from time import sleep

import win32gui as wig
import win32ui as wui
import win32con as wic
from win32api import SetCursorPos, mouse_event

#empirically determined offsets from the top left corner

#protocols
#y offset 140

def make_offsets():
    """ offsets measured from the LEFT & TOP edges,
        aka the (x,y) of the top left corner
        this is actually a really obfusticated way to do this
        but if something changes it could be useful """
    PROT_Y_OFFSET=140
    #x values
    BUTTON_WIDTH=28
    G0_START=68
    G1_START=305
    G2_START=400
    G3_START=495
    #number of buttons per group
    G0_COUNT=8
    G1_COUNT=3
    G2_COUNT=3
    G3_COUNT=3

    g0={ 1+n:( G0_START + BUTTON_WIDTH * n , PROT_Y_OFFSET) for n in range(G0_COUNT) }
    g1={ 1+n+G0_COUNT:( G1_START + BUTTON_WIDTH * n , PROT_Y_OFFSET) for n in range(G1_COUNT) }

    g2={ 1+n+G0_COUNT+G1_COUNT:( G2_START + BUTTON_WIDTH * n , PROT_Y_OFFSET) for n in range(G2_COUNT) }
    g3={ 1+n+G0_COUNT+G1_COUNT+G2_COUNT:( G3_START + BUTTON_WIDTH * n , PROT_Y_OFFSET) for n in range(G3_COUNT) }

    offsetDict={ 'record':(350,65) }
    offsetDict.update(g0)
    offsetDict.update(g1)
    offsetDict.update(g2)
    offsetDict.update(g3)
    return offsetDict

PCLAMP_BUTTON_OFFSETS = make_offsets()

def getWindows():
    """ Get a list of all the windows. List of tuples (int, string)
    the string is the window name. """
    toplist=[]
    winlist=[]

    def enum_callback(hwnd, results):
        winlist.append((hwnd,wig.GetWindowText(hwnd)))

    wig.EnumWindows(enum_callback, toplist)

    return winlist

def getClampexWinName():
    for i,name in getWindows():
        if name.count('Clampex'):
            return name

def getWindowFromName(name):
    print(name)
    return wui.FindWindow(None,name)

def getLeftBottom(window):
    return window.GetWindowRect()[0::3] #left,top,right,bottom

def getLeftTop(window):
    return window.GetWindowRect()[:2]

def getClampexWinLeftTop():
    name=getClampexWinName()
    window=getWindowFromName(name)
    return getLeftTop(window)

def clickMouse(x,y,timeDown=.1): #FIXME need a way to change focus back to the original window!
    """click ye mouse"""
    mX,mY=wig.GetCursorPos() #save the position so we can return to it
    SetCursorPos((x,y))
    mouse_event(wic.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
    sleep(timeDown)
    mouse_event(wic.MOUSEEVENTF_LEFTUP,x,y,0,0)
    SetCursorPos((mX,mY))

def clickButton(WindowLeftTop,ButtonOffset):
    x=WindowLeftTop[0]+ButtonOffset[0]
    y=WindowLeftTop[1]+ButtonOffset[1]
    clickMouse(x,y,timeDown=.1)

def clickProtocol(protocolNumber):
    leftTop=getClampexWinLeftTop()
    offset=PCLAMP_BUTTON_OFFSETS[protocolNumber]
    clickButton(leftTop,offset)

def clickRecord():
    leftTop=getClampexWinLeftTop()
    offset=PCLAMP_BUTTON_OFFSETS['record']
    clickButton(leftTop,offset)

def main():
    print(PCLAMP_BUTTON_OFFSETS)
    left,top = getClampexWinLeftTop()
    for x,y in PCLAMP_BUTTON_OFFSETS.values():
        x=x+left
        y=y+top
        clickMouse(x,y,1)

if __name__ == '__main__':
    main()

<commit_msg>removed the print statement for window name, no idea what caused the problem :x<commit_after>#uses win32gui to controler recalcitrant API-less datasources >_<
#XXX broken due to inability to focus window

from time import sleep

import win32gui as wig
import win32ui as wui
import win32con as wic
from win32api import SetCursorPos, mouse_event

#empirically determined offsets from the top left corner

#protocols
#y offset 140

def make_offsets():
    """ offsets measured from the LEFT & TOP edges,
        aka the (x,y) of the top left corner
        this is actually a really obfusticated way to do this
        but if something changes it could be useful """
    PROT_Y_OFFSET=140
    #x values
    BUTTON_WIDTH=28
    G0_START=68
    G1_START=305
    G2_START=400
    G3_START=495
    #number of buttons per group
    G0_COUNT=8
    G1_COUNT=3
    G2_COUNT=3
    G3_COUNT=3

    g0={ 1+n:( G0_START + BUTTON_WIDTH * n , PROT_Y_OFFSET) for n in range(G0_COUNT) }
    g1={ 1+n+G0_COUNT:( G1_START + BUTTON_WIDTH * n , PROT_Y_OFFSET) for n in range(G1_COUNT) }

    g2={ 1+n+G0_COUNT+G1_COUNT:( G2_START + BUTTON_WIDTH * n , PROT_Y_OFFSET) for n in range(G2_COUNT) }
    g3={ 1+n+G0_COUNT+G1_COUNT+G2_COUNT:( G3_START + BUTTON_WIDTH * n , PROT_Y_OFFSET) for n in range(G3_COUNT) }

    offsetDict={ 'record':(350,65) }
    offsetDict.update(g0)
    offsetDict.update(g1)
    offsetDict.update(g2)
    offsetDict.update(g3)
    return offsetDict

PCLAMP_BUTTON_OFFSETS = make_offsets()

def getWindows():
    """ Get a list of all the windows. List of tuples (int, string)
    the string is the window name. """
    toplist=[]
    winlist=[]

    def enum_callback(hwnd, results):
        winlist.append((hwnd,wig.GetWindowText(hwnd)))

    wig.EnumWindows(enum_callback, toplist)

    return winlist

def getClampexWinName():
    for i,name in getWindows():
        if name.count('Clampex'):
            return name

def getWindowFromName(name):
    return wui.FindWindow(None,name)

def getLeftBottom(window):
    return window.GetWindowRect()[0::3] #left,top,right,bottom

def getLeftTop(window):
    return window.GetWindowRect()[:2]

def getClampexWinLeftTop():
    name=getClampexWinName()
    window=getWindowFromName(name)
    return getLeftTop(window)

def clickMouse(x,y,timeDown=.1): #FIXME need a way to change focus back to the original window!
    """click ye mouse"""
    mX,mY=wig.GetCursorPos() #save the position so we can return to it
    SetCursorPos((x,y))
    mouse_event(wic.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
    sleep(timeDown)
    mouse_event(wic.MOUSEEVENTF_LEFTUP,x,y,0,0)
    SetCursorPos((mX,mY))

def clickButton(WindowLeftTop,ButtonOffset):
    x=WindowLeftTop[0]+ButtonOffset[0]
    y=WindowLeftTop[1]+ButtonOffset[1]
    clickMouse(x,y,timeDown=.1)

def clickProtocol(protocolNumber):
    leftTop=getClampexWinLeftTop()
    offset=PCLAMP_BUTTON_OFFSETS[protocolNumber]
    clickButton(leftTop,offset)

def clickRecord():
    leftTop=getClampexWinLeftTop()
    offset=PCLAMP_BUTTON_OFFSETS['record']
    clickButton(leftTop,offset)

def main():
    print(PCLAMP_BUTTON_OFFSETS)
    left,top = getClampexWinLeftTop()
    for x,y in PCLAMP_BUTTON_OFFSETS.values():
        x=x+left
        y=y+top
        clickMouse(x,y,1)

if __name__ == '__main__':
    main()

<|endoftext|>


<commit_before># -*- coding:utf-8 -*-
import sys
import gtk
import gobject
import pango

sys.path.append("python-h8simulator")
from simpleh8simulator import *

class H8SimGUI :
  def __init__(self) :
    self.builder = gtk.Builder()
    self.builder.add_from_file("gui.glade")

    self.window = self.builder.get_object("window1")
    self.filechooserdialog = self.builder.get_object("filechooserdialog1")
    self.treeview = self.builder.get_object("treeview1")

    self.menu_open_item = self.builder.get_object("imagemenuitem2")
    self.menu_exit_item = self.builder.get_object("imagemenuitem5")

    self.dis_assembly = self.builder.get_object("textview1")
    self.run_button = self.builder.get_object("button1")
    self.step_button = self.builder.get_object("button2")
    self.reset_button = self.builder.get_object("button3")

    self.fdialog_ok_button = self.builder.get_object("button4")
    self.fdialog_cancel_button = self.builder.get_object("button5")

    self.fdialog_ok_button.connect("clicked", self.hideFileChooserDialog)
    self.menu_open_item.connect("button-release-event", self.showFileChooserDialog)
    self.menu_exit_item.connect("button-release-event", self.exit)
    self.run_button.connect("clicked", self.sim_run)
    self.step_button.connect("clicked", self.sim_step)
    self.reset_button.connect("clicked", self.sim_reset)

    self.treeview.modify_font(pango.FontDescription('Courier'))
    self.treeview.append_column(gtk.TreeViewColumn('', gtk.CellRendererText(), text=0))
    self.treeview.append_column(gtk.TreeViewColumn('メモリ番地', gtk.CellRendererText(), text=1))
    self.treeview.append_column(gtk.TreeViewColumn('アセンブリ', gtk.CellRendererText(), text=2))
    self.treeview.append_column(gtk.TreeViewColumn('備考', gtk.CellRendererText(), text=3))
    self.treeview.set_model(gtk.ListStore(str, str, str, str))

    self.treeview.get_model().append(("","","", "「メニュー->ファイル->開く」からmotファイルを選択してください"))

    self.sim = SimpleH8simulator()
    self.disAssembly = None
    self.running = False

    self.window.show()

  def initView(self) :
    listiter = self.treeview.get_model().get_iter_first()
    while listiter :
      self.treeview.get_model().remove(listiter)
      listiter = self.treeview.get_model().get_iter_first()
    for k in sorted(self.disAssembly.keys()) :
      self.treeview.get_model().append(("",("%6X"%k) ,self.disAssembly[k], ""))

  def drawView(self) :
    listiter = self.treeview.get_model().get_iter_first()
    while listiter :
      if int(self.treeview.get_model().get_value(listiter, 1), 16) == self.sim.getProgramCounter() :
        self.treeview.get_model().set_value(listiter, 0, 'ER7=')
      else :
        self.treeview.get_model().set_value(listiter, 0, '')
      listiter = self.treeview.get_model().iter_next(listiter)

  def runStep(self) :
    self.sim.runStep()
    self.drawView()
    if self.running :
      gobject.timeout_add(100, self.runStep)

  def showFileChooserDialog(self, widget, event) :
    self.filechooserdialog.show()

  def hideFileChooserDialog(self, widget) :
    self.sim.load(self.filechooserdialog.get_file().get_path())
    self.disAssembly = self.sim.getDisAssembly()
    self.sim.reset()
    self.initView()
    self.filechooserdialog.hide()

  def sim_run(self, widget) :
    self.running = not self.running
    print self.running
    if self.running :
      gobject.timeout_add(100, self.runStep)

  def sim_step(self, widget) :
    self.sim.runStep()
    self.drawView()

  def sim_reset(self, widget) :
    self.sim.reset()
    self.drawView()

  def main(self) :
    gtk.main()

  def exit(self, windows, event) :
    sys.exit(0)

if __name__ == "__main__" :
  app = H8SimGUI()
  app.main()

<commit_msg>change ListModel to TreeModel<commit_after># -*- coding:utf-8 -*-
import sys
import gtk
import gobject
import pango

sys.path.append("python-h8simulator")
from simpleh8simulator import *

class H8SimGUI :
  def __init__(self) :
    self.builder = gtk.Builder()
    self.builder.add_from_file("gui.glade")

    self.window = self.builder.get_object("window1")
    self.filechooserdialog = self.builder.get_object("filechooserdialog1")
    self.treeview = self.builder.get_object("treeview1")

    self.menu_open_item = self.builder.get_object("imagemenuitem2")
    self.menu_exit_item = self.builder.get_object("imagemenuitem5")

    self.dis_assembly = self.builder.get_object("textview1")
    self.run_button = self.builder.get_object("button1")
    self.step_button = self.builder.get_object("button2")
    self.reset_button = self.builder.get_object("button3")

    self.fdialog_ok_button = self.builder.get_object("button4")
    self.fdialog_cancel_button = self.builder.get_object("button5")

    self.fdialog_ok_button.connect("clicked", self.hideFileChooserDialog)
    self.menu_open_item.connect("button-release-event", self.showFileChooserDialog)
    self.menu_exit_item.connect("button-release-event", self.exit)
    self.run_button.connect("clicked", self.sim_run)
    self.step_button.connect("clicked", self.sim_step)
    self.reset_button.connect("clicked", self.sim_reset)

    self.treeview.modify_font(pango.FontDescription('Courier'))
    self.treeview.append_column(gtk.TreeViewColumn('', gtk.CellRendererText(), text=0))
    self.treeview.append_column(gtk.TreeViewColumn('メモリ番地', gtk.CellRendererText(), text=1))
    self.treeview.append_column(gtk.TreeViewColumn('アセンブリ', gtk.CellRendererText(), text=2))
    self.treeview.append_column(gtk.TreeViewColumn('備考', gtk.CellRendererText(), text=3))
    self.treeview.set_model(gtk.TreeStore(str, str, str, str))

    self.treeview.get_model().append(None, ("","","", "「メニュー->ファイル->開く」からmotファイルを選択してください"))

    self.sim = SimpleH8simulator()
    self.disAssembly = None
    self.running = False

    self.window.show()

  def initView(self) :
    listiter = self.treeview.get_model().get_iter_first()
    while listiter :
      self.treeview.get_model().remove(listiter)
      listiter = self.treeview.get_model().get_iter_first()
    for k in sorted(self.disAssembly.keys()) :
      self.treeview.get_model().append(None, ("",("%6X"%k) ,self.disAssembly[k], ""))

  def drawView(self) :
    listiter = self.treeview.get_model().get_iter_first()
    while listiter :
      if int(self.treeview.get_model().get_value(listiter, 1), 16) == self.sim.getProgramCounter() :
        self.treeview.get_model().set_value(listiter, 0, 'ER7=')
      else :
        self.treeview.get_model().set_value(listiter, 0, '')
      listiter = self.treeview.get_model().iter_next(listiter)

  def runStep(self) :
    self.sim.runStep()
    self.drawView()
    if self.running :
      gobject.timeout_add(100, self.runStep)

  def showFileChooserDialog(self, widget, event) :
    self.filechooserdialog.show()

  def hideFileChooserDialog(self, widget) :
    self.sim.load(self.filechooserdialog.get_file().get_path())
    self.disAssembly = self.sim.getDisAssembly()
    self.sim.reset()
    self.initView()
    self.filechooserdialog.hide()

  def sim_run(self, widget) :
    self.running = not self.running
    print self.running
    if self.running :
      gobject.timeout_add(100, self.runStep)

  def sim_step(self, widget) :
    self.sim.runStep()
    self.drawView()

  def sim_reset(self, widget) :
    self.sim.reset()
    self.drawView()

  def main(self) :
    gtk.main()

  def exit(self, windows, event) :
    sys.exit(0)

if __name__ == "__main__" :
  app = H8SimGUI()
  app.main()

<|endoftext|>


<commit_before>import math
import numpy as np

import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget, QPushButton, QLabel
from PyQt5.QtGui import QIcon

# There are three classes defined in this file:
#   App:         the main window of the application
#   plotimage:   a Canvas to draw the input figure
#   PlotCanvas:  a Canvas to draw the activation

class App(QMainWindow):

    def __init__(self, network=None, data=None):
        super().__init__()

        # prepare matplotlib for interactive plotting on the screen
        plt.ion()

        self.network = network
        self.data = data

        self.left = 10
        self.top = 10
        self.title = 'Activations'
        self.width = 1800
        self.height = 900
        layers = self.network.get_layer_list()
        self.layer_label = layers[0]
        self.sample_index=0
        self.initUI()
        self.update(input=True)

    def initUI(self):
        '''Initialize the graphical components of this user interface.
        '''

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        # a column of buttons to select the network layer
        self.old_sender = None
        for i,name in enumerate(self.network.get_layer_list()):
            btn = QPushButton(name, self)
            btn.resize(btn.sizeHint())
            btn.move(1500, 70+30*i)
            btn.clicked.connect(self.layerbuttonClicked)
            # FIXME[hack]: we need a better concept to access buttons!
            if self.layer_label == name:
                btn.setStyleSheet("background-color: red")
                self.old_sender = btn

        # the "next" button: used to load the next image
        btnnext = QPushButton('next', self)
        btnnext.resize(btn.sizeHint())
        btnnext.move(1500, 120+100*7)
        btnnext.clicked.connect(self.nextsamplebuttonclickked)

        btnprev = QPushButton('prev', self)
        btnprev.resize(btn.sizeHint())
        btnprev.move(1400, 120+100*7)
        btnprev.clicked.connect(self.prevsamplebuttonclickked)

        # a small textfield to display the name of the current image
        self.img_counter = QLabel("0", self)
        self.img_counter.move(1500, 80+100*7)

        # canvas_input: a canvas to display the input image
        self.canvas_input = MyImage(self, width=4, height=4)
        self.canvas_input.move(900,0)
        self.canvas_input.resize(300,300)
        # canvas_activation: a canvas to display a layer activation
        self.canvas_activation = PlotCanvas(self, width=9, height=9)
        self.canvas_activation.move(0,0)

        # canvas_input2: a canvas to display the input image
        # (mayb be more efficient - check!)
        self.canvas_input2 = MyImage(self)
        self.canvas_input2.move(900,400)
        self.canvas_input2.resize(300,300)

        # info_box: display input and layer info
        self.info_box = InfoBox(self)
        self.info_box.move(900,700)
        self.info_box.resize(300,200)

        self.show()

    def nextsamplebuttonclickked(self):
        '''Callback for clicking the "next" sample button.
        '''
        self.sample_index = (self.sample_index + 1) % len(self.data)
        print("nextsamplebuttonclickked: {}".format(self.sample_index))
        self.update(input=True)

    def prevsamplebuttonclickked(self):
        '''Callback for clicking the "prev" sample button.
        '''
        self.sample_index = (self.sample_index - 1) % len(self.data)
        print("prevsamplebuttonclickked: {}".format(self.sample_index))
        self.update(input=True)

    def layerbuttonClicked(self, sample_index):
        '''Callback for clicking one of the layer buttons.
        '''
        sender = self.sender()
        self.layer_label = sender.text()
        print("layerbuttonClicked: {}".format(self.layer_label))
        self.update(activation=True)

        # FIXME[hack]: we need a better concept to access buttons!
        sender.setStyleSheet("background-color: red")
        if self.old_sender:
            self.old_sender.setStyleSheet("")
        self.old_sender = sender

    def update(self, input=False, activation=None):
        '''Update the interface. This method should be called whenever
        the state of the application was changed.
        '''
        print("update: {} ({}) ".format(self.layer_label,self.sample_index))

        if input:
            self.canvas_input.myplot(self.data[self.sample_index,:,:,0],'gray')
            self.canvas_input2.myplot(np.asarray(self.network.get_relevance(self.network.get_activations_list(self.data[self.sample_index,:,:,0]),self.network.model.predict(self.data[self.sample_index:self.sample_index+1,:,:,0:1])))[0][:,:,0],'coolwarm')
            self.info_box.showInputInfo("{}/{}".format(self.sample_index,len(self.data)), self.data.shape[1:3])
            self.img_counter.setText("{}/{}".format(self.sample_index,len(self.data)))
            if activation is None: activation = True

        if activation:
            activations = self.network.get_activations(self.layer_label,
                                                       self.data[self.sample_index:self.sample_index+1,:,:,0:1])
            self.canvas_activation.plotactivat(activations)
            self.info_box.showLayerInfo(activations.shape,
                                        self.network.get_layer_info(self.layer_label))

class MyImage(FigureCanvas):
    '''A simple class to display an image, using a MatPlotLib figure.
    '''

    def __init__(self, parent=None, width=9, height=9, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        self.axes.axis('off')

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        self.draw()

    def myplot(self, image,map):
        '''Plot the given image.
        '''
        self.axes.imshow(image,cmap=map)
        self.draw()

class PlotCanvas(FigureCanvas):
    '''A special kind of matplotlib backend that is used to plot the
    activation.

    '''

    def __init__(self, parent=None, width=9, height=9, dpi=100):

        fig = Figure(figsize=(width, height), dpi=dpi)

        self.axes = fig.add_subplot(111)
        self.axes.axis('off')

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        self.draw()

    def plotactivat(self, intermediate_output):
        '''Plot the activation patterns for a complete layer.
        '''

        print("plotactivat: intermediate_output.shape = {}".format(intermediate_output.shape))
        fully_connected = (len(intermediate_output.shape)==2)

        if fully_connected:
            intermediate_output = intermediate_output.reshape(1,1,1,intermediate_output.shape[1])
        # the axis of intermediate_output are:
        # (batch_size, width, height, output_channels)

    #    vm = np.max(intermediate_output) if fully_connected else None

        # number of plots: plot all output channels
        nbofplots = intermediate_output.shape[3]

        # image size: filter size (or a single pixel per neuron)
        imagesize = intermediate_output.shape[1]

        # number of columns and rows (arrange as square)
        ncolumns = nraws = math.ceil(np.sqrt(nbofplots))

        # the pixel map to be shown
        ishow = np.ones([(imagesize+1)*ncolumns,(1+imagesize)*ncolumns])*2

        intermediate_output = np.swapaxes(intermediate_output,0,3)
        # the axis of intermediate_output are:
        # (output_channels, width, height, batch_size)

        print("plotactivat: columns = {}, plots = {}".format(ncolumns,nbofplots))
        for i in range(ncolumns-(ncolumns*ncolumns-nbofplots)//ncolumns):

            ishow[i*(imagesize+1):(i+1)*(imagesize+1),0:(imagesize+1)*(nbofplots-i*ncolumns)]=np.hstack(np.lib.pad(intermediate_output[i*ncolumns:(i+1)*ncolumns,:,:,0],[(0,0),(0,1),(0,1)],'constant', constant_values=2))

        # FIXME: no negative values?
        self.axes.imshow(ishow,vmin=0,cmap='gray')
        self.draw()

from PyQt5.QtGui import QImage, QPixmap

class MyImage2(QLabel):
    '''An experimental class to display images using the QPixmap
    class.  This may be more efficient than using matplotlib for
    displaying images.
    '''

    def __init__(self, parent):
        super().__init__(parent)
        self.setScaledContents(True)
        # an alternative may be to call
        #     pixmap.scaled(self.size(), Qt.KeepAspectRatio)
        # in the myplot method.

    def myplot(self, image):
        '''Display the given image. Image is supposed to be a numpy array.
        '''

        print("myplot: {} ({}) {}-{}".format(image.shape,image.dtype,image.min(),image.max()))

        # To construct a 8-bit monochrome QImage, we need a uint8
        # numpy array
        if image.dtype != np.uint8:
            image = (image*255).astype(np.uint8)

        qtimage = QImage(image, image.shape[1], image.shape[0],
                         QImage.Format_Grayscale8)
        pixmap = QPixmap(qtimage)
        self.setPixmap(pixmap)

class InfoBox(QLabel):

    def __init__(self, parent):
        super().__init__(parent)
        self.layer_text = "Layer info:
\n"
        self.input_text = "Input image:
\n"

    def showLayerInfo(self, shape, info):
        self.layer_text = "Layer info: {}
\n".format(info['name'])
        self.layer_text += ("Fully connected" if len(shape) == 2 else "Convolutional") + "
\n"
        self.layer_text += "Shape: {}
\n".format(shape)
        self.showInfo()

    def showInputInfo(self, name, shape):
        self.input_text = "Input image:
\n"
        self.input_text += "Name: {}
\n".format(name)
        self.input_text += "Input shape: {}
\n".format(shape)
        self.showInfo()

    def showInfo(self):
        self.setText(self.input_text + "
\n
\n" +
                     self.layer_text)
<commit_msg>Remove unused file<commit_after><|endoftext|>