Exemple #1
0
class Relay(flx.Component):

    number_of_connections = flx.IntProp(settable=True)

    def init(self):
        self.update_number_of_connections()
        self.refresh()

    @flx.manager.reaction('connections_changed')
    def update_number_of_connections(self, *events):
        n = 0
        for name in flx.manager.get_app_names():
            sessions = flx.manager.get_connections(name)
            n += len(sessions)
        self.set_number_of_connections(n)

    @flx.emitter
    def system_info(self):
        return dict(cpu=psutil.cpu_percent(),
                    mem=psutil.virtual_memory().percent,
                    sessions=self.number_of_connections,
                    total_sessions=flx.manager.total_sessions,
                    )

    def refresh(self):
        self.system_info()
        asyncio.get_event_loop().call_later(1, self.refresh)
Exemple #2
0
class Example(flx.Widget):

    counter = flx.IntProp(3, settable=True)

    def init(self):
        super().init()

        with flx.HBox():
            self.but1 = flx.Button(text='reset')
            self.but2 = flx.Button(text='increase')
            self.label = flx.Label(text='', flex=1)  # take all remaining space

    @flx.action
    def increase(self):
        self._mutate_counter(self.counter + 1)

    @flx.reaction('but1.pointer_click')
    def but1_clicked(self, *events):
        self.set_counter(0)

    @flx.reaction('but2.pointer_click')
    def but2_clicked(self, *events):
        self.increase(0)

    @flx.reaction
    def update_label(self, *events):
        self.label.set_text('count is ' + str(self.counter))
class Web(flx.Widget):
    name = flx.StringProp('John Doe', settable=True)
    age = flx.IntProp(22, settable=True)

    @flx.action
    def increase_age(self):
        self._mutate_age(self.age + 1)

    def _create_dom(self):
        # Use this method to create a root element for this widget.
        # If you just want a <div> you don't have to implement this.
        return flx.create_element('div')  # the default is <div>

    def _render_dom(self):
        # Use this to determine the content. This method may return a
        # string, a list of virtual nodes, or a single virtual node
        # (which must match the type produced in _create_dom()).
        return [
            flx.create_element('span', {}, 'Hello',
                               flx.create_element('b', {}, self.name), '! '),
            flx.create_element(
                'span', {},
                'I happen to know that your age is %i.' % self.age),
            flx.create_element('br'),
            flx.create_element('button', {'onclick': self.increase_age},
                               'Next year ...')
        ]
Exemple #4
0
class Relay(flx.Component):

    number_of_connections = flx.IntProp(settable=True)

    def init(self):
        self.update_number_of_connections()

        self.current_idx = 0

        if platform.system() == 'Windows':
            directories = glob.glob(r'Y:\log_pool\*')
            self.ROOT_PATH = r'Y:\log_pool'
        else:
            directories = glob.glob(
                r'/Users/xiaoprime/Documents/GitHub/Q-learning-NW-SRCH/Simulator/log_pool/*'
            )
            self.ROOT_PATH = r'/Users/xiaoprime/Documents/GitHub/Q-learning-NW-SRCH/Simulator/log_pool'

        time.sleep(1)

        directories = sorted(list(
            filter(lambda f: os.path.isdir(f), directories)),
                             reverse=True)
        #self.stock_list = list(enumerate(directories, start=1))
        self.stock_list = [
            x.split('\\' if platform.system() == 'Windows' else '/')[-1]
            for x in directories
        ]
        #self.refresh()

    @flx.manager.reaction('connections_changed')
    def update_number_of_connections(self, *events):
        n = 0
        for name in flx.manager.get_app_names():
            sessions = flx.manager.get_connections(name)
            n += len(sessions)
        self.set_number_of_connections(n)

    @flx.emitter
    def system_info(self, dat, stockname, otherseries=None):
        dat = dat.to_dict('split')
        dat['label'] = [str(x).split(' ')[0] for x in dat['index']]
        dat['index'] = list(date2num(dat['index']))

        dat['rec'] = {}
        dat['min'] = {}
        dat['max'] = {}
        dat['min']['index'] = np.nanmin(dat['index'])
        dat['max']['index'] = np.nanmax(dat['index'])
        for idx, tp in zip(range(len(dat['columns'])), dat['columns']):
            dat['rec'][tp] = [x[idx] for x in dat['data']]
            dat['min'][tp] = np.nanmin(dat['rec'][tp])
            dat['max'][tp] = np.nanmax(dat['rec'][tp])
        del dat['data']

        return dict(dat=dat,
                    stockname=stockname,
                    otherseries=otherseries,
                    sessions=self.number_of_connections,
                    total_sessions=flx.manager.total_sessions)
Exemple #5
0
class Relay(flx.Component):
    number_of_connections = flx.IntProp(settable=True)
    
    def init(self):
        self.update_number_of_connections()

    @flx.manager.reaction('connections_changed')
    def update_number_of_connections(self, *events):
        n = 0
        for name in flx.manager.get_app_names():
            sessions = flx.manager.get_connections(name)
            n += len(sessions)
        self.set_number_of_connections(n)

    @flx.emitter
    def new_data(self, serial_data):
        return dict(serial_data=serial_data,
                    sessions=self.number_of_connections,
                    total_sessions=flx.manager.total_sessions)
