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

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

"""
Verify correct use of the live 'as' assembler.
"""

import string
import sys

import TestSCons

_python_ = TestSCons._python_
_exe   = TestSCons._exe

test = TestSCons.TestSCons()

as = test.detect('AS', 'as')

if not as:
    test.skip_test("as not found; skipping test\n")

x86 = (sys.platform == 'win32' or string.find(sys.platform, 'linux') != -1)

if not x86:
    test.skip_test("skipping as test on non-x86 platform '%s'\n" % sys.platform)

test.write("wrapper.py", """\
import os
import string
import sys
open('%s', 'wb').write("wrapper.py: %%s\\n" %% sys.argv[-1])
cmd = string.join(sys.argv[1:])
os.system(cmd)
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))

test.write('SConstruct', """\
aaa = Environment()
bbb = aaa.Clone(AS = r'%(_python_)s wrapper.py ' + WhereIs('as'))
ccc = aaa.Clone(CPPPATH=['.'])
aaa.Program(target = 'aaa', source = ['aaa.s', 'aaa_main.c'])
bbb.Program(target = 'bbb', source = ['bbb.s', 'bbb_main.c'])
ccc.Program(target = 'ccc', source = ['ccc.S', 'ccc_main.c'])
""" % locals())

test.write('aaa.s',
"""        .file   "aaa.s"
.data
.align 4
.globl name
name:
        .ascii	"aaa.s"
        .byte	0
""")

test.write('bbb.s', """\
.file   "bbb.s"
.data
.align 4
.globl name
name:
        .ascii	"bbb.s"
        .byte	0
""")

test.write('ccc.h', """\
#define STRING  "ccc.S"
""")

test.write('ccc.S', """\
#include <ccc.h>
.file   STRING
.data
.align 4
.globl name
name:
        .ascii	STRING
        .byte	0
""")

test.write('aaa_main.c', r"""
#include <stdlib.h>
#include <stdio.h>

extern char name[];

int
main(int argc, char *argv[])
{
        argv[argc++] = "--";
        printf("aaa_main.c %s\n", name);
        exit (0);
}
""")

test.write('bbb_main.c', r"""
#include <stdlib.h>
#include <stdio.h>

extern char name[];

int
main(int argc, char *argv[])
{
        argv[argc++] = "--";
        printf("bbb_main.c %s\n", name);
        exit (0);
}
""")

test.write('ccc_main.c', r"""
#include <stdlib.h>
#include <stdio.h>

extern char name[];

int
main(int argc, char *argv[])
{
        argv[argc++] = "--";
        printf("ccc_main.c %s\n", name);
        exit (0);
}
""")

test.write('ddd_main.c', r"""
extern char name[];

int
main(int argc, char *argv[])
{
        argv[argc++] = "--";
        printf("ddd_main.c %s\n", name);
        exit (0);
}
""")

test.run()

test.run(program = test.workpath('aaa'), stdout =  "aaa_main.c aaa.s\n")
test.run(program = test.workpath('bbb'), stdout =  "bbb_main.c bbb.s\n")
test.run(program = test.workpath('ccc'), stdout =  "ccc_main.c ccc.S\n")

test.must_match('wrapper.out', "wrapper.py: bbb.s\n")

test.write("ccc.h", """\
#define STRING  "ccc.S 2"
""")

test.run()
test.run(program = test.workpath('ccc'), stdout =  "ccc_main.c ccc.S 2\n")

test.unlink('wrapper.out')

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

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

"""
Verify correct use of the live 'as' assembler.
"""

import string
import sys

import TestSCons

_python_ = TestSCons._python_
_exe   = TestSCons._exe

test = TestSCons.TestSCons()

if not test.detect('AS', 'as'):
    test.skip_test("as not found; skipping test\n")

x86 = (sys.platform == 'win32' or string.find(sys.platform, 'linux') != -1)

if not x86:
    test.skip_test("skipping as test on non-x86 platform '%s'\n" % sys.platform)

test.write("wrapper.py", """\
import os
import string
import sys
open('%s', 'wb').write("wrapper.py: %%s\\n" %% sys.argv[-1])
cmd = string.join(sys.argv[1:])
os.system(cmd)
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))

test.write('SConstruct', """\
aaa = Environment()
bbb = aaa.Clone(AS = r'%(_python_)s wrapper.py ' + WhereIs('as'))
ccc = aaa.Clone(CPPPATH=['.'])
aaa.Program(target = 'aaa', source = ['aaa.s', 'aaa_main.c'])
bbb.Program(target = 'bbb', source = ['bbb.s', 'bbb_main.c'])
ccc.Program(target = 'ccc', source = ['ccc.S', 'ccc_main.c'])
""" % locals())

test.write('aaa.s',
"""        .file   "aaa.s"
.data
.align 4
.globl name
name:
        .ascii	"aaa.s"
        .byte	0
""")

test.write('bbb.s', """\
.file   "bbb.s"
.data
.align 4
.globl name
name:
        .ascii	"bbb.s"
        .byte	0
""")

test.write('ccc.h', """\
#define STRING  "ccc.S"
""")

test.write('ccc.S', """\
#include <ccc.h>
.file   STRING
.data
.align 4
.globl name
name:
        .ascii	STRING
        .byte	0
""")

test.write('aaa_main.c', r"""
#include <stdlib.h>
#include <stdio.h>

extern char name[];

int
main(int argc, char *argv[])
{
        argv[argc++] = "--";
        printf("aaa_main.c %s\n", name);
        exit (0);
}
""")

test.write('bbb_main.c', r"""
#include <stdlib.h>
#include <stdio.h>

extern char name[];

int
main(int argc, char *argv[])
{
        argv[argc++] = "--";
        printf("bbb_main.c %s\n", name);
        exit (0);
}
""")

test.write('ccc_main.c', r"""
#include <stdlib.h>
#include <stdio.h>

extern char name[];

int
main(int argc, char *argv[])
{
        argv[argc++] = "--";
        printf("ccc_main.c %s\n", name);
        exit (0);
}
""")

test.write('ddd_main.c', r"""
extern char name[];

int
main(int argc, char *argv[])
{
        argv[argc++] = "--";
        printf("ddd_main.c %s\n", name);
        exit (0);
}
""")

test.run()

test.run(program = test.workpath('aaa'), stdout =  "aaa_main.c aaa.s\n")
test.run(program = test.workpath('bbb'), stdout =  "bbb_main.c bbb.s\n")
test.run(program = test.workpath('ccc'), stdout =  "ccc_main.c ccc.S\n")

test.must_match('wrapper.out', "wrapper.py: bbb.s\n")

test.write("ccc.h", """\
#define STRING  "ccc.S 2"
""")

test.run()
test.run(program = test.workpath('ccc'), stdout =  "ccc_main.c ccc.S 2\n")

test.unlink('wrapper.out')

test.pass_test()
<|endoftext|>


<commit_before>from functools import partial
from kivy.properties import(
    DictProperty,
    ObjectProperty,
    OptionProperty,
    ListProperty,
    BooleanProperty,
    BoundedNumericProperty,
    NumericProperty
)
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.label import Label
from kivy.uix.slider import Slider
from kivy.uix.textinput import TextInput
from kivy.uix.modalview import ModalView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.screenmanager import Screen
from kivy.clock import Clock
from kivy.lang import Builder

class CalendarWidget(RecycleDataViewBehavior, Widget):
    turn = NumericProperty()
    key = ObjectProperty()
    """The key to set in the entity"""
    value = ObjectProperty(allownone=True)
    """The value you want to set the key to"""

    def _update_disabledness(self, *args, **kwargs):
        self.disabled = self.turn < self.parent.parent.entity.engine.turn

    def _trigger_update_disabledness(self, *args, **kwargs):
        Clock.unschedule(self._update_disabledness)
        Clock.schedule_once(self._update_disabledness)

    def _set_value(self):
        entity = self.parent.parent.entity
        entity = getattr(entity, 'stat', entity)
        entity[self.key] = self.value

    def on_value(self, *args):
        # do I want to do some validation at this point?
        # Maybe I should validate on the proxy objects and catch that in Calendar,
        # display an error message?
        if not self.parent:
            return
        calendar = self.parent.parent
        my_dict = calendar.idx[(self.turn, self.key)]
        entity = calendar.entity
        update_mode = calendar.update_mode
        if my_dict['value'] != self.value:
            my_dict['value'] = self.value
            if update_mode == 'batch':
                calendar.changed = True
            elif update_mode == 'present':
                if self.turn == entity.engine.turn:
                    self._set_value()
                else:
                    calendar.changed = True
            else:
                eng = entity.engine
                now = eng.turn
                if now == self.turn:
                    self._set_value()
                else:
                    eng.turn = self.turn
                    self._set_value()
                    eng.turn = now

    def on_parent(self, *args):
        if not self.parent:
            return
        self._trigger_update_disabledness()
        self.parent.parent.entity.engine.time.connect(self._trigger_update_disabledness)

class CalendarLabel(CalendarWidget, Label):

    def __init__(self, **kwargs):
        if 'text' not in kwargs or not kwargs['text']:
            kwargs['text'] = ''
        super().__init__(**kwargs)

class CalendarSlider(Slider, CalendarWidget):
    pass

class CalendarTextInput(CalendarWidget, TextInput):
    pass

class CalendarToggleButton(CalendarWidget, ToggleButton):
    def on_state(self, *args):
        self.value = self.state == 'down'

class CalendarOptionButton(CalendarWidget, Button):
    options = ListProperty()
    modalview = ObjectProperty()
    columns = BoundedNumericProperty(1, min=1)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._make_modalview()
        self._update_modalview()
        self.bind(columns=self._make_modalview)
        self.bind(options=self._update_modalview)
        self.bind(on_release=self.modalview.open)

    def _make_modalview(self, *args):
        if not self.modalview:
            self.modalview = ModalView()
        if self.modalview.children:
            container = self.modalview.children[0]
        else:
            container = GridLayout(cols=self.columns)
            self.modalview.add_widget(container)
        container.size = container.minimum_size
        self._update_modalview()

    def _update_modalview(self, *args):
        if not self.modalview:
            Clock.schedule_once(self.on_options, 0)
            return
        if not self.modalview.children:
            container = GridLayout(cols=self.columns)
            self.modalview.add_widget(container)
        else:
            container = self.modalview.children[0]
        for option in self.options:
            if type(option) is tuple:
                text, value = option
                container.add_widget(Button(
                    size_hint_y=None, height=30,
                    text=text, on_release=partial(self._set_value_and_close, text)))
            else:
                container.add_widget(Button(
                    text=str(option), on_release=partial(
                    self._set_value_and_close, str(option)),
                    size_hint_y=None, height=30))
        container.size = container.minimum_size

    def _set_value_and_close(self, val, *args):
        self.value = val
        self.modalview.dismiss()