Exemple #6
0
class ReticoModule(flx.Widget):

    p_left = flx.IntProp(settable=True)
    p_top = flx.IntProp(settable=True)
    p_width = flx.IntProp(settable=True)
    p_height = flx.IntProp(settable=True)

    active = flx.BoolProp(settable=True)

    def init(self, retico_widget):
        self.retico_widget = retico_widget
        self.l_title = flx.Label(text="", css_class="title-label")
        self.close_button = flx.Button(text="X", css_class="close-button")
        with flx.VBox(
                style=
                "cursor: default; padding-bottom: 30px; padding-left: 20px; padding-right:20px; padding-top: 30px;"
        ) as self.content_box:
            self.content_box.set_padding("20px")
        self.out_button_l = flx.Button(text="◀",
                                       css_class="out-button left-button")
        self.out_button_r = flx.Button(text="▶",
                                       css_class="out-button right-button")
        self.in_button_l = flx.Button(text="▶",
                                      css_class="in-button left-button")
        self.in_button_r = flx.Button(text="◀",
                                      css_class="in-button right-button")
        self.enable_button = flx.Button(text="enabled",
                                        css_class="enable-button")
        self.trigger_edit = flx.LineEdit(self.content_box)
        self.trigger_button = flx.Button(parent=self.content_box,
                                         text="Trigger")
        self.trigger_edit.set_parent(None)
        self.trigger_button.set_parent(None)
        self.trigger_button.set_disabled(True)
        self.set_active(True)
        self.set_position()

    def set_position(self):
        rect = self.node.getBoundingClientRect()
        mpane = self.retico_widget.mpane.node

        self.set_p_left(rect.left + mpane.scrollLeft)
        self.set_p_top(rect.top + mpane.scrollTop)
        self.set_p_width(rect.width)
        self.set_p_height(rect.height)

        window.setTimeout(self.set_position, 100)

    @flx.action
    def clear_content(self):
        for child in self.content_box.children:
            child.set_parent(None)
            child.dispose()

    @flx.action
    def add_info(self, text):
        style = "font-size: 10pt; text-align: center;"
        lbl = flx.Label(style=style, parent=self.content_box)
        lbl.set_html(text)

    @flx.action
    def update_info(self, text):
        style = "font-size: 10pt; text-align: center;"
        if len(self.content_box.children) > 1:
            self.clear_content()
            flx.Label(style=style, parent=self.content_box)
        self.content_box.children[0].set_html(text)

    @flx.action
    def create_trigger(self):
        self.trigger_edit.set_parent(self.content_box)
        self.trigger_button.set_parent(self.content_box)

    @flx.reaction("trigger_button.pointer_click")
    def trigger_clicked(self):
        params_txt = self.trigger_edit.text
        print("TRIGGER CLICKED!", str(params_txt))
        self.retico_widget.model.handle_trigger(self, params_txt)

    # @flx.action
    # def set_content(self, content_list):
    #     for child in self.content_box.children:
    #         child.set_parent(None)
    #         child.dispose()
    #     for element in content_list:
    #         element.set_parent(self.content_box)

    @flx.action
    def disable_input_buttons(self):
        self.in_button_l.set_disabled(True)
        self.in_button_r.set_disabled(True)

    @flx.action
    def disable_output_buttons(self):
        self.out_button_l.set_disabled(True)
        self.out_button_r.set_disabled(True)

    @flx.action
    def enable_input_buttons(self):
        self.in_button_l.set_disabled(False)
        self.in_button_r.set_disabled(False)

    @flx.action
    def enable_output_buttons(self):
        self.out_button_l.set_disabled(False)
        self.out_button_r.set_disabled(False)

    @flx.action
    def enable_close_button(self):
        self.close_button.set_disabled(False)
        self.trigger_button.set_disabled(True)

    @flx.action
    def disable_close_button(self):
        self.close_button.set_disabled(True)
        self.trigger_button.set_disabled(False)

    @flx.action
    def highlight(self, active, color="#ffd"):
        self.node.style["box-shadow"] = None
        if active:
            if color == "border":
                self.node.style[
                    "box-shadow"] = "rgba(255, 255, 255, 0.6) 0px 0px 20px"
            elif color == "red-border":
                self.node.style[
                    "box-shadow"] = "rgba(255, 0, 0, 0.6) 0px 0px 20px"
            else:
                self.node.style["background-color"] = color
        else:
            self.node.style["background-color"] = "#fff"

    @flx.reaction("out_button_l.pointer_click", "out_button_r.pointer_click")
    def out_button_click(self):
        if not self.retico_widget.model.connecting_state:
            self.retico_widget.model.init_out_click(self)
        else:
            self.retico_widget.model.connect_to(self)

    @flx.reaction("in_button_l.pointer_click", "in_button_r.pointer_click")
    def in_button_click(self):
        if not self.retico_widget.model.connecting_state:
            self.retico_widget.model.init_in_click(self)
        else:
            self.retico_widget.model.connect_to(self)

    @flx.reaction("close_button.pointer_click")
    def _close(self):
        self.retico_widget.model.delete_module(self)

    @flx.reaction("enable_button.pointer_click")
    def enable_button_click(self):
        self.retico_widget.model.toggle_module(self)

    @flx.action
    def set_mtitle(self, thing):
        self.l_title.set_text(thing)

    def in_pos(self):
        rect = self.node.getBoundingClientRect()
        mp_node = self.retico_widget.mpane.node
        return (
            rect.left + (rect.width / 2) + mp_node.scrollLeft,
            rect.bottom - 13 + mp_node.scrollTop,
        )

    def out_pos(self):
        rect = self.node.getBoundingClientRect()
        mp_node = self.retico_widget.mpane.node
        return (
            rect.left + (rect.width / 2) + mp_node.scrollLeft,
            rect.top + 45 + mp_node.scrollTop,
        )

    @flx.action
    def setup(self):
        self.disable_input_buttons()
        self.disable_output_buttons()
        self.disable_close_button()
        self.highlight(True, "red-border")

    @flx.action
    def stop(self):
        self.enable_close_button()
        self.highlight(False)

    @flx.action
    def display_active(self):
        if self.active:
            self.node.style["opacity"] = 1
            self.enable_button.set_text("enabled")
        else:
            self.node.style["opacity"] = 0.1
            self.enable_button.set_text("disabled")
class SlowControlGUI(flx.PyComponent):
    led = flx.IntProp(0, settable=True)
    hv = flx.IntProp(0, settable=True)
    vsel = flx.IntProp(0, settable=True)

    chillerStat = flx.IntProp(0, settable=True)
    chillerSwitch = flx.IntProp(0, settable=True)
    tempchiller = flx.FloatProp(0, settable=True)
    tempbench = flx.FloatProp(0, settable=True)
    tempext = flx.FloatProp(0, settable=True)
    humbench = flx.FloatProp(0, settable=True)
    humext = flx.FloatProp(0, settable=True)

#    sercon =  flx.ComponentProp()
#   serconChiller =  flx.ComponentProp()
#    serconSensirion =  flx.ComponentProp()
#    ledcon =  flx.ComponentProp()

    initialised = 0

    def init(self):
        super().init()
        #        self._mutate_sercon(SerialConnection('/dev/ttyACM1'))
        self.sercon = SerialConnection('/dev/sensor_0')
        #        self._mutate_serconChiller(SerialConnectionChiller('/dev/ttyUSB0'))
        self.serconChiller = SerialConnectionChiller('/dev/ttyUSB0')
        #        self._mutate_serconSensirion(SerialConnectionSensirion('/dev/ttyACM0'))
        self.serconSensirion = SerialConnectionSensirion('/dev/sensor_1') 
        #        self._mutate_ledcon(LedPulser())
        self.ledcon = LedPulser() 
        self.hvcon = SerialConnectionHV('/dev/ttyUSB4')

        self.t0 = datetime.now()
        #Always start in inhbit mode
        reply=self.sercon.sendCommand('i')
        if (reply!='INH'):
            print('Please check serial connection')

        reply=self.sercon.sendCommand('0')
        if (reply!='V0'):
            print('Please check serial connection')

        ret=self.ledcon.ledSwitch(0)
        if (ret!=0):
            print('Please check led pulser connection')

#        with flx.HBox(flex=0, spacing=10):

        with flx.PinboardLayout():
            self.tempText = flx.Label(text='T: XX.XX H: YY.YY',style='left:10px; top:120px; width:300px;height:20px;')
            self.sensirionText = flx.Label(text='T_EXT:XXX.XX H_EXT:YYY.YY DEW_EXT:ZZZ.ZZ',style='left:10px; top:140px; width:400px;height:20px;')
            self.hvText = flx.Label(text='VSET:XXX.XX VMON:XXX.XX',style='left:10px; top:180px; width:300px;height:20px;')
            self.chillerText = flx.Label(text='CHILLER TBATH:XXX.XX TSET:YYY.YY PUMP:ZZ',style='left:10px; top:160px; width:400px;height:20px;')
            self.but1 = flx.Button(text='Led Pulser',css_class="border-black",style='left:10px; top:10px; width:180px;height:100px;')
            self.but2 = flx.Button(text='HV',css_class="border-black",style='left:200px; top:10px; width:150px;height:100px;')
            self.but3 = flx.Button(text='VSEL',css_class="border-black",style='left:360px; top:10px; width:100px;height:100px;')
            self.chillerStatus = flx.Button(text='COOLING OK',css_class="border-black",style='left:470px; top:10px; width:250px;height:100px;')
#            self.label = flx.Label(text='', flex=1)  # take all remaining space

        self.refreshTemperature()
        self.refreshChiller()
        self.refreshSensirion()
        self.refreshHV()
#upload to things speak (every 60s)
        self.refreshThingSpeak()

        self.initialised=1

    @flx.action
    def refreshTemperature(self):
        if (self.initialised != 0):
            reply=self.sercon.sendCommand('t')
            self.tempText.set_text(reply)
            logging.info(reply)
            temp=reply.split(' ')[1]
            self._mutate_tempbench(temp)
            hum=reply.split(' ')[3]
            self._mutate_humbench(hum)
        asyncio.get_event_loop().call_later(5, self.refreshTemperature)

    @flx.action
    def refreshSensirion(self):
        if (self.initialised != 0):
            reply=self.serconSensirion.sendCommand('t')
            if (len(reply.split(' ')) == 10):
                temp=reply.split(' ')[1]
                self._mutate_tempext(temp)
                hum=reply.split(' ')[7]
                self._mutate_humext(hum)
                dew=reply.split(' ')[9]
                self.sensirionText.set_text('T_EXT:'+temp+' H_EXT:'+hum+' DEW_EXT:'+dew)
                logging.info('T_EXT:'+temp+' H_EXT:'+hum+' DEW_EXT:'+dew)

        asyncio.get_event_loop().call_later(6, self.refreshSensirion)

    @flx.action
    def refreshHV(self):
        if (self.initialised != 0):
           vmon=self.hvcon.sendCommand('m')
           vset=self.hvcon.sendCommand('s')
           stat=self.hvcon.sendCommand('i')
           self.hvText.set_text('VSET:'+vset+' VMON:'+vmon)
           logging.info('VSET:'+vset+' VMON:'+vmon+' STATUS:'+stat)
           if ( (int(stat) & 1) == 1):
               self._mutate_hv(1)
           elif ( (int(stat) & 1) == 0):
               self._mutate_hv(0)
        asyncio.get_event_loop().call_later(7, self.refreshHV)

    @flx.action
    def refreshChiller(self):
        try:
            if (self.initialised != 0):
                tbath=self.serconChiller.sendCommand('t')
                #            print(tbath)
                tset=self.serconChiller.sendCommand('g')
                pump=self.serconChiller.sendCommand('p')
                status=self.serconChiller.sendCommand('s')
                self.chillerText.set_text('CHILLER TBATH:'+tbath+' TSET:'+tset+' PUMP:'+pump)

                if (pump== '000.00' and status == '0'):
                    self.chillerStatus.set_text('COOLING OFF')
                    self.chillerStatus.apply_style('background:yellow;')
                    self._mutate_chillerSwitch(0)
                elif (status == '0' and pump== '003.00'):
                    self.chillerStatus.set_text('COOLING OK')
                    self.chillerStatus.apply_style('background:green;')
                    self._mutate_chillerStat(1)
                    self._mutate_chillerSwitch(1)
                else:
                    self.chillerStatus.set_text('COOLING KO')
                    self.chillerStatus.apply_style('background:red;')
                    self._mutate_chillerStat(0)

                if not 'ERR' in tbath: 
                    self._mutate_tempchiller(float(tbath))

                logging.info('CHILLER TBATH: '+tbath+' STATUS: '+status+' TSET:'+tset+' PUMP:'+pump)
        except:
                logging.info('Got an exception')

        asyncio.get_event_loop().call_later(10, self.refreshChiller)

    def refreshThingSpeak(self):
        if (self.initialised != 0):
            params = {'field1': self.tempbench, 'field2': self.humbench, 'field3': self.tempchiller, 'field4': self.chillerStat, 'field5': self.tempext, 'field6': self.humext, 'key': thingspeak_key}
            logThingSpeak(params)

        asyncio.get_event_loop().call_later(60, self.refreshThingSpeak)

    @flx.action
    def hv_switch(self):
        if (self.hv==0):
            reply=self.hvcon.sendCommand('o')
            if (reply=='OK'):
                self._mutate_hv(1)
        elif (self.hv==1):
            reply=self.hvcon.sendCommand('k')
            if (reply=='OK'):
                self._mutate_hv(0)

    @flx.action
    def led_switch(self):
        if (self.led==0):
            ret=self.ledcon.ledSwitch(1)
            if (ret==0):
                self._mutate_led(1)
        elif (self.led==1):
            ret=self.ledcon.ledSwitch(0)
            if (ret==0):
                self._mutate_led(0)

    @flx.action
    def chiller_switch(self):
        if (self.chillerSwitch==0):
            reply=self.serconChiller.sendCommand('o')
            if (reply=='OK'):
                self._mutate_chillerSwitch(1)
        elif (self.chillerSwitch==1):
            reply=self.serconChiller.sendCommand('k')
            if (reply=='OK'):
                self._mutate_chillerSwitch(0)
        
    @flx.action
    def vsel_switch(self):
        if (self.vsel==0):
            reply=self.sercon.sendCommand('1')
            if (reply=='V1'):
                self._mutate_vsel(1)
        elif (self.vsel==1):
            reply=self.sercon.sendCommand('0')
            if (reply=='V0'):
                self._mutate_vsel(0)

    @flx.reaction('but1.pointer_click')
    def but1_clicked(self, *events):
        self.led_switch()

    @flx.reaction('but2.pointer_click')
    def but2_clicked(self, *events):
        self.hv_switch()

    @flx.reaction('but3.pointer_click')
    def but3_clicked(self, *events):
        self.vsel_switch()

    @flx.reaction('chillerStatus.pointer_click')
    def chillerButton_clicked(self, *events):
        self.chiller_switch()