class CalendarToggleButton(RecycleDataViewBehavior, Button):
    index = None

    def on_touch_up(self, touch):
        if super().on_touch_up(touch):
            return self.parent.select_with_touch(self.index, touch)

    def apply_selection(self, rv, index, is_selected):
        self.state = 'down' if is_selected else 'normal'

class CalendarMenuLayout(LayoutSelectionBehavior, RecycleBoxLayout):
    pass

class Calendar(RecycleView):
    _control2wid = {
        'slider': 'CalendarSlider',
        'togglebutton': 'CalendarToggleButton',
        'textinput': 'CalendarTextInput',
        'option': 'CalendarOptionButton'
    }
    cols = NumericProperty()
    entity = ObjectProperty()
    idx = DictProperty()
    changed = BooleanProperty(False)
    """Whether there are changes yet to be committed to the LiSE core"""
    update_mode = OptionProperty('batch', options=['batch', 'present', 'all'])
    """How to go about submitting changes to the LiSE core. Options:

    * ``'batch'``: don't submit changes automatically. You have to call
    ``get_track`` and apply the changes using the ``LiSE.handle`` method
    ``apply_choices``. This is the default.
    * ``'present'``: immediately apply changes that affect the current turn,
    possibly wiping out anything in the future -- so you still have to use
    ``get_track`` and ``apply_choices``. However, if you're using a calendar
    in the same interface as another control widget for the same stat,
    ``'present'`` will ensure that the two widgets always display the same value.
    * ``'all'``: apply every change immediately to the LiSE core. Should only be
    used when the LiSE core is in planning mode.

    """

    def on_data(self, *args):
        idx = self.idx
        for item in self.data:
            if 'key' in item and 'turn' in item:
                idx[(item['turn'], item['key'])] = item

    def get_track(self):
        """Get a dictionary that can be used to submit my changes to ``LiSE.Engine.apply_choices``

        If a data dictionary does not have the key 'turn', it will not be included in the track.
        You can use this to add labels and other non-input widgets to the calendar.

        """
        changes = []
        track = {'entity': self.entity, 'changes': changes}
        if not self.data:
            return track
        for datum in self.data:
            if 'turn' in datum:
                break
        else:
            # I don't know *why* the calendar has no actionable data in it but here u go
            return track
        last = self.entity.engine.turn
        accumulator = []
        for datum in self.data:
            if 'turn' not in datum:
                continue
            trn = datum['turn']
            if trn < last:
                continue
            if trn > last:
                if trn > last + 1:
                    changes.extend([[]] * (trn - last - 1))
                changes.append(accumulator)
                accumulator = []
                last = trn
            accumulator.append((datum['key'], datum['value']))
        changes.append(accumulator)
        return track

    def from_schedule(self, schedule, start_turn=None, headers=True, turn_labels=True, key=lambda x: str(x)):
        # It should be convenient to style the calendar using data from the core;
        # not sure what the API should be like
        control2wid = self._control2wid
        if start_turn is None:
            start_turn = self.entity.engine.turn
        curturn = start_turn
        endturn = curturn + len(next(iter(schedule.values())))
        data = []
        stats = sorted((stat for stat in schedule if not stat.startswith('_')), key=key)
        if headers:
            if turn_labels:
                data.append({'widget': 'Label', 'text': ''})
            for stat in stats:
                if stat.startswith('_'):
                    continue
                data.append({'widget': 'Label', 'text': str(stat)})
        cols = len(data)
        iters = {stat: iter(values) for (stat, values) in schedule.items()}
        for turn in range(curturn, endturn):
            if turn_labels:
                data.append({'widget': 'Label', 'text': str(turn)})
            if '_config' in iters:
                config = next(iters['_config'])
            else:
                config = None
            for stat in stats:
                datum = {'key': stat, 'value': next(iters[stat]), 'turn': turn}
                if config and stat in config and 'control' in config[stat]:
                    datum.update(config[stat])
                    datum['widget'] = control2wid.get(datum.pop('control', None), 'CalendarLabel')
                    if datum['widget'] == 'CalendarToggleButton':
                        if datum['value']:
                            datum['text'] = config[stat].get('true_text', 'True')
                            datum['state'] = 'down'
                        else:
                            datum['text'] = config[stat].get('false_text', 'False')
                            datum['state'] = 'normal'
                else:
                    datum['widget'] = 'CalendarLabel'
                data.append(datum)
        (self.cols, self.data, self.changed) = (cols, data, False)

Builder.load_string("""
<Calendar>:
    key_viewclass: 'widget'
    RecycleGridLayout:
        cols: root.cols
        size_hint_y: None
        default_size: None, dp(56)
        default_size_hint: 1, None
        height: self.minimum_height
        orientation: 'horizontal'
<CalendarLabel>:
    text: str(self.value) if self.value is not None else ''
<CalendarSlider>:
    padding: 25
    Label:
        center_x: root.center_x
        y: root.center_y
        text: str(root.value)
        size: self.texture_size
<CalendarOptionButton>:
    text: str(self.value)
""")

if __name__ == '__main__':
    from kivy.app import App
    class CalendarTestApp(App):
        def build(self):
            self.wid = Calendar()
            return self.wid

        def on_start(self):
            # it seems like the calendar blanks out its data sometime after initialization
            data = []
            for i in range(7):
                for j in range(3):
                    data.append({'widget': 'Button', 'text': f'row{i} col{j}'})
            self.wid.data = data

    CalendarTestApp().run()<commit_msg>Remove redundant CalendarToggleButton declaration, update text quicker<commit_after>from functools import partial
from kivy.properties import(
    DictProperty,
    ObjectProperty,
    OptionProperty,
    ListProperty,
    BooleanProperty,
    BoundedNumericProperty,
    NumericProperty,
    StringProperty
)
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.label import Label
from kivy.uix.slider import Slider
from kivy.uix.textinput import TextInput
from kivy.uix.modalview import ModalView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.screenmanager import Screen
from kivy.clock import Clock
from kivy.lang import Builder

class CalendarWidget(RecycleDataViewBehavior, Widget):
    turn = NumericProperty()
    key = ObjectProperty()
    """The key to set in the entity"""
    value = ObjectProperty(allownone=True)
    """The value you want to set the key to"""

    def _update_disabledness(self, *args, **kwargs):
        self.disabled = self.turn < self.parent.parent.entity.engine.turn

    def _trigger_update_disabledness(self, *args, **kwargs):
        Clock.unschedule(self._update_disabledness)
        Clock.schedule_once(self._update_disabledness)

    def _set_value(self):
        entity = self.parent.parent.entity
        entity = getattr(entity, 'stat', entity)
        entity[self.key] = self.value

    def on_value(self, *args):
        # do I want to do some validation at this point?
        # Maybe I should validate on the proxy objects and catch that in Calendar,
        # display an error message?
        if not self.parent:
            return
        calendar = self.parent.parent
        my_dict = calendar.idx[(self.turn, self.key)]
        entity = calendar.entity
        update_mode = calendar.update_mode
        if my_dict['value'] != self.value:
            my_dict['value'] = self.value
            if update_mode == 'batch':
                calendar.changed = True
            elif update_mode == 'present':
                if self.turn == entity.engine.turn:
                    self._set_value()
                else:
                    calendar.changed = True
            else:
                eng = entity.engine
                now = eng.turn
                if now == self.turn:
                    self._set_value()
                else:
                    eng.turn = self.turn
                    self._set_value()
                    eng.turn = now

    def on_parent(self, *args):
        if not self.parent:
            return
        self._trigger_update_disabledness()
        self.parent.parent.entity.engine.time.connect(self._trigger_update_disabledness)

class CalendarLabel(CalendarWidget, Label):

    def __init__(self, **kwargs):
        if 'text' not in kwargs or not kwargs['text']:
            kwargs['text'] = ''
        super().__init__(**kwargs)

class CalendarSlider(Slider, CalendarWidget):
    pass

class CalendarTextInput(CalendarWidget, TextInput):
    pass

class CalendarOptionButton(CalendarWidget, Button):
    options = ListProperty()
    modalview = ObjectProperty()
    columns = BoundedNumericProperty(1, min=1)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._make_modalview()
        self._update_modalview()
        self.bind(columns=self._make_modalview)
        self.bind(options=self._update_modalview)
        self.bind(on_release=self.modalview.open)

    def _make_modalview(self, *args):
        if not self.modalview:
            self.modalview = ModalView()
        if self.modalview.children:
            container = self.modalview.children[0]
        else:
            container = GridLayout(cols=self.columns)
            self.modalview.add_widget(container)
        container.size = container.minimum_size
        self._update_modalview()

    def _update_modalview(self, *args):
        if not self.modalview:
            Clock.schedule_once(self.on_options, 0)
            return
        if not self.modalview.children:
            container = GridLayout(cols=self.columns)
            self.modalview.add_widget(container)
        else:
            container = self.modalview.children[0]
        for option in self.options:
            if type(option) is tuple:
                text, value = option
                container.add_widget(Button(
                    size_hint_y=None, height=30,
                    text=text, on_release=partial(self._set_value_and_close, text)))
            else:
                container.add_widget(Button(
                    text=str(option), on_release=partial(
                    self._set_value_and_close, str(option)),
                    size_hint_y=None, height=30))
        container.size = container.minimum_size

    def _set_value_and_close(self, val, *args):
        self.value = val
        self.modalview.dismiss()

class CalendarToggleButton(CalendarWidget, ToggleButton):
    index = None
    true_text = StringProperty('True')
    false_text = StringProperty('False')

    def on_state(self, *args):
        self.value = self.state == 'down'
        self.text = self.true_text if self.value else self.false_text