#    @flx.reaction
#    def update_label(self, *events):
 
    @flx.reaction
    def update_buttons(self, *events):
        if (self.hv==1):
            self.but2.set_text('HV ON')
            self.but2.apply_style('background:red;')
        if (self.hv==0):
            self.but2.set_text('HV OFF')
            self.but2.apply_style('background:yellow;')
        if (self.led==1):
            self.but1.set_text('LED ON')
            self.but1.apply_style('background:red;')
        if (self.led==0):
            self.but1.set_text('LED OFF')
            self.but1.apply_style('background:yellow;')
        if (self.chillerSwitch==0):
            self.chillerStatus.set_text('COOLING OFF')
            self.chillerStatus.apply_style('background:yellow;')
        if (self.chillerSwitch==1 and self.chillerStat==0):
            self.chillerStatus.set_text('COOLING ON')
            self.chillerStatus.apply_style('background:orange;')
        if (self.chillerSwitch==1 and self.chillerStat==1):
            self.chillerStatus.set_text('COOLING OK')
            self.chillerStatus.apply_style('background:green;')
        if (self.vsel==1):
            self.but3.set_text('V1')
        if (self.vsel==0):
            self.but3.set_text('V0')
Exemple #8
0
class Run(flx.PyWidget):
    exterior_wall_tuple = flx.TupleProp((1, 10), settable=True)
    exterior_roof_tuple = flx.TupleProp((1, 9), settable=True)
    exterior_window_tuple = flx.TupleProp((1, 3), settable=True)
    eastrate_tuple = flx.TupleProp((0.05, 0.3), settable=True)
    westrate_tuple = flx.TupleProp((0.05, 0.3), settable=True)
    southrate_tuple = flx.TupleProp((0.05, 0.3), settable=True)
    northrate_tuple = flx.TupleProp((0.05, 0.3), settable=True)
    direction_tuple = flx.TupleProp((0, 359), settable=True)
    airchange_tuple = flx.TupleProp((0, 39), settable=True)
    cop_tuple = flx.TupleProp((1, 4), settable=True)
    east_shading_tuple = flx.TupleProp((0, 1), settable=True)
    west_shading_tuple = flx.TupleProp((0, 1), settable=True)
    south_shading_tuple = flx.TupleProp((0, 1), settable=True)
    north_shading_tuple = flx.TupleProp((0, 1), settable=True)
    infiltration_airchange_tuple = flx.TupleProp((1, 3), settable=True)

    mutation_param_int = flx.IntProp(4, settable=True)
    num_of_generation_int = flx.IntProp(50, settable=True)
    num_of_individual_int = flx.IntProp(50, settable=True)
    num_of_tour_particps_int = flx.IntProp(2, settable=True)
    max_proc_int = flx.IntProp(8, settable=True)

    floor_height_float = flx.FloatProp(2.8, settable=True)
    window_height_float = flx.FloatProp(1.5, settable=True)
    window_edge_height_float = flx.FloatProp(1, settable=True)
    heating_setpoint_float = flx.FloatProp(18, settable=True)
    cooling_setpoint_float = flx.FloatProp(26, settable=True)
    apmv_upper_float = flx.FloatProp(0.5, settable=True)
    apmv_lower_float = flx.FloatProp(-0.5, settable=True)

    weather_file_str = flx.StringProp(
        '../WeatherData/CHN_Chongqing.Chongqing.Shapingba.575160_CSWD.epw',
        settable=True)
    idf_file_str = flx.StringProp('shading_model_6-0603-1.idf', settable=True)
    output_path_str = flx.StringProp('temp/', settable=True)

    def init(self):
        self.moo = MooWidget(self)

    @flx.action
    def run_moo(self):
        # the actual range used by the algorithm is set here.
        paras = [
            discrete_interval(tuple(self.moo.root.exterior_wall_tuple)),
            discrete_interval(tuple(self.moo.root.exterior_roof_tuple)),
            discrete_interval(tuple(self.moo.root.exterior_window_tuple)),
            tuple(self.moo.root.eastrate_tuple),
            tuple(self.moo.root.westrate_tuple),
            tuple(self.moo.root.southrate_tuple),
            tuple(self.moo.root.northrate_tuple),
            tuple(self.moo.root.direction_tuple),
            tuple(self.moo.root.airchange_tuple),
            discrete_interval(tuple(self.moo.root.cop_tuple)),
            discrete_interval(tuple(self.moo.root.east_shading_tuple)),
            discrete_interval(tuple(self.moo.root.west_shading_tuple)),
            discrete_interval(tuple(self.moo.root.south_shading_tuple)),
            discrete_interval(tuple(self.moo.root.north_shading_tuple)),
            discrete_interval(tuple(
                self.moo.root.infiltration_airchange_tuple))
        ]
        """Algorithm parameter"""
        hyperparameter: Dict = {
            "MUTATION_PARAM": int(self.moo.root.mutation_param_int),
            "NUM_OF_GENERATIONS": int(self.moo.root.num_of_generation_int),
            "NUM_OF_INDIVIDUALS": int(self.moo.root.num_of_individual_int),
            "NUM_OF_TOUR_PARTICIPS":
            int(self.moo.root.num_of_tour_particps_int),
            "CONCURRENCY": True,
            "MAX_PROC": int(self.moo.root.max_proc_int)
        }
        """other constants"""
        constants: Dict = {
            "FLOOR_HEIGHT": float(self.moo.root.floor_height_float),
            "WINDOW_HEIGHT": float(self.moo.root.window_height_float),
            "WINDOW_EDG_HEIGHT": float(self.moo.root.window_edge_height_float),
            "HEATING_SETPOINT": float(self.moo.root.heating_setpoint_float),
            "COOLING_SETPOINT": float(self.moo.root.cooling_setpoint_float),
            "APMV_UPPER": float(self.moo.root.apmv_upper_float),
            "APMV_LOWER": float(self.moo.root.apmv_lower_float)
        }
        """path constants"""
        paths: Dict = {
            "WEATHER_FILE": str(self.moo.root.weather_file_str),
            "IDF_FILE": str(self.moo.root.idf_file_str),
            "OUTPUT_PATH": str(self.moo.root.output_path_str)
        }

        __import__('pprint').pprint(paras)
        __import__('pprint').pprint(hyperparameter)
        __import__('pprint').pprint(constants)
        __import__('pprint').pprint(paths)

        moo_run(paras, hyperparameter, constants, paths)

    @flx.action
    def stop(self):
        sys.exit(0)
Exemple #9
0
class Relay(flx.Component):
    #	def init(self):
    #		super().init()
    #		self.time = "Relay Default Time"
    #		self.newTime = False
    #
    #	def setTime(self, time):
    #		self.time = time
    #		self.newTime = True
    vin = flx.StringProp("", settable=True)
    timeString = flx.StringProp("", settable=True)
    voltage = flx.FloatProp(0, settable=True)
    capacity = flx.FloatProp(0, settable=True)
    pandaRecording = flx.IntProp(0, settable=True)
    pandaGps = flx.IntProp(0, settable=True)
    vehicleControlRunning = flx.BoolProp(False, settable=True)

    @flx.reaction('vin')
    def on_vin(self, *events):
        for ev in events:
            self.updateVin(ev.new_value)

    @flx.reaction('timeString')
    def on_timeString(self, *events):
        for ev in events:
            self.updateTime(ev.new_value)

    @flx.reaction('voltage')
    def on_voltage(self, *events):
        for ev in events:
            self.updateVoltage(ev.new_value)

    @flx.reaction('capacity')
    def on_voltage(self, *events):
        for ev in events:
            self.updateCapacity(ev.new_value)

    @flx.reaction('pandaRecording')
    def on_pandaRecording(self, *events):
        for ev in events:
            self.updatePandaRecording(ev.new_value)

    @flx.reaction('pandaGps')
    def on_pandaGps(self, *events):
        for ev in events:
            self.updatePandaGps(ev.new_value)

    @flx.reaction('vehicleControlRunning')
    def on_vehicleControlRunning(self, *events):
        for ev in events:
            self.updateVehicleControlRunning(ev.new_value)

    """ Global object to relay paint events to all participants.
	"""

    @flx.emitter
    def updateVin(self, value):
        return dict(value=value)

    @flx.emitter
    def updateTime(self, value):
        return dict(value=value)

    @flx.emitter
    def updateVoltage(self, value):
        return dict(value=value)

    @flx.emitter
    def updateCapacity(self, value):
        return dict(value=value)

    @flx.emitter
    def updatePandaRecording(self, value):
        return dict(value=value)

    @flx.emitter
    def updatePandaGps(self, value):
        return dict(value=value)

    @flx.emitter
    def updateVehicleControlRunning(self, value):
        return dict(value=value)
Exemple #10
0
class LeafletWidget(flx.Widget):
    """ A widget that shows a slippy/tile-map using Leaflet.
    """
    
    layers = flx.ListProp([], doc="""
        List of tilemap layer tuples: (url, 'Layer').
        """)
    
    zoom = flx.IntProp(8, settable=True, doc="""
        Zoom level for the map.
        """)
    
    min_zoom = flx.IntProp(0, settable=True, doc="""
        self zoom level for the map.
        """)
    
    max_zoom = flx.IntProp(18, settable=True, doc="""
        Maximum zoom level for the map.
        """)
    
    center = flx.FloatPairProp((5.2, 5.5), settable=True, doc="""
        The center of the map.
        """)
    
    show_layers = flx.BoolProp(False, settable=True, doc="""
        Whether to show layers-icon on the top-right of the map.
        """)
    
    show_scale = flx.BoolProp(False, settable=True, doc="""
        Whether to show scale at bottom-left of map.
        """)
    
    @flx.action
    def add_layer(self, url, name=None):
        """ Add a layer to the map.
        """
        # Avoid duplicates
        self.remove_layer(url)
        if name:
            self.remove_layer(name)
        # Add layer
        layers = self.layers + [(url, name or 'Layer')]
        self._mutate_layers(layers)
    
    @flx.action
    def remove_layer(self, url_or_name):
        """ Remove a layer from the map by url or name.
        """
        layers = list(self.layers)
        for i in reversed(range(len(layers))):
            if url_or_name in layers[i]:
                layers.pop(i)
        self._mutate_layers(layers)

    def _create_dom(self):
        global L, document
        node = document.createElement('div')
        self.mapnode = document.createElement('div')
        node.appendChild(self.mapnode)
        self.mapnode.id = 'maproot'
        self.mapnode.style.position = 'absolute'
        self.mapnode.style.top = '0px'
        self.mapnode.style.left = '0px'
        self.map = L.map(self.mapnode)
        self.map.on('zoomend', self.map_handle_zoom)
        self.map.on('moveend', self.map_handle_move)
        self.map.on('click', self.map_handle_mouse)
        self.map.on('dblclick', self.map_handle_mouse)
        # Container to keep track of leaflet layer objects
        self.layer_container = []
        self.layer_control = L.control.layers()
        self.scale = L.control.scale({'imperial': False, 'maxWidth': 200})
        # Set the path for icon images
        L.Icon.Default.prototype.options.imagePath = '_data/shared/'
        return node

    def map_handle_zoom(self, e):
        global isNaN
        zoom = self.map.getZoom()
        if isNaN(zoom):
            return
        if zoom != self.zoom:
            self.set_zoom(zoom)

    def map_handle_move(self, e):
        center_coord = self.map.getCenter()
        center = center_coord.lat, center_coord.lng
        if center != self.center:
            self.set_center(center)

    def map_handle_mouse(self, e):
        latlng = [e.latlng.lat, e.latlng.lng]
        xy = [e.layerPoint.x, e.layerPoint.y]
        self.pointer_event(e.type, latlng, xy)

    @flx.emitter
    def pointer_event(self, event, latlng, xy):
        return {'event': event, 'latlng': latlng, 'xy': xy}

    @flx.reaction
    def __handle_zoom(self):
        self.map.setZoom(self.zoom)

    @flx.reaction
    def __handle_min_zoom(self):
        self.map.setMinZoom(self.min_zoom)

    @flx.reaction
    def __handle_max_zoom(self):
        self.map.setMaxZoom(self.max_zoom)

    @flx.reaction
    def __handle_center(self):
        self.map.panTo(self.center)

    @flx.reaction
    def __handle_show_layers(self):
        if self.show_layers:
            self.map.addControl(self.layer_control)
        else:
            self.map.removeControl(self.layer_control)

    @flx.reaction
    def __handle_show_scale(self):
        if self.show_scale:
            self.map.addControl(self.scale)
        else:
            self.map.removeControl(self.scale)

    @flx.reaction
    def __size_changed(self):
        size = self.size
        if size[0] or size[1]:
            self.mapnode.style.width = size[0] + 'px'
            self.mapnode.style.height = size[1] + 'px'
            # Notify the map that it's container's size changed
            self.map.invalidateSize()

    @flx.reaction
    def __layers_changed(self):
        global L
        for layer in self.layer_container:
            self.layer_control.removeLayer(layer)
            if self.map.hasLayer(layer):
                self.map.removeLayer(layer)
        for layer_url, layer_name in self.layers:
            if not layer_url.endswith('.png'):
                if not layer_url.endswith('/'):
                    layer_url += '/'
                layer_url += '{z}/{x}/{y}.png'
            new_layer = L.tileLayer(layer_url)
            self.layer_container.append(new_layer)
            self.map.addLayer(new_layer)
            self.layer_control.addOverlay(new_layer, layer_name)