class CalendarMenuLayout(LayoutSelectionBehavior, RecycleBoxLayout):
    pass

class Calendar(RecycleView):
    _control2wid = {
        'slider': 'CalendarSlider',
        'togglebutton': 'CalendarToggleButton',
        'textinput': 'CalendarTextInput',
        'option': 'CalendarOptionButton'
    }
    cols = NumericProperty()
    entity = ObjectProperty()
    idx = DictProperty()
    changed = BooleanProperty(False)
    """Whether there are changes yet to be committed to the LiSE core"""
    update_mode = OptionProperty('batch', options=['batch', 'present', 'all'])
    """How to go about submitting changes to the LiSE core. Options:

    * ``'batch'``: don't submit changes automatically. You have to call
    ``get_track`` and apply the changes using the ``LiSE.handle`` method
    ``apply_choices``. This is the default.
    * ``'present'``: immediately apply changes that affect the current turn,
    possibly wiping out anything in the future -- so you still have to use
    ``get_track`` and ``apply_choices``. However, if you're using a calendar
    in the same interface as another control widget for the same stat,
    ``'present'`` will ensure that the two widgets always display the same value.
    * ``'all'``: apply every change immediately to the LiSE core. Should only be
    used when the LiSE core is in planning mode.

    """

    def on_data(self, *args):
        idx = self.idx
        for item in self.data:
            if 'key' in item and 'turn' in item:
                idx[(item['turn'], item['key'])] = item

    def get_track(self):
        """Get a dictionary that can be used to submit my changes to ``LiSE.Engine.apply_choices``

        If a data dictionary does not have the key 'turn', it will not be included in the track.
        You can use this to add labels and other non-input widgets to the calendar.

        """
        changes = []
        track = {'entity': self.entity, 'changes': changes}
        if not self.data:
            return track
        for datum in self.data:
            if 'turn' in datum:
                break
        else:
            # I don't know *why* the calendar has no actionable data in it but here u go
            return track
        last = self.entity.engine.turn
        accumulator = []
        for datum in self.data:
            if 'turn' not in datum:
                continue
            trn = datum['turn']
            if trn < last:
                continue
            if trn > last:
                if trn > last + 1:
                    changes.extend([[]] * (trn - last - 1))
                changes.append(accumulator)
                accumulator = []
                last = trn
            accumulator.append((datum['key'], datum['value']))
        changes.append(accumulator)
        return track

    def from_schedule(self, schedule, start_turn=None, headers=True, turn_labels=True, key=lambda x: str(x)):
        # It should be convenient to style the calendar using data from the core;
        # not sure what the API should be like
        control2wid = self._control2wid
        if start_turn is None:
            start_turn = self.entity.engine.turn
        curturn = start_turn
        endturn = curturn + len(next(iter(schedule.values())))
        data = []
        stats = sorted((stat for stat in schedule if not stat.startswith('_')), key=key)
        if headers:
            if turn_labels:
                data.append({'widget': 'Label', 'text': ''})
            for stat in stats:
                if stat.startswith('_'):
                    continue
                data.append({'widget': 'Label', 'text': str(stat)})
        cols = len(data)
        iters = {stat: iter(values) for (stat, values) in schedule.items()}
        for turn in range(curturn, endturn):
            if turn_labels:
                data.append({'widget': 'Label', 'text': str(turn)})
            if '_config' in iters:
                config = next(iters['_config'])
            else:
                config = None
            for stat in stats:
                datum = {'key': stat, 'value': next(iters[stat]), 'turn': turn}
                if config and stat in config and 'control' in config[stat]:
                    datum.update(config[stat])
                    datum['widget'] = control2wid.get(datum.pop('control', None), 'CalendarLabel')
                    if datum['widget'] == 'CalendarToggleButton':
                        if datum['value']:
                            datum['text'] = config[stat].get('true_text', 'True')
                            datum['state'] = 'down'
                        else:
                            datum['text'] = config[stat].get('false_text', 'False')
                            datum['state'] = 'normal'
                else:
                    datum['widget'] = 'CalendarLabel'
                data.append(datum)
        (self.cols, self.data, self.changed) = (cols, data, False)

Builder.load_string("""
<Calendar>:
    key_viewclass: 'widget'
    RecycleGridLayout:
        cols: root.cols
        size_hint_y: None
        default_size: None, dp(56)
        default_size_hint: 1, None
        height: self.minimum_height
        orientation: 'horizontal'
<CalendarLabel>:
    text: str(self.value) if self.value is not None else ''
<CalendarSlider>:
    padding: 25
    Label:
        center_x: root.center_x
        y: root.center_y
        text: str(root.value)
        size: self.texture_size
<CalendarOptionButton>:
    text: str(self.value)
""")

if __name__ == '__main__':
    from kivy.app import App
    class CalendarTestApp(App):
        def build(self):
            self.wid = Calendar()
            return self.wid

        def on_start(self):
            # it seems like the calendar blanks out its data sometime after initialization
            data = []
            for i in range(7):
                for j in range(3):
                    data.append({'widget': 'Button', 'text': f'row{i} col{j}'})
            self.wid.data = data

    CalendarTestApp().run()<|endoftext|>


<commit_before># Copyright 2016 Allan Rank
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import mysql.connector

from flask import current_app
from flask import _app_ctx_stack as stack

class MySQLConnector(object):
    def __init__(self, app=None):
        self.app = app
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        app.config.setdefault("MYSQL_HOST", "localhost")
        app.config.setdefault("MYSQL_USER", None)
        app.config.setdefault("MYSQL_PASSWORD", None)
        app.config.setdefault("MYSQL_DB", None)
        app.config.setdefault("MYSQL_PORT", 3306)
        app.config.setdefault("MYSQL_UNIX_SOCKET", None)
        app.config.setdefault("MYSQL_USE_UNICODE", True)
        app.config.setdefault("MYSQL_CHARSET", "utf8")
        app.config.setdefault("MYSQL_AUTOCOMMIT", False)
        app.config.setdefault("MYSQL_TIME_ZONE", None)
        app.config.setdefault("MYSQL_SQL_MODE", None)
        app.config.setdefault("MYSQL_CONNECTION_TIMEOUT", 10)
        app.config.setdefault("MYSQL_CLIENT_FLAGS", None)
        app.config.setdefault("MYSQL_BUFFERED", False)
        app.config.setdefault("MYSQL_RAW", False)
        app.config.setdefault("MYSQL_CONSUME_RESULTS", False)
        app.config.setdefault("MYSQL_AUTH_PLUGIN", None)
        app.config.setdefault("MYSQL_COLLATION", "utf8_general_ci")
        app.config.setdefault("MYSQL_GET_WARNINGS", False)
        app.config.setdefault("MYSQL_RAISE_ON_WARNINGS", False)
        app.config.setdefault("MYSQL_SSL_CA", None)
        app.config.setdefault("MYSQL_SSL_CERT", None)
        app.config.setdefault("MYSQL_SSL_KEY", None)
        app.config.setdefault("MYSQL_SSL_VERIFY_CERT", False)
        app.config.setdefault("MYSQL_FORCE_IPV6", False)
        app.config.setdefault("MYSQL_POOL_NAME", None)
        app.config.setdefault("MYSQL_POOL_SIZE", None)
        app.config.setdefault("MYSQL_POOL_RESET_SESSION", None)
        app.config.setdefault("MYSQL_COMPRESS", False)
        app.config.setdefault("MYSQL_CONVERTER_CLASS", None)
        app.config.setdefault("MYSQL_FABRIC", None)
        app.config.setdefault("MYSQL_FAILOVER", None)
        app.config.setdefault("MYSQL_OPTION_FILES", None)
        app.config.setdefault("MYSQL_OPTION_GROUPS", None)
        app.config.setdefault("MYSQL_ALLOW_LOCAL_INFILE", True)
        app.config.setdefault("MYSQL_USE_PURE", True)

        if hasattr(app, "teardown_appcontext"):
            app.teardown_appcontext(self.teardown)
        else:
            app.teardown_request(self.teardown)

    def connect(self):
        arguments = {}
        if current_app.config["MYSQL_HOST"]:
            arguments["host"] = current_app.config["MYSQL_HOST"]

        if current_app.config["MYSQL_USER"]:
            arguments["user"] = current_app.config["MYSQL_USER"]

        if current_app.config["MYSQL_PASSWORD"]:
            arguments["password"] = current_app.config["MYSQL_PASSWORD"]

        if current_app.config["MYSQL_DB"]:
            arguments["database"] = current_app.config["MYSQL_DB"]

        if current_app.config["MYSQL_PORT"]:
            arguments["port"] = current_app.config["MYSQL_PORT"]

        if current_app.config["MYSQL_UNIX_SOCKET"]:
            arguments["unix_socket"] = current_app.config["MYSQL_UNIX_SOCKET"]

        if current_app.config["MYSQL_USE_UNICODE"]:
            arguments["use_unicode"] = current_app.config["MYSQL_USE_UNICODE"]

        if current_app.config["MYSQL_CHARSET"]:
            arguments["charset"] = current_app.config["MYSQL_CHARSET"]

        if current_app.config["MYSQL_AUTOCOMMIT"]:
            arguments["autocommit"] = current_app.config["MYSQL_AUTOCOMMIT"]

        if current_app.config["MYSQL_TIME_ZONE"]:
            arguments["time_zone"] = current_app.config["MYSQL_TIME_ZONE"]

        if current_app.config["MYSQL_SQL_MODE"]:
            arguments["sql_mode"] = current_app.config["MYSQL_SQL_MODE"]

        if current_app.config["MYSQL_CONNECTION_TIMEOUT"]:
            arguments["connection_timeout"] = current_app.config["MYSQL_CONNECTION_TIMEOUT"]

        if current_app.config["MYSQL_CLIENT_FLAGS"]:
            arguments["client_flags"] = current_app.config["MYSQL_CLIENT_FLAGS"]

        if current_app.config["MYSQL_BUFFERED"]:
            arguments["buffered"] = current_app.config["MYSQL_BUFFERED"]

        if current_app.config["MYSQL_RAW"]:
            arguments["raw"] = current_app.config["MYSQL_RAW"]

        if current_app.config["MYSQL_CONSUME_RESULTS"]:
            arguments["consume_results"] = current_app.config["MYSQL_CONSUME_RESULTS"]

        if current_app.config["MYSQL_AUTH_PLUGIN"]:
            arguments["auth_plugin"] = current_app.config["MYSQL_AUTH_PLUGIN"]

        if current_app.config["MYSQL_COLLATION"]:
            arguments["collation"] = current_app.config["MYSQL_COLLATION"]

        if current_app.config["MYSQL_GET_WARNINGS"]:
            arguments["get_warnings"] = current_app.config["MYSQL_GET_WARNINGS"]

        if current_app.config["MYSQL_RAISE_ON_WARNINGS"]:
            arguments["raise_on_warnings"] = current_app.config["MYSQL_RAISE_ON_WARNINGS"]

        if current_app.config["MYSQL_SSL_CA"]:
            arguments["ssl_ca"] = current_app.config["MYSQL_SSL_CA"]

        if current_app.config["MYSQL_SSL_CERT"]:
            arguments["ssl_cert"] = current_app.config["MYSQL_SSL_CERT"]

        if current_app.config["MYSQL_SSL_KEY"]:
            arguments["ssl_key"] = current_app.config["MYSQL_SSL_KEY"]

        if current_app.config["MYSQL_SSL_VERIFY_CERT"]:
            arguments["ssl_verify_cert"] = current_app.config["MYSQL_SSL_VERIFY_CERT"]

        if current_app.config["MYSQL_FORCE_IPV6"]:
            arguments["force_ipv6"] = current_app.config["MYSQL_FORCE_IPV6"]

        if current_app.config["MYSQL_POOL_NAME"]:
            arguments["pool_name"] = current_app.config["MYSQL_POOL_NAME"]

        if current_app.config["MYSQL_POOL_SIZE"]:
            arguments["pool_size"] = current_app.config["MYSQL_POOL_SIZE"]

        if current_app.config["MYSQL_POOL_RESET_SESSION"]:
            arguments["pool_reset_session"] = current_app.config["MYSQL_POOL_RESET_SESSION"]

        if current_app.config["MYSQL_COMPRESS"]:
            arguments["compress"] = current_app.config["MYSQL_COMPRESS"]

        if current_app.config["MYSQL_CONVERTER_CLASS"]:
            arguments["converter_class"] = current_app.config["MYSQL_CONVERTER_CLASS"]

        if current_app.config["MYSQL_FABRIC"]:
            arguments["fabric"] = current_app.config["MYSQL_FABRIC"]

        if current_app.config["MYSQL_FAILOVER"]:
            arguments["failover"] = current_app.config["MYSQL_FAILOVER"]

        if current_app.config["MYSQL_OPTION_FILES"]:
            arguments["option_files"] = current_app.config["MYSQL_OPTION_FILES"]

        if current_app.config["MYSQL_OPTION_GROUPS"]:
            arguments["option_groups"] = current_app.config["MYSQL_OPTION_GROUPS"]

        if current_app.config["MYSQL_ALLOW_LOCAL_INFILE"]:
            arguments["allow_local_infile"] = current_app.config["MYSQL_ALLOW_LOCAL_INFILE"]

        if current_app.config["MYSQL_USE_PURE"]:
            arguments["use_pure"] = current_app.config["MYSQL_USE_PURE"]

        return mysql.connector.connect(**arguments)

    def teardown(self, exception):
        ctx = stack.top
        if hasattr(ctx, "mysql_connector"):
            ctx.mysql_connector.close()

    @property
    def connection(self):
        ctx = stack.top
        if ctx is not None:
            if not hasattr(ctx, "mysql_connector"):
                ctx.mysql_connector = self.connect()
            return ctx.mysql_connector
<commit_msg>mysqlconnector: property for testing usage of c extension<commit_after># Copyright 2016 Allan Rank
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import mysql.connector

from flask import current_app
from flask import _app_ctx_stack as stack

class MySQLConnector(object):
    def __init__(self, app=None):
        self.app = app
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        app.config.setdefault("MYSQL_HOST", "localhost")
        app.config.setdefault("MYSQL_USER", None)
        app.config.setdefault("MYSQL_PASSWORD", None)
        app.config.setdefault("MYSQL_DB", None)
        app.config.setdefault("MYSQL_PORT", 3306)
        app.config.setdefault("MYSQL_UNIX_SOCKET", None)
        app.config.setdefault("MYSQL_USE_UNICODE", True)
        app.config.setdefault("MYSQL_CHARSET", "utf8")
        app.config.setdefault("MYSQL_AUTOCOMMIT", False)
        app.config.setdefault("MYSQL_TIME_ZONE", None)
        app.config.setdefault("MYSQL_SQL_MODE", None)
        app.config.setdefault("MYSQL_CONNECTION_TIMEOUT", 10)
        app.config.setdefault("MYSQL_CLIENT_FLAGS", None)
        app.config.setdefault("MYSQL_BUFFERED", False)
        app.config.setdefault("MYSQL_RAW", False)
        app.config.setdefault("MYSQL_CONSUME_RESULTS", False)
        app.config.setdefault("MYSQL_AUTH_PLUGIN", None)
        app.config.setdefault("MYSQL_COLLATION", "utf8_general_ci")
        app.config.setdefault("MYSQL_GET_WARNINGS", False)
        app.config.setdefault("MYSQL_RAISE_ON_WARNINGS", False)
        app.config.setdefault("MYSQL_SSL_CA", None)
        app.config.setdefault("MYSQL_SSL_CERT", None)
        app.config.setdefault("MYSQL_SSL_KEY", None)
        app.config.setdefault("MYSQL_SSL_VERIFY_CERT", False)
        app.config.setdefault("MYSQL_FORCE_IPV6", False)
        app.config.setdefault("MYSQL_POOL_NAME", None)
        app.config.setdefault("MYSQL_POOL_SIZE", None)
        app.config.setdefault("MYSQL_POOL_RESET_SESSION", None)
        app.config.setdefault("MYSQL_COMPRESS", False)
        app.config.setdefault("MYSQL_CONVERTER_CLASS", None)
        app.config.setdefault("MYSQL_FABRIC", None)
        app.config.setdefault("MYSQL_FAILOVER", None)
        app.config.setdefault("MYSQL_OPTION_FILES", None)
        app.config.setdefault("MYSQL_OPTION_GROUPS", None)
        app.config.setdefault("MYSQL_ALLOW_LOCAL_INFILE", True)
        app.config.setdefault("MYSQL_USE_PURE", True)

        if hasattr(app, "teardown_appcontext"):
            app.teardown_appcontext(self.teardown)
        else:
            app.teardown_request(self.teardown)

    def connect(self):
        arguments = {}
        if current_app.config["MYSQL_HOST"]:
            arguments["host"] = current_app.config["MYSQL_HOST"]

        if current_app.config["MYSQL_USER"]:
            arguments["user"] = current_app.config["MYSQL_USER"]

        if current_app.config["MYSQL_PASSWORD"]:
            arguments["password"] = current_app.config["MYSQL_PASSWORD"]

        if current_app.config["MYSQL_DB"]:
            arguments["database"] = current_app.config["MYSQL_DB"]

        if current_app.config["MYSQL_PORT"]:
            arguments["port"] = current_app.config["MYSQL_PORT"]

        if current_app.config["MYSQL_UNIX_SOCKET"]:
            arguments["unix_socket"] = current_app.config["MYSQL_UNIX_SOCKET"]

        if current_app.config["MYSQL_USE_UNICODE"]:
            arguments["use_unicode"] = current_app.config["MYSQL_USE_UNICODE"]

        if current_app.config["MYSQL_CHARSET"]:
            arguments["charset"] = current_app.config["MYSQL_CHARSET"]

        if current_app.config["MYSQL_AUTOCOMMIT"]:
            arguments["autocommit"] = current_app.config["MYSQL_AUTOCOMMIT"]

        if current_app.config["MYSQL_TIME_ZONE"]:
            arguments["time_zone"] = current_app.config["MYSQL_TIME_ZONE"]

        if current_app.config["MYSQL_SQL_MODE"]:
            arguments["sql_mode"] = current_app.config["MYSQL_SQL_MODE"]

        if current_app.config["MYSQL_CONNECTION_TIMEOUT"]:
            arguments["connection_timeout"] = current_app.config["MYSQL_CONNECTION_TIMEOUT"]

        if current_app.config["MYSQL_CLIENT_FLAGS"]:
            arguments["client_flags"] = current_app.config["MYSQL_CLIENT_FLAGS"]

        if current_app.config["MYSQL_BUFFERED"]:
            arguments["buffered"] = current_app.config["MYSQL_BUFFERED"]

        if current_app.config["MYSQL_RAW"]:
            arguments["raw"] = current_app.config["MYSQL_RAW"]

        if current_app.config["MYSQL_CONSUME_RESULTS"]:
            arguments["consume_results"] = current_app.config["MYSQL_CONSUME_RESULTS"]

        if current_app.config["MYSQL_AUTH_PLUGIN"]:
            arguments["auth_plugin"] = current_app.config["MYSQL_AUTH_PLUGIN"]

        if current_app.config["MYSQL_COLLATION"]:
            arguments["collation"] = current_app.config["MYSQL_COLLATION"]

        if current_app.config["MYSQL_GET_WARNINGS"]:
            arguments["get_warnings"] = current_app.config["MYSQL_GET_WARNINGS"]

        if current_app.config["MYSQL_RAISE_ON_WARNINGS"]:
            arguments["raise_on_warnings"] = current_app.config["MYSQL_RAISE_ON_WARNINGS"]

        if current_app.config["MYSQL_SSL_CA"]:
            arguments["ssl_ca"] = current_app.config["MYSQL_SSL_CA"]

        if current_app.config["MYSQL_SSL_CERT"]:
            arguments["ssl_cert"] = current_app.config["MYSQL_SSL_CERT"]

        if current_app.config["MYSQL_SSL_KEY"]:
            arguments["ssl_key"] = current_app.config["MYSQL_SSL_KEY"]

        if current_app.config["MYSQL_SSL_VERIFY_CERT"]:
            arguments["ssl_verify_cert"] = current_app.config["MYSQL_SSL_VERIFY_CERT"]

        if current_app.config["MYSQL_FORCE_IPV6"]:
            arguments["force_ipv6"] = current_app.config["MYSQL_FORCE_IPV6"]

        if current_app.config["MYSQL_POOL_NAME"]:
            arguments["pool_name"] = current_app.config["MYSQL_POOL_NAME"]

        if current_app.config["MYSQL_POOL_SIZE"]:
            arguments["pool_size"] = current_app.config["MYSQL_POOL_SIZE"]

        if current_app.config["MYSQL_POOL_RESET_SESSION"]:
            arguments["pool_reset_session"] = current_app.config["MYSQL_POOL_RESET_SESSION"]

        if current_app.config["MYSQL_COMPRESS"]:
            arguments["compress"] = current_app.config["MYSQL_COMPRESS"]

        if current_app.config["MYSQL_CONVERTER_CLASS"]:
            arguments["converter_class"] = current_app.config["MYSQL_CONVERTER_CLASS"]

        if current_app.config["MYSQL_FABRIC"]:
            arguments["fabric"] = current_app.config["MYSQL_FABRIC"]

        if current_app.config["MYSQL_FAILOVER"]:
            arguments["failover"] = current_app.config["MYSQL_FAILOVER"]

        if current_app.config["MYSQL_OPTION_FILES"]:
            arguments["option_files"] = current_app.config["MYSQL_OPTION_FILES"]

        if current_app.config["MYSQL_OPTION_GROUPS"]:
            arguments["option_groups"] = current_app.config["MYSQL_OPTION_GROUPS"]

        if current_app.config["MYSQL_ALLOW_LOCAL_INFILE"]:
            arguments["allow_local_infile"] = current_app.config["MYSQL_ALLOW_LOCAL_INFILE"]

        if current_app.config["MYSQL_USE_PURE"]:
            arguments["use_pure"] = current_app.config["MYSQL_USE_PURE"]

        return mysql.connector.connect(**arguments)

    def teardown(self, exception):
        ctx = stack.top
        if hasattr(ctx, "mysql_connector"):
            ctx.mysql_connector.close()

    @property
    def connection(self):
        ctx = stack.top
        if ctx is not None:
            if not hasattr(ctx, "mysql_connector"):
                ctx.mysql_connector = self.connect()
            return ctx.mysql_connector

    @property
    def have_cext(self):
        try:
            return mysql.connector.HAVE_CEXT
        except AttributeError:
            return False