Exemple #11
0
class RobotModelWidget(flx.Widget):
    """ A Robot model Rviz window based on ros3djs.
    """

    host_ip = flx.StringProp("127.0.0.1",
                             settable=True,
                             doc="""
                             The IP of the host computer.
                             """)

    base_link = flx.StringProp("/base_link",
                               settable=True,
                               doc="""
                               The base link frame of the robot.
                               """)

    rosbridge_port = flx.IntProp(9090,
                                 settable=True,
                                 doc="""
                                 The port of rosbridge websocket.
                                 """)

    resources_port = flx.IntProp(9091,
                                 settable=True,
                                 doc="""
                                 The port of web server serving .dae files for urdf.
                                 """)

    robot_description = flx.StringProp("/sam/simple_description",
                                       settable=True,
                                       doc="""
                                       The ros param with the robot description.
                                       """)

    def _create_dom(self):
        global document

        node = document.createElement('div')
        self.viewernode = document.createElement('div')
        self.viewernode.id = 'urdf'
        node.appendChild(self.viewernode)

        return node

    def _render_dom(self):
        self.viewer_init()
        return super()._render_dom()

    @flx.action
    def viewer_init(self):
        global window  #, document

        if self.initialised:
            return

        self.ros = window.ROSLIB.Ros(
            {'url': 'ws://' + self.host_ip + ':' + str(self.rosbridge_port)})

        # Create the main viewer.
        self.viewer = window.ROS3D.Viewer({
            'divID': 'urdf',
            'width': window.innerWidth,
            'height': window.innerHeight,
            'antialias': True,
            'background': '#002233'
        })

        # Add a grid.
        self.viewer.addObject(window.ROS3D.Grid({'color': '#0181c4'}))

        # Setup a client to listen to TFs.
        self.tfClient = window.ROSLIB.TFClient({
            'ros': self.ros,
            'fixedFrame': self.base_link,  #"sam/base_link",
            'angularThres': 0.01,
            'transThres': 0.01,
            'rate': 10.0
        })

        # Setup the URDF client.
        self.urdfClient = window.ROS3D.UrdfClient({
            'param':
            self.robot_description,
            'path':
            'http://' + self.host_ip + ':' + str(self.resources_port),
            'ros':
            self.ros,
            'tfClient':
            self.tfClient,
            'rootObject':
            self.viewer.scene,
            'loader':
            window.ROS3D.COLLADA_LOADER_2
        })

        self.initialised = True

    @flx.reaction('size')
    def __on_size(self, *events):
        if self.viewer:
            self.viewer.resize(window.innerWidth, window.innerHeight)