<|endoftext|>


<commit_before>from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
import sys
try:
	import MacOS
except ImportError:
	MacOS = None
from .py23 import *

def _reverseString(s):
	s = list(s)
	s.reverse()
	return strjoin(s)

def getMacCreatorAndType(path):
	if MacOS is not None:
		fileCreator, fileType = MacOS.GetCreatorAndType(path)
		if sys.version_info[:2] < (2, 7) and sys.byteorder == "little":
			# work around bug in MacOS.GetCreatorAndType() on intel:
			# http://bugs.python.org/issue1594
			# (fixed with Python 2.7)
			fileCreator = _reverseString(fileCreator)
			fileType = _reverseString(fileType)
		return fileCreator, fileType
	else:
		return None, None

def setMacCreatorAndType(path, fileCreator, fileType):
	if MacOS is not None:
		if sys.byteorder == "little":
			# work around bug in MacOS.SetCreatorAndType() on intel:
			# http://bugs.python.org/issue1594
			fileCreator = _reverseString(fileCreator)
			fileType = _reverseString(fileType)
		MacOS.SetCreatorAndType(path, fileCreator, fileType)
<commit_msg>[macCreatorType] disable workaround in py27 for setting as well getting<commit_after>from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
import sys
try:
	import MacOS
except ImportError:
	MacOS = None
from .py23 import *

def _reverseString(s):
	s = list(s)
	s.reverse()
	return strjoin(s)

def getMacCreatorAndType(path):
	if MacOS is not None:
		fileCreator, fileType = MacOS.GetCreatorAndType(path)
		if sys.version_info[:2] < (2, 7) and sys.byteorder == "little":
			# work around bug in MacOS.GetCreatorAndType() on intel:
			# http://bugs.python.org/issue1594
			# (fixed with Python 2.7)
			fileCreator = _reverseString(fileCreator)
			fileType = _reverseString(fileType)
		return fileCreator, fileType
	else:
		return None, None

def setMacCreatorAndType(path, fileCreator, fileType):
	if MacOS is not None:
		if sys.version_info[:2] < (2, 7) and sys.byteorder == "little":
			# work around bug in MacOS.SetCreatorAndType() on intel:
			# http://bugs.python.org/issue1594
			# (fixed with Python 2.7)
			fileCreator = _reverseString(fileCreator)
			fileType = _reverseString(fileType)
		MacOS.SetCreatorAndType(path, fileCreator, fileType)
<|endoftext|>


<commit_before># Copyright 2012 10gen, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Motor specific extensions to Sphinx."""

import inspect

from docutils.nodes import field, list_item, paragraph, title_reference
from docutils.nodes import field_list, field_body, bullet_list, Text, field_name
from sphinx.addnodes import desc, desc_content, versionmodified, desc_signature
from sphinx.util.inspect import safe_getattr

import motor

# This is a place to store info while parsing, to be used before generating.
motor_info = {}

def find_by_path(root, classes):
    if not classes:
        return [root]

    _class = classes[0]
    rv = []
    for child in root.children:
        if isinstance(child, _class):
            rv.extend(find_by_path(child, classes[1:]))

    return rv

def get_parameter_names(parameters_node):
    parameter_names = []
    for list_item_node in find_by_path(parameters_node, [list_item]):
        title_ref_nodes = find_by_path(
            list_item_node, [paragraph, title_reference])

        parameter_names.append(title_ref_nodes[0].astext())

    return parameter_names

def insert_callback(parameters_node, callback_required):
    # We need to know what params are here already
    parameter_names = get_parameter_names(parameters_node)

    if 'callback' not in parameter_names:
        if '*args' in parameter_names:
            args_pos = parameter_names.index('*args')
        else:
            args_pos = len(parameter_names)

        if '**kwargs' in parameter_names:
            kwargs_pos = parameter_names.index('**kwargs')
        else:
            kwargs_pos = len(parameter_names)

        doc = (" (%s): function taking (result, error), to execute when operation"
            " completes" % ("required" if callback_required else "optional"))

        new_item = list_item(
            '', paragraph(
                '', '',
                title_reference('', 'callback'),
                Text(doc)))

        # Insert "callback" before *args and **kwargs
        parameters_node.insert(min(args_pos, kwargs_pos), new_item)

def process_motor_nodes(app, doctree):
    # Search doctree for Motor's methods and attributes whose docstrings were
    # copied from PyMongo, and fix them up for Motor:
    #   1. Add a 'callback' param (sometimes optional, sometimes required) to
    #      all async methods. If the PyMongo method took no params, we create
    #      a parameter-list from scratch, otherwise we edit PyMongo's list.
    #   2. Remove all version annotations like "New in version 2.0" since
    #      PyMongo's version numbers are meaningless in Motor's docs.
    #
    # We do this here, rather than by registering a callback to Sphinx's
    # 'autodoc-process-signature' event, because it's way easier to handle the
    # parsed doctree before it's turned into HTML than it is to update the RST.
    for objnode in doctree.traverse(desc):
        if objnode['objtype'] in ('method', 'attribute'):
            signature_node = find_by_path(objnode, [desc_signature])[0]
            name = '.'.join([
                signature_node['module'], signature_node['fullname']])

            assert name.startswith('motor.')
            obj_motor_info = motor_info.get(name)
            if obj_motor_info:
                desc_content_node = find_by_path(objnode, [desc_content])[0]
                if obj_motor_info.get('is_async_method'):
                    try:
                        # Find the parameter list, a bullet_list instance
                        parameters_node = find_by_path(desc_content_node,
                            [field_list, field, field_body, bullet_list])[0]
                    except IndexError:
                        # PyMongo method has no parameters, create an empty
                        # params list
                        parameters_node = bullet_list()
                        parameters_field_list_node = field_list('',
                            field('',
                                field_name('', 'Parameters '),
                                field_body('',
                                    parameters_node)))

                        desc_content_node.append(parameters_field_list_node)

                    insert_callback(
                        parameters_node, obj_motor_info['callback_required'])

                if obj_motor_info['is_pymongo_docstring']:
                    # Remove all "versionadded", "versionchanged" and
                    # "deprecated" directives from the docs we imported from
                    # PyMongo
                    version_nodes = find_by_path(
                        desc_content_node, [versionmodified])

                    for version_node in version_nodes:
                        version_node.parent.remove(version_node)

def get_motor_attr(motor_class, name, *defargs):
    """If any Motor attributes can't be accessed, grab the equivalent PyMongo
    attribute. While we're at it, store some info about each attribute
    in the global motor_info dict.
    """
    attr = safe_getattr(motor_class, name)
    method_class = safe_getattr(attr, 'im_class', None)
    from_pymongo = not safe_getattr(
        method_class, '__module__', '').startswith('motor')

    # Store some info for process_motor_nodes()
    full_name = '%s.%s.%s' % (
        motor_class.__module__, motor_class.__name__, name)

    is_async_method = getattr(attr, 'is_async_method', False)
    is_cursor_method = getattr(attr, 'is_motorcursor_chaining_method', False)
    if is_async_method or is_cursor_method:
        pymongo_method = getattr(
            motor_class.__delegate_class__, attr.pymongo_method_name)
    else:
        pymongo_method = None

    is_pymongo_docstring = from_pymongo or is_async_method or is_cursor_method

    motor_info[full_name] = {
        # These sub-attributes are set in motor.asynchronize()
        'is_async_method': is_async_method,
        'callback_required': getattr(attr, 'callback_required', False),
        'is_pymongo_docstring': is_pymongo_docstring,
        'pymongo_method': pymongo_method }

    return attr