Exemple #12
0
class IGraph(flx.PyComponent):
    CSS = """
.flx-main-widget{
overflow:scroll;
}
.configure{
overflow:scroll;
}
"""
    graph = flx.AnyProp(None, settable=True)
    graph_options = {
        #        "height": "90%",
    }
    graph_list = flx.ListProp([])
    current_graph = flx.IntProp(0, settable=True)

    def init(self):

        with ui.VSplit():
            with ui.HFix(flex=0):
                self.previous = ui.Button(text="<-", disabled=True, flex=1)
                self.content = ui.Label(flex=0)
                self.next = ui.Button(text="->", disabled=True, flex=1)
            with ui.HSplit(flex=1, spacing=20):
                self.configure = flx.Widget(css_class="configure", flex=0)
                with ui.HFix(flex=1):
                    self.visjs = VisJS(
                        style="background-color: #dddddd;",
                        flex=1,
                    )
        self.refresh()

    @event.reaction("graph")
    def update_viz(self, *events):
        ev = events[-1]
        graph = ev["new_value"]
        old_graph = ev["old_value"]
        if old_graph is None:
            self.visjs.load_viz(graph)
        else:

            def find_by_id(id, iterable):
                try:
                    return [elem for elem in iterable if elem["id"] == id][0]
                except IndexError:
                    return None

            self.visjs.update_viz({
                "nodes": {
                    "add": [
                        node for node in graph["nodes"]
                        if not find_by_id(node["id"], old_graph["nodes"])
                    ],
                    "remove": [
                        node["id"] for node in old_graph["nodes"]
                        if not find_by_id(node["id"], graph["nodes"])
                    ],
                    "update": [
                        node for node in graph["nodes"]
                        if find_by_id(node["id"], old_graph["nodes"])
                        and find_by_id(node["id"], old_graph["nodes"]) != node
                    ]
                },
                "edges": {
                    "add": [
                        edge for edge in graph["edges"]
                        if not find_by_id(edge["id"], old_graph["edges"])
                    ],
                    "remove": [
                        edge["id"] for edge in old_graph["edges"]
                        if not find_by_id(edge["id"], graph["edges"])
                    ],
                    "update": [
                        edge for edge in graph["edges"]
                        if find_by_id(edge["id"], old_graph["edges"])
                        and find_by_id(edge["id"], old_graph["edges"]) != edge
                    ],
                },
                "options": graph["options"],
            })

    @flx.action
    def refresh(self):
        try:
            graph = nx.nx_agraph.read_dot(self.file)
        except ImportError:
            try:
                graph = nx.nx_pydot.read_dot(self.file)
            except TypeError:
                print("TypeError")
                asyncio.get_event_loop().call_later(0.1, self.refresh)
                return

        def uniq_id():
            i = 0
            while True:
                yield i
                i = i + 1

        genid = uniq_id()
        for src in graph.nodes:
            for dst in graph[src]:
                for number in graph[src][dst]:
                    if "smooth.type" not in graph[src][dst][number]:
                        graph[src][dst][number]["smooth.type"] = "curvedCW"
                    if "smooth.roundness" not in graph[src][dst][number]:
                        graph[src][dst][number]["smooth.roundness"] = float(
                            number) / 5.
        graph_desc = {
            "nodes": [{
                "id":
                node_id,
                "label":
                graph.nodes[node_id].get("label", node_id),
                **dotted_dict_to_nested_dict({
                    k: cast_it(v)
                    for k, v in graph.nodes[node_id].items()
                }),
            } for node_id in graph.nodes],
            "edges": [{
                "id":
                next(genid),
                "arrows":
                "to",
                "from":
                src,
                "to":
                dst,
                "number":
                number,
                **dotted_dict_to_nested_dict({
                    k: cast_it(v)
                    for k, v in graph[src][dst][number].items()
                }),
            } for src in graph.nodes for dst in graph[src]
                      for number in graph[src][dst]],
            "options":
            dotted_dict_to_nested_dict({
                **self.graph_options,
                **dict_cast(graph.graph.get("graph", {})),
            })
        }

        gl = len(self.graph_list)
        cg = self.current_graph
        last_graph = (gl != 0 and self.graph_list[-1]) or None
        if graph_desc != last_graph:
            self._mutate_graph_list([graph_desc], 'insert', gl)
            if cg == (gl - 1):
                self.set_current_graph(cg + 1)

        asyncio.get_event_loop().call_later(0.1, self.refresh)

    @flx.reaction("graph_list", "current_graph")
    def _update_buttons(self, *evs):
        self.previous.set_disabled(
            len(self.graph_list) == 1 or self.current_graph == 0)
        self.previous.set_text(
            "{} <-".format(self.current_graph -
                           1) if self.current_graph else "|")
        self.content.set_text("{}".format(self.current_graph))
        self.next.set_disabled(self.current_graph == len(self.graph_list) - 1)
        self.next.set_text("-> {}".format(
            self.current_graph +
            1) if self.current_graph < len(self.graph_list) - 1 else "|")

    @flx.reaction("current_graph")
    def _update_graph(self, *evs):
        self.set_graph(self.graph_list[self.current_graph])

    @event.reaction("previous.pointer_click")
    def _previous(self, *evs):
        self.set_current_graph(self.current_graph - 1)

    @event.reaction("next.pointer_click")
    def _next(self, *evs):
        self.set_current_graph(self.current_graph + 1)
Exemple #13
0
class PanelRxView(flx.Widget):
    CSS = """
        .detail {
            boarder: solid green 3px;
            font-size:small;
            word-wrap:break-word;
            overflow: auto;
        }
        .packet_list { overflow: auto; }
        .flx-TreeWidget {
            border: gray solid 1px;
            font-size: small;
        }
        .flx-TreeItem {
            border-top: white solid 1px;
            text-overflow:ellipse;
            white-space:nowrap;
        }
        .flx-TreeItem:hover {
            background-color: #EEEEEE;
        }
        .flx-TreeItem.selected-true {
            background: blue;
            color: white;
        }
        .flx-TreeWidget .flx-TreeItem > .text.hastitle {
            width: 95%;
        }
        .flx-TreeItem > .title {
            background: white;
            color: gray;
        }
    """

    labels = flx.ListProp(settable=True)
    label_idx = flx.IntProp(settable=True)
    packets = flx.ListProp(settable=True)

    def init(self):
        with flx.HSplit():
            with flx.VBox(flex=1):
                self.summary = flx.TreeWidget(flex=1, max_selected=1)
            with flx.VSplit(flex=1):
                with flx.GroupWidget(css_class="list", flex=6, title="Detail"):
                    self.detail = flx.Label(flex=1, css_class="detail")
                    self.detail.set_wrap(2)
                with flx.GroupWidget(css_class="list", flex=4,
                                     title="hexdump"):
                    self.hexdump = flx.Label(flex=1, css_class="detail")
                    self.hexdump.set_wrap(1)

    @flx.action
    def add_pkt(self, info):
        self.packets.append(
            dict(summary=info['pkt_summary'],
                 detail=info['pkt_detail'],
                 hex=info['pkt_hex']))
        self.add_one_label(info['pkt_summary'])

    @flx.action
    def update_info(self, info):
        if info['packets']:
            self.add_labels(info['packets'])
        if info['hexdump_txt']:
            line = '<pre><code>' + info['hexdump_txt'] + '</ code></ pre>'
            self.hexdump.set_html(line)
        if info['detail_txt']:
            line = '<pre><code>' + info['detail_txt'] + '</ code></ pre>'
            self.detail.set_html(line)

    @flx.action
    def add_labels(self, msg):
        with self.summary:
            for l in msg.splitlines():
                self.add_one_label(l)

    @flx.action
    def add_one_label(self, msg):
        with self.summary:
            l = flx.TreeItem(text=msg, title=str(self.label_idx), checked=None)
        self._mutate_labels([l], 'insert', len(self.labels))
        self._mutate_label_idx(self.label_idx + 1)

    @flx.action
    def clear_labels(self):
        for l in self.labels:
            l.dispose()
        self.labels.clear()
        self._mutate_label_idx(0)
        self.hexdump.set_text('')
        self.detail.set_text('')

    @flx.action
    def clear_info(self):
        self.set_packets([])
        self.clear_labels()

    @flx.reaction('summary.children**.checked', 'summary.children**.selected')
    def _update_detail(self, *events):
        e = events[-1]
        id = int(e.source.title)
        self.show_detail(self.packets[id]['detail'])
        self.show_hexdump(self.packets[id]['hex'])

    def show_detail(self, msg):
        msg = '<pre><code>' + msg + '</code></pre>'
        self.detail.set_html(msg)

    def show_hexdump(self, msg):
        msg = '<pre><code>' + msg + '</code></pre>'
        self.hexdump.set_html(msg)