def get_motor_argspec(pymongo_method, is_async_method):
    args, varargs, kwargs, defaults = inspect.getargspec(pymongo_method)

    # This part is copied from Sphinx's autodoc.py
    if args and args[0] in ('cls', 'self'):
        del args[0]

    defaults = list(defaults) if defaults else []

    if is_async_method:
        # Add 'callback=None' argument
        args.append('callback')
        defaults.append(None)

    return (args, varargs, kwargs, defaults)

# Adapted from MethodDocumenter.format_args
def format_motor_args(pymongo_method, is_async_method):
    argspec = get_motor_argspec(pymongo_method, is_async_method)
    formatted_argspec = inspect.formatargspec(*argspec)
    # escape backslashes for reST
    return formatted_argspec.replace('\\', '\\\\')

def process_motor_signature(app, what, name, obj, options, signature, return_annotation):
    if name in motor_info and motor_info[name].get('pymongo_method'):
        # Real sig obscured by decorator, reconstruct it
        pymongo_method = motor_info[name]['pymongo_method']
        is_async_method = motor_info[name]['is_async_method']
        args = format_motor_args(pymongo_method, is_async_method)
        return (args, return_annotation)

def setup(app):
    app.add_autodoc_attrgetter(type(motor.MotorBase), get_motor_attr)
    app.connect('autodoc-process-signature', process_motor_signature)
    app.connect("doctree-read", process_motor_nodes)
<commit_msg>Update Motor's Sphinx extension for Futures<commit_after># Copyright 2012 10gen, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Motor specific extensions to Sphinx."""

import inspect

from docutils.nodes import field, list_item, paragraph, title_reference
from docutils.nodes import field_list, field_body, bullet_list, Text, field_name
from sphinx.addnodes import desc, desc_content, versionmodified, desc_signature
from sphinx.util.inspect import safe_getattr

import motor

# This is a place to store info while parsing, to be used before generating.
motor_info = {}

def find_by_path(root, classes):
    if not classes:
        return [root]

    _class = classes[0]
    rv = []
    for child in root.children:
        if isinstance(child, _class):
            rv.extend(find_by_path(child, classes[1:]))

    return rv

def get_parameter_names(parameters_node):
    parameter_names = []
    for list_item_node in find_by_path(parameters_node, [list_item]):
        title_ref_nodes = find_by_path(
            list_item_node, [paragraph, title_reference])

        parameter_names.append(title_ref_nodes[0].astext())

    return parameter_names

def insert_callback(parameters_node):
    # We need to know what params are here already
    parameter_names = get_parameter_names(parameters_node)

    if 'callback' not in parameter_names:
        if '*args' in parameter_names:
            args_pos = parameter_names.index('*args')
        else:
            args_pos = len(parameter_names)

        if '**kwargs' in parameter_names:
            kwargs_pos = parameter_names.index('**kwargs')
        else:
            kwargs_pos = len(parameter_names)

        doc = (
            " (optional): function taking (result, error), executed when"
            " operation completes")

        new_item = list_item(
            '', paragraph(
                '', '',
                title_reference('', 'callback'),
                Text(doc)))

        # Insert "callback" before *args and **kwargs
        parameters_node.insert(min(args_pos, kwargs_pos), new_item)

def process_motor_nodes(app, doctree):
    # Search doctree for Motor's methods and attributes whose docstrings were
    # copied from PyMongo, and fix them up for Motor:
    #   1. Add a 'callback' param (sometimes optional, sometimes required) to
    #      all async methods. If the PyMongo method took no params, we create
    #      a parameter-list from scratch, otherwise we edit PyMongo's list.
    #   2. Remove all version annotations like "New in version 2.0" since
    #      PyMongo's version numbers are meaningless in Motor's docs.
    #
    # We do this here, rather than by registering a callback to Sphinx's
    # 'autodoc-process-signature' event, because it's way easier to handle the
    # parsed doctree before it's turned into HTML than it is to update the RST.
    for objnode in doctree.traverse(desc):
        if objnode['objtype'] in ('method', 'attribute'):
            signature_node = find_by_path(objnode, [desc_signature])[0]
            name = '.'.join([
                signature_node['module'], signature_node['fullname']])

            assert name.startswith('motor.')
            obj_motor_info = motor_info.get(name)
            if obj_motor_info:
                desc_content_node = find_by_path(objnode, [desc_content])[0]
                if obj_motor_info.get('is_async_method'):
                    try:
                        # Find the parameter list, a bullet_list instance
                        parameters_node = find_by_path(
                            desc_content_node,
                            [field_list, field, field_body, bullet_list])[0]
                    except IndexError:
                        # PyMongo method has no parameters, create an empty
                        # params list
                        parameters_node = bullet_list()
                        parameters_field_list_node = field_list(
                            '',
                            field(
                                '',
                                field_name('', 'Parameters '),
                                field_body('', parameters_node)))

                        desc_content_node.append(parameters_field_list_node)

                    insert_callback(parameters_node)

                    callback_future_text = (
                        "If a callback is passed, returns None, else returns a"
                        " Future.")

                    desc_content_node.append(
                        paragraph('', Text(callback_future_text)))

                if obj_motor_info['is_pymongo_docstring']:
                    # Remove all "versionadded", "versionchanged" and
                    # "deprecated" directives from the docs we imported from
                    # PyMongo
                    version_nodes = find_by_path(
                        desc_content_node, [versionmodified])

                    for version_node in version_nodes:
                        version_node.parent.remove(version_node)

def get_motor_attr(motor_class, name, *defargs):
    """If any Motor attributes can't be accessed, grab the equivalent PyMongo
    attribute. While we're at it, store some info about each attribute
    in the global motor_info dict.
    """
    attr = safe_getattr(motor_class, name)
    method_class = safe_getattr(attr, 'im_class', None)
    from_pymongo = not safe_getattr(
        method_class, '__module__', '').startswith('motor')

    # Store some info for process_motor_nodes()
    full_name = '%s.%s.%s' % (
        motor_class.__module__, motor_class.__name__, name)

    is_async_method = getattr(attr, 'is_async_method', False)
    is_cursor_method = getattr(attr, 'is_motorcursor_chaining_method', False)
    if is_async_method or is_cursor_method:
        pymongo_method = getattr(
            motor_class.__delegate_class__, attr.pymongo_method_name)
    else:
        pymongo_method = None

    is_pymongo_docstring = from_pymongo or is_async_method or is_cursor_method

    motor_info[full_name] = {
        # These sub-attributes are set in motor.asynchronize()
        'is_async_method': is_async_method,
        'is_pymongo_docstring': is_pymongo_docstring,
        'pymongo_method': pymongo_method,
    }

    return attr

def get_motor_argspec(pymongo_method, is_async_method):
    args, varargs, kwargs, defaults = inspect.getargspec(pymongo_method)

    # This part is copied from Sphinx's autodoc.py
    if args and args[0] in ('cls', 'self'):
        del args[0]

    defaults = list(defaults) if defaults else []

    if is_async_method:
        # Add 'callback=None' argument
        args.append('callback')
        defaults.append(None)

    return args, varargs, kwargs, defaults

# Adapted from MethodDocumenter.format_args
def format_motor_args(pymongo_method, is_async_method):
    argspec = get_motor_argspec(pymongo_method, is_async_method)
    formatted_argspec = inspect.formatargspec(*argspec)
    # escape backslashes for reST
    return formatted_argspec.replace('\\', '\\\\')

def process_motor_signature(
        app, what, name, obj, options, signature, return_annotation):
    if name in motor_info and motor_info[name].get('pymongo_method'):
        # Real sig obscured by decorator, reconstruct it
        pymongo_method = motor_info[name]['pymongo_method']
        is_async_method = motor_info[name]['is_async_method']
        args = format_motor_args(pymongo_method, is_async_method)
        return args, return_annotation

def setup(app):
    app.add_autodoc_attrgetter(type(motor.MotorBase), get_motor_attr)
    app.connect('autodoc-process-signature', process_motor_signature)
    app.connect("doctree-read", process_motor_nodes)
<|endoftext|>


<commit_before># -*- coding:utf-8 -*-
#from django.conf.urls import patterns, url, include
from rest_framework.routers import DefaultRouter
from django.http import HttpResponseRedirect

# class MyRouter(DefaultRouter):
#
#     def get_api_root_view(self):
#         return lambda r: HttpResponseRedirect('https://github.com/globocom/database-as-a-service/wiki/Introduction-to-the-API')

router = DefaultRouter()

# physical
from .environment import EnvironmentAPI
router.register(r'environment', EnvironmentAPI)

from .plan import PlanAPI
router.register(r'plan', PlanAPI)

from .engine import EngineAPI
router.register(r'engine', EngineAPI)

from .engine_type import EngineTypeAPI
router.register(r'engine_type', EngineTypeAPI)

# logical
from .project import ProjectAPI
router.register(r'project', ProjectAPI)

from .database import DatabaseAPI
router.register(r'database', DatabaseAPI)

from .credential import CredentialAPI
router.register(r'credential', CredentialAPI)

urlpatterns = router.urls

# urlpatterns = patterns(
#     '',
#     # url(r'^$', 'api_help', name='api.index'),
#     # url(r'^', include(router.urls)),
#     # url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
#     url('^logical', )
# )
<commit_msg>Add integration type and credential url<commit_after># -*- coding:utf-8 -*-
#from django.conf.urls import patterns, url, include
from rest_framework.routers import DefaultRouter
from django.http import HttpResponseRedirect

# class MyRouter(DefaultRouter):
#
#     def get_api_root_view(self):
#         return lambda r: HttpResponseRedirect('https://github.com/globocom/database-as-a-service/wiki/Introduction-to-the-API')

router = DefaultRouter()

# physical
from .environment import EnvironmentAPI
router.register(r'environment', EnvironmentAPI)

from .plan import PlanAPI
router.register(r'plan', PlanAPI)

from .engine import EngineAPI
router.register(r'engine', EngineAPI)

from .engine_type import EngineTypeAPI
router.register(r'engine_type', EngineTypeAPI)

# logical
from .project import ProjectAPI
router.register(r'project', ProjectAPI)

from .database import DatabaseAPI
router.register(r'database', DatabaseAPI)

from .credential import CredentialAPI
router.register(r'credential', CredentialAPI)

from .integration_type import IntegrationTypeAPI
router.register(r'integration_type', IntegrationTypeAPI)

from .integration_credential import IntegrationCredentialAPI
router.register(r'integration_credential', IntegrationCredentialAPI)

urlpatterns = router.urls

# urlpatterns = patterns(
#     '',
#     # url(r'^$', 'api_help', name='api.index'),
#     # url(r'^', include(router.urls)),
#     # url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
#     url('^logical', )
# )
<|endoftext|>


<commit_before># Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

SR = {
    "taigaio_url": "https://taiga.io",
    "social": {
        "twitter_url": "https://twitter.com/taigaio",
        "github_url": "https://github.com/taigaio",
    },
    "support": {
        "url": "https://taiga.io/support",
        "email": "support@taiga.io",
        "mailing_list": "https://groups.google.com/forum/#!forum/taigaio",
    }
}
<commit_msg>Fix support pages url<commit_after># Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

SR = {
    "taigaio_url": "https://taiga.io",
    "social": {
        "twitter_url": "https://twitter.com/taigaio",
        "github_url": "https://github.com/taigaio",
    },
    "support": {
        "url": "https://tree.taiga.io/support",
        "email": "support@taiga.io",
        "mailing_list": "https://groups.google.com/forum/#!forum/taigaio",
    }
}
<|endoftext|>


<commit_before>import socket
import threading
import json

class EnablerConnection():
    def __init__(self):
        self.connections = []

        self.stopped = False
        self.enabler_listening_port = 50001

        self.local_ip = socket.gethostbyname(socket.gethostname())
        t = threading.Thread(target=self.listen_loop, name='0.0.0.0',
                args=('0.0.0.0',))
        t.setDaemon(True)
        t.start()

    def send(self, outString):
        for socket_handler in self.connections:
            try:
                socket_handler.send(outString)
            except Exception as e:
                # TODO:  Isolate dropped connection, recover from other things.
                # For now, no recovery.  If ANYTHING goes wrong, drop the
                # connection.
                print("Exception while sending data: %s" % e)
                self.connections.remove(socket_handler)
                print("Connection dropped.")

    def listen_loop(self, this_ip):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((this_ip, self.enabler_listening_port))
        s.listen(1)
        print("Listening for OpenXC Enabler on " + this_ip + ":" +
                str(self.enabler_listening_port))
        while True:
            conn, addr = s.accept()
            print("New connection to " + this_ip + " from " + str(addr))
            handler = SocketHandler(conn, addr)
            handler.start()
            self.connections.append(handler)

    def send_measurement(self, name, value, event=None):
        data = {'name':name,'value':value}
        if event is not None and event != '':
            data['event'] = event
        self.send(json.dumps(data) + '\x00')

    def received_messages(self):
        all_received_data = ''.join(handler.received_command_data for handler in
                self.connections)
        return all_received_data.split('\0')

class SocketHandler(threading.Thread):
    def __init__(self, connection, address):
        super(SocketHandler, self).__init__()
        self.daemon = True
        self.connection = connection
        self.address = address
        self.received_command_data = ""

    def send(self, data):
        self.connection.sendall(data)

    def run(self):
        while True:
            data = self.connection.recv(1024)
            if not data:
                break
            else:
                self.received_command_data += data
<commit_msg>Update code for python3<commit_after>import socket
import threading
import json

class EnablerConnection():
    def __init__(self):
        self.connections = []

        self.stopped = False
        self.enabler_listening_port = 50001

        self.local_ip = socket.gethostbyname(socket.gethostname())
        t = threading.Thread(target=self.listen_loop, name='0.0.0.0',
                args=('0.0.0.0',))
        t.setDaemon(True)
        t.start()

    def send(self, outString):
        for socket_handler in self.connections:
            try:
                socket_handler.send(outString)
            except Exception as e:
                # TODO:  Isolate dropped connection, recover from other things.
                # For now, no recovery.  If ANYTHING goes wrong, drop the
                # connection.
                print("Exception while sending data: %s" % e)
                self.connections.remove(socket_handler)
                print("Connection dropped.")

    def listen_loop(self, this_ip):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((this_ip, self.enabler_listening_port))
        s.listen(1)
        print("Listening for OpenXC Enabler on " + this_ip + ":" +
                str(self.enabler_listening_port))
        while True:
            conn, addr = s.accept()
            print("New connection to " + this_ip + " from " + str(addr))
            handler = SocketHandler(conn, addr)
            handler.start()
            self.connections.append(handler)

    def send_measurement(self, name, value, event=None):
        data = {'name':name,'value':value}
        if event is not None and event != '':
            data['event'] = event
        self.send(str.encode(json.dumps(data) + '\x00'))

    def received_messages(self):
        all_received_data = ''.join(handler.received_command_data for handler in
                self.connections)
        return all_received_data.split('\0')

class SocketHandler(threading.Thread):
    def __init__(self, connection, address):
        super(SocketHandler, self).__init__()
        self.daemon = True
        self.connection = connection
        self.address = address
        self.received_command_data = ""

    def send(self, data):
        self.connection.sendall(data)

    def run(self):
        while True:
            data = self.connection.recv(1024)
            if not data:
                break
            else:
                self.received_command_data += data.decode()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import cv2
import helpers
import binarydetector
import numpy as np
from enum import IntEnum

class BinarizationMethod(IntEnum):
    datadriven = 0
    otsu = 1
    levels = 2
    threshold = 3

def get_salient_regions_gray(img,
                             find_holes=True, find_islands=True,
                             find_indentations=True, find_protrusions=True,
                             SE_size_factor=0.15, area_factor=0.05,
                             connectivity=4,
                             binarizationmethod=BinarizationMethod.datadriven,
                             threshold=-1,
                             visualize=True):
    '''
    Find salient regions of all four types

    Parameters:
    ------
    img: 2-dimensional numpy array with values between 0 and 255
        grayscale image to detect regions
    find_holes: bool, optional
        Whether to detect regions of type hole
    find_islands: bool, optional
        Whether to detect regions of type island
    find_indentations: bool, optional
        Whether to detect regions of type indentation
    find_protrusions: bool, optional
        Whether to detect regions of type protrusion
    SE_size_factor: float, optional
        The fraction of the image size that the structuring element should be
    area_factor: float, optional
        factor that describes the minimum area of a significent CC
    connectivity: int
        What connectivity to use to define CCs
    binarizationmethod: BinarizationMethod (enum)
        Which method to use for binarizing.
    threshold
        Which threshold to use if binarizationmethod is ´levels´
    visualize: bool, optional
        option for vizualizing the process

    Returns:
    ------
    dictiornary with the following possible items:
    holes: 2-dimensional numpy array with values 0/255
        Image with all holes as foreground.
    islands: 2-dimensional numpy array with values 0/255
        Image with all islands as foreground.
    indentations: 2-dimensional numpy array with values 0/255
        Image with all indentations as foreground.
    protrusions: 2-dimensional numpy array with values 0/255
        Image with all protrusions as foreground.
    '''
    SE, lam = helpers.get_SE(img, SE_size_factor=SE_size_factor)
    if binarizationmethod == BinarizationMethod.datadriven:
        _, binarized = helpers.data_driven_binarization(img, lam=lam,
                                                        connectivity=connectivity,
                                                        visualize=visualize)
    elif binarizationmethod == BinarizationMethod.otsu:
        _, binarized = helpers.data_driven_binarization(img, lam=lam,
                                                        connectivity=connectivity,
                                                        otsu_only=True,
                                                        visualize=visualize)
    else:
        binarized = helpers.binarize(img,
                                     threshold=threshold, visualize=visualize)

    result = binarydetector.get_salient_regions(binarized,
                                                find_holes,
                                                find_islands,
                                                find_indentations,
                                                find_protrusions,
                                                SE_size_factor,
                                                area_factor,
                                                connectivity,
                                                visualize)
    return result

def get_salient_regions_color(img,
                              find_holes=True, find_islands=True,
                              find_indentations=True, find_protrusions=True,
                              SE_size_factor=0.15, area_factor=0.05,
                              connectivity=4,
                              binarizationmethod=BinarizationMethod.datadriven,
                              threshold=-1,
                              visualize=True):
    '''
    Find salient regions of all four types

    Parameters:
    ------
    img: 3-dimensional numpy array with values between 0 and 255
        image to detect regions
    find_holes: bool, optional
        Whether to detect regions of type hole
    find_islands: bool, optional
        Whether to detect regions of type island
    find_indentations: bool, optional
        Whether to detect regions of type indentation
    find_protrusions: bool, optional
        Whether to detect regions of type protrusion
    SE_size_factor: float, optional
        The fraction of the image size that the structuring element should be
    area_factor: float, optional
        factor that describes the minimum area of a significent CC
    connectivity: int
        What connectivity to use to define CCs
    binarizationmethod: BinarizationMethod (enum)
        Which method to use for binarizing.
    threshold
        Which threshold to use if binarizationmethod is ´levels´
    visualize: bool, optional
        option for vizualizing the process

    Returns:
    ------
    dictiornary with the following possible items:
    holes: 2-dimensional numpy array with values 0/255
        Image with all holes as foreground.
    islands: 2-dimensional numpy array with values 0/255
        Image with all islands as foreground.
    indentations: 2-dimensional numpy array with values 0/255
        Image with all indentations as foreground.
    protrusions: 2-dimensional numpy array with values 0/255
        Image with all protrusions as foreground.
    '''

    # Make grayscale image
    grayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    return get_salient_regions_gray(grayscale,
                                    find_holes=find_holes,
                                    find_islands=find_islands,
                                    find_indentations=find_indentations,
                                    find_protrusions=find_protrusions,
                                    SE_size_factor=SE_size_factor,
                                    area_factor=area_factor,
                                    connectivity=connectivity,
                                    binarizationmethod=binarizationmethod,
                                    threshold=threshold,
                                    visualize=visualize)
<commit_msg>comented out line<commit_after># -*- coding: utf-8 -*-
import cv2
import helpers
import binarydetector
#import numpy as np
from enum import IntEnum