Exemple #14
0
class MyPrompt(MyWidget):

    options = flx.ListProp([])
    n_options = flx.IntProp(5)
    ref = flx.StringProp('MyID')

    def init(self):
        super().init()
        self.label = {}
        with flx.VBox() as self.wmain:
            self.label['above'] = flx.Label(text='Text above', flex=1)
            with flx.HBox():
                self.winput = MyLineEdit(flex=1)
            with flx.VBox():
                self.dots_above = MyDots(text='···')
                with flx.VBox() as self.woptions_box:
                    pass
                self.dots_below = MyDots(text='···')
        self.woptions = []
        self.show_more = 0
        self.index = 0
        self.shift = 0
        self.focus_element = self.winput

    @flx.emitter
    def emit_option(self, option):
        return dict(value=option, ref=self.ref, text=self.winput.text)

    @flx.emitter
    def emit_text(self, text):
        return dict(value=text, ref=self.ref)

    @flx.emitter
    def emit_escape(self):
        return dict(ref=self.ref)

    @flx.emitter
    def emit_interrupt(self):
        return dict(ref=self.ref)

    @flx.action
    def set_focus(self):
        self._set_focus()

    async def _set_focus(self):
        elem = self.focus_element
        while elem.node.offsetParent == None:
            await self.sleep(50)
        elem.node.focus()
        return

    async def select_text(self):
        await self.sleep(50)
        self.winput.node.select()
        return

    @flx.action
    def set_properties(self, kwargs):
        if 'prefill' in kwargs:
            self.winput.set_text(kwargs.pop('prefill'))
            self.select_text()
        if 'placeholder' in kwargs:
            self.winput.set_placeholder_text(kwargs.pop('placeholder'))
        for key in ['above']:
            if key in kwargs:
                value = kwargs.pop(key)
                elem = self.label[key]
                if value is None:
                    elem.set_text('hidden')
                    elem.node.hidden = True
                else:
                    elem.node.hidden = False
                    elem.set_text(value)
        if 'ref' in kwargs:
            self._mutate_ref(kwargs['ref'])
        keys = ['options', 'n_options']
        if any([key in kwargs for key in keys]):
            kw = kwargs
            kw['options'] = kw.get('options', self.options)
            kw['n_options'] = kw.get('n_options', self.n_options)
            self.set_options(kw.pop('options'), kw.pop('n_options'))
        for key, val in kwargs.items():
            print(f'Error: unhandled key={key}, val={val}')
        return

    @flx.action
    def set_options(self, options, n_options=None):
        if n_options == None: n_options = 5
        if not self.winput: return
        self._mutate_options(options)
        self._mutate_n_options(n_options)
        self.pre_match = {}
        for s in self.options:
            self.pre_match[s] = self.my_grams(s)
        self.filtered = self.options
        self.index = 0
        self.shift = 0
        self.redraw_options()

    @flx.reaction('woptions_box.children*.pointer_click')
    def _listen_clicks(self, *events):
        for ev in events:
            self.listen_click(ev.source.text)

    def listen_click(self, option):
        self.winput.node.select()  # Select text
        self.emit_option(option)
        self.options.remove(option)
        self.options.insert(0, option)
        self.index = 0
        self.shift = 0
        self.redraw_options()
        return

    @flx.reaction('key_down')
    def listen_keys(self, *events):
        for ev in events:
            if ev.modifiers == 'Ctrl' and ev.key == 'c' and self.winput.text == '':
                self.emit_interrupt()
            elif ev.modifiers:
                continue
            elif ev.key == 'Escape':
                self.emit_escape()
            elif ev.key == 'Enter':
                if len(self.woptions):
                    option = self.woptions[self.index].text
                    self.listen_click(option)
                else:
                    self.emit_text(self.winput.text)
            elif ev.key == 'ArrowDown':
                if self.index + 1 < len(self.woptions): self.index += 1
                elif self.shift + self.n_options < len(self.filtered):
                    self.shift += 1
                self.redraw_options()
            elif ev.key == 'ArrowUp':
                redraw = True
                if self.index > 0: self.index -= 1
                elif self.shift: self.shift -= 1
                else: redraw = False
                if redraw: self.redraw_options()
        return

    @flx.reaction('winput.text')
    def listen_winput(self, *events):
        if self.winput.text == '':
            self.filtered = self.options
        else:
            score = self.fuzzy_scores(self.winput.text)
            thr = max(max(score.values()) / 2, 1 / 3)
            self.filtered = sorted(
                [s for s in self.options if score[s] > thr],
                key=lambda s: -score[s],
            )
        self.index = 0
        self.shift = 0
        self.redraw_options()
        return

    def redraw_options(self):
        to_show = self.filtered[self.shift:self.shift + self.n_options]
        with self.woptions_box:
            while len(self.woptions) < len(to_show):
                self.woptions.append(flx.Button())
            while len(self.woptions) > len(to_show):
                self.woptions.pop().dispose()
        for i in range(len(to_show)):
            self.woptions[i].set_text(to_show[i])
            style = 'background:#ccc' if i == self.index else 'background:#eee'
            self.woptions[i].node.style = style
        if len(self.options) == 1:
            self.winput.node.hidden = True
            self.focus_element = self.woptions[0]
        else:
            self.winput.node.hidden = False
            self.focus_element = self.winput
        self.dots_above.set_visible(self.shift > 0)
        self.dots_below.set_visible(
            len(self.filtered) - self.shift > self.n_options)
        return

    def my_grams(self, s):
        n = len(s)
        s = s.lower()
        g = {}
        for i in range(n):
            g[s[i]] = (g[s[i]] or 0) + 1
            if i + 1 < n: g[s[i] + s[i + 1]] = (g[s[i] + s[i + 1]] or 0) + 1
            if i + 2 < n: g[s[i] + s[i + 2]] = (g[s[i] + s[i + 1]] or 0) + 1
        return g

    def fuzzy_scores(self, text):
        x = self.my_grams(text)
        score = {}
        for key, y in self.pre_match.items():
            hits = total = 0
            z = y.copy()
            for k, v in x.items():
                z[k] = (z[k] or 0) - x[k]
                hits += z[k] >= 0
                total += 1
            score[key] = hits / total
        return score