class BinarizationMethod(IntEnum):
    datadriven = 0
    otsu = 1
    levels = 2
    threshold = 3

def get_salient_regions_gray(img,
                             find_holes=True, find_islands=True,
                             find_indentations=True, find_protrusions=True,
                             SE_size_factor=0.15, area_factor=0.05,
                             connectivity=4,
                             binarizationmethod=BinarizationMethod.datadriven,
                             threshold=-1,
                             visualize=True):
    '''
    Find salient regions of all four types

    Parameters:
    ------
    img: 2-dimensional numpy array with values between 0 and 255
        grayscale image to detect regions
    find_holes: bool, optional
        Whether to detect regions of type hole
    find_islands: bool, optional
        Whether to detect regions of type island
    find_indentations: bool, optional
        Whether to detect regions of type indentation
    find_protrusions: bool, optional
        Whether to detect regions of type protrusion
    SE_size_factor: float, optional
        The fraction of the image size that the structuring element should be
    area_factor: float, optional
        factor that describes the minimum area of a significent CC
    connectivity: int
        What connectivity to use to define CCs
    binarizationmethod: BinarizationMethod (enum)
        Which method to use for binarizing.
    threshold
        Which threshold to use if binarizationmethod is ´levels´
    visualize: bool, optional
        option for vizualizing the process

    Returns:
    ------
    dictiornary with the following possible items:
    holes: 2-dimensional numpy array with values 0/255
        Image with all holes as foreground.
    islands: 2-dimensional numpy array with values 0/255
        Image with all islands as foreground.
    indentations: 2-dimensional numpy array with values 0/255
        Image with all indentations as foreground.
    protrusions: 2-dimensional numpy array with values 0/255
        Image with all protrusions as foreground.
    '''
    SE, lam = helpers.get_SE(img, SE_size_factor=SE_size_factor)
    if binarizationmethod == BinarizationMethod.datadriven:
        _, binarized = helpers.data_driven_binarization(img, lam=lam,
                                                        connectivity=connectivity,
                                                        visualize=visualize)
    elif binarizationmethod == BinarizationMethod.otsu:
        _, binarized = helpers.data_driven_binarization(img, lam=lam,
                                                        connectivity=connectivity,
                                                        otsu_only=True,
                                                        visualize=visualize)
    else:
        binarized = helpers.binarize(img,
                                     threshold=threshold, visualize=visualize)

    result = binarydetector.get_salient_regions(binarized,
                                                find_holes,
                                                find_islands,
                                                find_indentations,
                                                find_protrusions,
                                                SE_size_factor,
                                                area_factor,
                                                connectivity,
                                                visualize)
    return result

def get_salient_regions_color(img,
                              find_holes=True, find_islands=True,
                              find_indentations=True, find_protrusions=True,
                              SE_size_factor=0.15, area_factor=0.05,
                              connectivity=4,
                              binarizationmethod=BinarizationMethod.datadriven,
                              threshold=-1,
                              visualize=True):
    '''
    Find salient regions of all four types

    Parameters:
    ------
    img: 3-dimensional numpy array with values between 0 and 255
        image to detect regions
    find_holes: bool, optional
        Whether to detect regions of type hole
    find_islands: bool, optional
        Whether to detect regions of type island
    find_indentations: bool, optional
        Whether to detect regions of type indentation
    find_protrusions: bool, optional
        Whether to detect regions of type protrusion
    SE_size_factor: float, optional
        The fraction of the image size that the structuring element should be
    area_factor: float, optional
        factor that describes the minimum area of a significent CC
    connectivity: int
        What connectivity to use to define CCs
    binarizationmethod: BinarizationMethod (enum)
        Which method to use for binarizing.
    threshold
        Which threshold to use if binarizationmethod is ´levels´
    visualize: bool, optional
        option for vizualizing the process

    Returns:
    ------
    dictiornary with the following possible items:
    holes: 2-dimensional numpy array with values 0/255
        Image with all holes as foreground.
    islands: 2-dimensional numpy array with values 0/255
        Image with all islands as foreground.
    indentations: 2-dimensional numpy array with values 0/255
        Image with all indentations as foreground.
    protrusions: 2-dimensional numpy array with values 0/255
        Image with all protrusions as foreground.
    '''

    # Make grayscale image
    grayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    return get_salient_regions_gray(grayscale,
                                    find_holes=find_holes,
                                    find_islands=find_islands,
                                    find_indentations=find_indentations,
                                    find_protrusions=find_protrusions,
                                    SE_size_factor=SE_size_factor,
                                    area_factor=area_factor,
                                    connectivity=connectivity,
                                    binarizationmethod=binarizationmethod,
                                    threshold=threshold,
                                    visualize=visualize)
<|endoftext|>


<commit_before># encoding: utf-8

from datetime import datetime

__author__ = "Tsuyoshi Hombashi"
__copyright__ = "Copyright {}, {}".format(datetime.now().year, __author__)
__license__ = "MIT License"
__version__ = "0.2.1"
__maintainer__ = __author__
__email__ = "tsuyoshi.hombashi@gmail.com"
<commit_msg>Bump version<commit_after># encoding: utf-8

from datetime import datetime

__author__ = "Tsuyoshi Hombashi"
__copyright__ = "Copyright {}, {}".format(datetime.now().year, __author__)
__license__ = "MIT License"
__version__ = "0.2.2"
__maintainer__ = __author__
__email__ = "tsuyoshi.hombashi@gmail.com"
<|endoftext|>


<commit_before>import scipy.constants
import argparse
import decimal
from bokeh.plotting import figure, output_file, show
decimal.getcontext().prec = 1000

phi = scipy.constants.golden

parser = argparse.ArgumentParser(description="A visual display of the Fibonacci sequence.")
parser.add_argument("integer", type = int, help = "Type in the number of Fibonacci terms to be shown.")
args = parser.parse_args()

#implementing Binet's formula to produce the Nth term
def nth_term(term):
    return int(round((phi**term - (1 - phi)**term) / 5**0.5))

#produces a list of the first N Fibonacci terms
def fib_list(term):
    fib_list = [0, 1]
    for i in range(2, term + 1):
        fib_list.append(fib_list[i - 1] + fib_list[i - 2])
    return fib_list

#produces a list of the first N prime numbers
def prime_list(term):
    prime_list = [2]
    number = 3

    while len(prime_list) < term + 1:
        counter = 0
        for n in range(2, number):
            if number % n == 0:
                counter += 1
            else:
                counter += 0
        if counter == 0:
            prime_list.append(number)
        number += 1
    return prime_list

# check how many digits quotient of last 2 terms matches phi out to
def phi_match(term):
    phi1000list = []
    phi_dec_list = []
    with open('phi1000.txt', 'r') as phi:
        phi1000 = phi.read()
        phi_dec = str(decimal.Decimal(nth_term(term)) / decimal.Decimal(nth_term(term - 1)))

        for char in phi1000:
            phi1000list.append(char)

        for char in phi_dec:
            phi_dec_list.append(char)

    for i in range(1001):
        if(phi1000list[i] == phi_dec_list[i]):
            i += 1
        else:
            break

    return i - 1

#data for graph
x = range(args.integer + 1)
y = fib_list(args.integer)
y1 = prime_list(args.integer)

#output to static HTML file
output_file("lines.html", title="Growth of Fibonacci Sequence")

# creating a new plot with title and axis labels
p = figure(title="Growth of Fibonacci Sequence vs. Prime numbers", x_axis_label='Term number', y_axis_label='Value')

#add a line renderer with legend and line thickness
p.line(x, y, legend="Fibonacci terms", line_width=2, line_color="red")
p.line(x, y1, legend="Prime number terms", line_width=3, line_color="blue", line_dash="4 4")

#show results
show(p)

print ""
print "The number {0} term in the Fibonacci sequence is {1}.".format(int(args.integer), nth_term(args.integer))
print ""
print "The first terms of the Fibonacci sequence out to term {} are:".format(int(args.integer))
print fib_list(args.integer)
print "The first terms of prime numbers out to term {} are:".format(int(args.integer))
print prime_list(args.integer)
print ""
print "The value of the quotient of the last two terms in the sequence is: {}".format(float(y[args.integer]) / float(y[args.integer - 1]))
print "The true value of phi is: {}".format(phi)
print ""
print "The quotient of the last two terms of the sequence match the true value of phi out to {} digits.".format(phi_match(args.integer))
<commit_msg>split functions into separate directory<commit_after>import scipy.constants
import argparse
import decimal
from bokeh.plotting import figure, output_file, show
from fib_math.functions import nth_term, fib_list, prime_list, phi_match
decimal.getcontext().prec = 1000

phi = scipy.constants.golden

parser = argparse.ArgumentParser(description="A visual display of the Fibonacci sequence.")
parser.add_argument("integer", type = int, help = "Type in the number of Fibonacci terms to be shown.")
args = parser.parse_args()

#data for graph
x = range(args.integer + 1)
y = fib_list(args.integer)
y1 = prime_list(args.integer)

#output to static HTML file
output_file("lines.html", title="Growth of Fibonacci Sequence")

# creating a new plot with title and axis labels
p = figure(title="Growth of Fibonacci Sequence vs. Prime numbers", x_axis_label='Term number', y_axis_label='Value')

#add a line renderer with legend and line thickness
p.line(x, y, legend="Fibonacci terms", line_width=2, line_color="red")
p.line(x, y1, legend="Prime number terms", line_width=3, line_color="blue", line_dash="4 4")

#show results
show(p)

'''
can use python's map function to produce a list of terms for phi_match function
'''

print ""
print "The number {0} term in the Fibonacci sequence is {1}.".format(int(args.integer), nth_term(args.integer))
print ""
print "The first terms of the Fibonacci sequence out to term {} are:".format(int(args.integer))
print fib_list(args.integer)
print "The first terms of prime numbers out to term {} are:".format(int(args.integer))
print prime_list(args.integer)
print ""
print "The value of the quotient of the last two terms in the sequence is: {}".format(float(y[args.integer]) / float(y[args.integer - 1]))
print "The true value of phi is: {}".format(phi)
print ""
print "The quotient of the last two terms of the sequence match the true value of phi out to {} digits.".format(phi_match(args.integer))
<|endoftext|>