<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

from PyQt4 import QtGui
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import *

import DIRT

class RunningWindow(QDialog):

    def __init__(self, parent=None):
        super(RunningWindow, self).__init__(parent)

        self.layout = GridLayout(self)

        # self.setGeometry(300, 300, 350, 350)
        self.setWindowTitle('DiRT Startup')
        self.setModal(True)
        self.setStyleSheet("background-color: rgb(245,247,255);")

class GridLayout(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        # Create the QVBoxLayout that lays out the whole form
        self.layout = QVBoxLayout()

        # Create the form layout that manages the labeled controls
        self.form_layout = QFormLayout()

        # Create the build button with its caption
        self.fileInputEdit = QLineEdit(self)
        self.form_layout.addRow('Input Files:',self.fileInputEdit)
        self.Button1 = QPushButton('Input Files Location', self)
        self.form_layout.addWidget(self.Button1)
        self.blank_line = QLabel('', self)
        self.form_layout.addRow('', self.blank_line)

        self.prepDirEdit = QLineEdit(self)
        self.form_layout.addRow('Preprocessed Directory:',self.prepDirEdit)
        self.Button2 = QPushButton('Preprocessed Location', self)
        self.form_layout.addWidget(self.Button2)
        self.blank_line1 = QLabel('', self)
        self.form_layout.addRow('', self.blank_line1)

        self.outDirEdit = QLineEdit(self)
        self.form_layout.addRow('Output Directory:',self.outDirEdit)
        self.Button3 = QPushButton('Output Location', self)
        self.form_layout.addWidget(self.Button3)
        self.blank_line2 = QLabel('', self)
        self.form_layout.addRow('', self.blank_line2)

        # Add the form layout to the main VBox layout
        self.layout.addLayout(self.form_layout)

        # Create and fill the combo box to choose the skipping character
        self.gap_length = QLineEdit(self)

        # Add it to the form layout with a label
        self.form_layout.addRow('Gap Length:', self.gap_length)

        # Create and fill the combo box to choose the skipping character
        self.minimum_match_length = QLineEdit(self)

        # Add it to the form layout with a label
        self.form_layout.addRow('Minimum Match Length:', self.minimum_match_length)

        # Create and add the label to show the greeting text
        self.option = QLabel('', self)
        self.form_layout.addRow('Options', self.option)

        # Add stretch to separate the form layout from the button
        self.layout.addStretch(1)

        # Create a horizontal box layout to hold the button
        self.button_box = QHBoxLayout()

        # Add stretch to push the button to the far right
        self.button_box.addStretch(1)

        # Create the build button with its caption
        self.startButton = QPushButton('DiRT Start', self)

        # Add it to the button box
        self.button_box.addWidget(self.startButton)

        # Add the button box to the bottom of the main VBox layout
        self.layout.addLayout(self.button_box)

        self.setLayout(self.layout)

        # Link to the DirtStart Button
        self.connect(self.startButton, SIGNAL('clicked()'), self.run)

        # Link Location Buttons
        self.connect(self.Button1, SIGNAL('clicked()'), self.select_input_file)
        self.connect(self.Button2, SIGNAL('clicked()'), self.select_preprocessed_directory)
        self.connect(self.Button3, SIGNAL('clicked()'), self.select_output_directory)

        self.adjustSize()

    def run(self):
        gap_length = int(self.gap_length.text())
        match_length = int(self.minimum_match_length.text())
        print gap_length, match_length
        args = None
        DIRT.main(args)

    def select_input_file(self):
        fileName = QFileDialog.getOpenFileName(self, "Open File")
        self.fileInputEdit.setText(fileName)

    def select_preprocessed_directory(self):
        file = str(QFileDialog.getExistingDirectory(self, "Select Directory"))
        self.prepDirEdit.setText(file)

    def select_output_directory(self):
        file = str(QFileDialog.getExistingDirectory(self, "Select Directory"))
        self.outDirEdit.setText(file)
<commit_msg>fix naming<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

from PyQt4 import QtGui
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import *

import DIRT

class RunningWindow(QDialog):

    def __init__(self, parent=None):
        super(RunningWindow, self).__init__(parent)

        self.layout = GridLayout(self)

        # self.setGeometry(300, 300, 350, 350)
        self.setWindowTitle('DiRT Startup')
        self.setModal(True)
        self.setStyleSheet("background-color: rgb(245,247,255);")

class GridLayout(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        # Create the QVBoxLayout that lays out the whole form
        self.layout = QVBoxLayout()

        # Create the form layout that manages the labeled controls
        self.form_layout = QFormLayout()

        # Create the build button with its caption
        self.input_file_field = QLineEdit(self)
        self.form_layout.addRow('Input Files:', self.input_file_field)
        self.btn_input_file = QPushButton('Input Files Location', self)
        self.form_layout.addWidget(self.btn_input_file)
        self.blank_line = QLabel('', self)
        self.form_layout.addRow('', self.blank_line)

        self.preprocessed_dir_field = QLineEdit(self)
        self.form_layout.addRow('Preprocessed Directory:', self.preprocessed_dir_field)
        self.btn_preprocessed_dir = QPushButton('Preprocessed Location', self)
        self.form_layout.addWidget(self.btn_preprocessed_dir)
        self.blank_line1 = QLabel('', self)
        self.form_layout.addRow('', self.blank_line1)

        self.output_dir_field = QLineEdit(self)
        self.form_layout.addRow('Output Directory:', self.output_dir_field)
        self.btn_output_dir = QPushButton('Output Location', self)
        self.form_layout.addWidget(self.btn_output_dir)
        self.blank_line2 = QLabel('', self)
        self.form_layout.addRow('', self.blank_line2)

        # Add the form layout to the main VBox layout
        self.layout.addLayout(self.form_layout)

        # Create and fill the combo box to choose the skipping character
        self.gap_length = QLineEdit(self)

        # Add it to the form layout with a label
        self.form_layout.addRow('Gap Length:', self.gap_length)

        # Create and fill the combo box to choose the skipping character
        self.minimum_match_length = QLineEdit(self)

        # Add it to the form layout with a label
        self.form_layout.addRow('Minimum Match Length:', self.minimum_match_length)

        # Create and add the label to show the greeting text
        self.option = QLabel('', self)
        self.form_layout.addRow('Options', self.option)

        # Add stretch to separate the form layout from the button
        self.layout.addStretch(1)

        # Create a horizontal box layout to hold the button
        self.button_box = QHBoxLayout()

        # Add stretch to push the button to the far right
        self.button_box.addStretch(1)

        # Create the build button with its caption
        self.btn_run = QPushButton('DiRT Start', self)

        # Add it to the button box
        self.button_box.addWidget(self.btn_run)

        # Add the button box to the bottom of the main VBox layout
        self.layout.addLayout(self.button_box)

        self.setLayout(self.layout)

        on_click = SIGNAL('clicked()')
        # Link to the DirtStart Button
        self.connect(self.btn_run, on_click, self.run)

        # Link Location Buttons
        self.connect(self.btn_input_file, on_click, self.select_input_file)
        self.connect(self.btn_preprocessed_dir, on_click, self.select_preprocessed_directory)
        self.connect(self.btn_output_dir, on_click, self.select_output_directory)

        self.adjustSize()

    def run(self):
        gap_length = int(self.gap_length.text())
        match_length = int(self.minimum_match_length.text())
        print gap_length, match_length
        args = None
        DIRT.main(args)

    def select_input_file(self):
        dialog = QFileDialog()
        file_name = dialog.getOpenFileName(self, "Open")
        self.input_file_field.setText(file_name)

    def select_preprocessed_directory(self):
        preprocessed_dir = str(QFileDialog.getExistingDirectory(self, "Select Directory"))
        self.preprocessed_dir_field.setText(preprocessed_dir)

    def select_output_directory(self):
        output_dir = str(QFileDialog.getExistingDirectory(self, "Select Directory"))
        self.output_dir_field.setText(output_dir)
<|endoftext|>


<commit_before>from sklearn import hmm
import utils
from copy import deepcopy
import numpy as np
import pandas as pd
from collections import OrderedDict
import itertools
import matplotlib.pyplot as plt

def init_HMM(pi_prior,a_prior,mean_prior,cov_prior):
    '''
    Initializes a trace object from a series and a metadata dictionary.
    Series must be sampled at a particular sample rate
    pi_prior is the starting probability of the HMM
    a_prior is the transition matrix of the HMM
    mean_prior is the initial mean value of each state
    cov_prior is the initial covariance of each state

    For an n-state HMM:

    * pi_prior is a 1-D numpy array of size n
    * a_prior is a 2-D numpy array of size n x n
    * mean_prior is an numpy array of size n
    * cov_prior is a 3-D numpy array that has been tiled into two rows,
      one column, and n third dimensional states.

      * ex) np.tile(1,(2,1,n)) for uniform covariance to start with.
    '''
    model = hmm.GaussianHMM(pi_prior.size,'full',pi_prior,a_prior)
    model.means_ = mean_prior
    model.covars_ = cov_prior
    return model

def fit_trace_to_HMM(model,trace):
    '''
    Fits the given trace to the model. NaNs are turned into zeroes.
    '''
    trace_values = utils.trace_series_to_numpy_array(trace.series)
    model.fit([trace_values])
    startprob, means, covars, transmat = _sort_learnt_parameters(model.startprob_,
            model.means_, model.covars_ , model.transmat_)
    model=hmm.GaussianHMM(startprob.size, 'full', startprob, transmat)
    model.means_ = means
    model.covars_ = covars
    return model

def fit_instance_to_HMM(model,instance):
    '''
    Fits the given instance to the model. NaNs are turned into zeroes.
    '''
    for trace in instance.traces:
        model=fit_trace_to_HMM(model,trace)
    return model

def generate_HMMs_from_type(type,pi_prior,a_prior,
        mean_prior,cov_prior,key_for_model_name=None):
    '''
    Generates a dictionary of HMMs using each instance of given type.
    The key to the dictionary is defined by the parameter 'key_for_model_name'
    which looks at each instances metadata and uses the value from that key
    in order to name the model. If no key is given, the model is named based on
    its index.
    '''
    instance_models=OrderedDict()
    for i,instance in enumerate(type.instances):
        if(key_for_model_name):
            instance_name=instance.traces[0].metadata[key_for_model_name]
        else:
            instance_name=i
        instance_models[instance_name]=init_HMM(pi_prior,a_prior,mean_prior,cov_prior)
        instance_models[instance_name]=fit_instance_to_HMM(instance_models[instance_name],
                instance)
    return instance_models

def generate_FHMM_from_HMMs(type_models):
    '''
    Takes a dictionary of models, where the keys are the device type name, and
    generates an FHMM of these models. It returns the fhmm model as well as
    a dictionary with the key being device type and each value being a list
    containing the means for each state of that device type.
    '''
    list_pi=[]
    list_A=[]
    list_means=[]
    means={}
    for device_type_name in type_models:
        list_pi.append(type_models[device_type_name].startprob_)
        list_A.append(type_models[device_type_name].transmat_)
        list_means.append(type_models[device_type_name].means_.flatten().
            tolist())
        means[device_type_name]=type_models[device_type_name].means_
    pi_combined=_compute_pi_fhmm(list_pi)
    A_combined=_compute_A_fhmm(list_A)
    [mean_combined, cov_combined]=_compute_means_fhmm(list_means)
    model_fhmm=_create_combined_hmm(len(pi_combined),pi_combined,
            A_combined, mean_combined, cov_combined)
    return model_fhmm,means

def predict_with_FHMM(model_fhmm,means,power_total):
    '''
    Predicts the _decoded states and power for the given test data with the
    given FHMM. test_data is a dictionary containing keys for each device
    that is in the FHMM.
    '''
    learnt_states=model_fhmm.predict(power_total)
    [_decoded_states,_decoded_power]=_decode_hmm(len(learnt_states), means,
            means.keys(), learnt_states)
    return _decoded_states,_decoded_power

def plot_FHMM_and_predictions(test_data,_decoded_power):
    '''
    This plots the actual and predicted power based on the FHMM.
    '''
    for i,device_type in enumerate(test_data):
        if(device_type is not 'use'):
            plt.figure()
            plt.plot(test_data[device_type],'g')
            plt.plot(_decoded_power[device_type],'b')
            plt.title('Ground Truth (Green) and Predicted (Blue) for %s' %device_type)
            plt.ylabel('Power (W)')
            plt.xlabel('Time')
            plt.ylim((np.min(test_data[device_type])-10, np.max(test_data[device_type])+10))
            plt.tight_layout()

def get_best_instance_model(instance_models,device_type,key_for_model_name):
    dfs_model = {}
    best_model_score = 0
    for model_name in instance_models:
        instances_of_model = []
        for instance in device_type.instances:
            test_trace = instance.traces[0]
            instance_name = test_trace.metadata[key_for_model_name]
            test = utils.trace_series_to_numpy_array(test_trace.series)
            model_score = instance_models[model_name].score(test)
            instances_of_model.append([model_name,instance_name,model_score])
            if(model_score > best_model_score):
                best_model = instance_models[model_name]
        dfs_model[model_name] = pd.DataFrame(data=instances_of_model,
                columns=['Model_Instance','Test_Instance','Value'])
    model_averages = []
    for key in dfs_model:
        sum=0
        for row in dfs_model[key].iterrows():
            sum = sum+row[1]['Value']
        model_averages.append([key,sum/len(dfs_model[key].index)])
    print
    avg_model_df = pd.DataFrame(data=model_averages,
            columns=['Model_Instance','Avg Probability'])
    print avg_model_df._sort('Avg Probability',ascending=False)
    bestModel = avg_model_df._sort('Avg Probability',
            ascending=False)._sort('Avg Probability',
                    ascending=False).head(1)['Model_Instance'].values[0]
    print str(bestModel) + ' is best.'
    return bestModel

def _sort_startprob(mapping, startprob):
    '''
    _sort the startprob of the HMM according to power means; as returned by mapping
    '''

    num_elements = len(startprob)
    new_startprob = np.zeros(num_elements)
    for i in xrange(len(startprob)):
        new_startprob[i] = startprob[mapping[i]]
    return new_startprob

def _sort_covars(mapping, covars):
    num_elements = len(covars)
    new_covars = np.zeros_like(covars)
    for i in xrange(len(covars)):
        new_covars[i] = covars[mapping[i]]
    return new_covars

def _sort_transition_matrix(mapping, A):
    '''
    sorts the transition matrix of the HMM according to power means; as returned by mapping
    '''
    num_elements = len(A)
    A_new = np.zeros((num_elements, num_elements))
    for i in range(num_elements):
        for j in range(num_elements):
            A_new[i,j] = A[mapping[i], mapping[j]]
    return A_new

def _return_sorting_mapping(means):
    means_copy = deepcopy(means)
    # _sorting
    means_copy = np.sort(means_copy, axis = 0)
    # Finding mapping
    mapping = {}
    mapping_set=set()
    x=0
    for i, val in enumerate(means_copy):
        x= np.where(val==means)[0]
        for val in x:
            if val not in mapping_set:
                mapping_set.add(val)
                mapping[i]=val
                break
    return mapping

def _sort_learnt_parameters(startprob, means, covars, transmat):
    '''
    sorts the learnt parameters for the HMM
    '''
    mapping = _return_sorting_mapping(means)
    means_new = np.sort(means, axis = 0)

    startprob_new = _sort_startprob(mapping, startprob)
    covars_new = _sort_covars(mapping, covars)
    transmat_new = _sort_transition_matrix(mapping, transmat)
    assert np.shape(means_new) == np.shape(means)
    assert np.shape(startprob_new) == np.shape(startprob)
    assert np.shape(transmat_new) == np.shape(transmat)
    return [startprob_new, means_new, covars_new, transmat_new]

def _compute_pi_fhmm(list_pi):
    '''
    Input: list_pi: List of PI's of individual learnt HMMs
    Output: Combined Pi for the FHMM
    '''
    result=list_pi[0]
    for i in range(len(list_pi)-1):
        result=np.kron(result,list_pi[i+1])
    return result

def _compute_A_fhmm(list_A):
    '''
    Input: list_pi: List of PI's of individual learnt HMMs
    Output: Combined Pi for the FHMM
    '''
    result=list_A[0]
    for i in range(len(list_A)-1):
        result=np.kron(result,list_A[i+1])
    return result

def _compute_means_fhmm(list_means):
    '''
    Returns [mu, sigma]
    '''

    #list_of_appliances_centroids=[ [appliance[i][0] for i in range(len(appliance))] for appliance in list_B]
    states_combination=list(itertools.product(*list_means))
    num_combinations=len(states_combination)
    means_stacked=np.array([sum(x) for x in states_combination])
    means=np.reshape(means_stacked,(num_combinations,1))
    cov=np.tile(5*np.identity(1), (num_combinations, 1, 1))
    return [means, cov]

def _create_combined_hmm(n, pi, A, mean, cov):
    combined_model=hmm.GaussianHMM(n_components=n,covariance_type='full', startprob=pi, transmat=A)
    combined_model.covars_=cov
    combined_model.means_=mean
    return combined_model

def _decode_hmm(length_sequence, centroids, appliance_list, states):
    '''
    decodes the HMM state sequence
    '''
    power_states_dict={}
    hmm_states={}
    hmm_power={}
    total_num_combinations=1
    for appliance in appliance_list:
        total_num_combinations*=len(centroids[appliance])

    for appliance in appliance_list:
        hmm_states[appliance]=np.zeros(length_sequence,dtype=np.int)
        hmm_power[appliance]=np.zeros(length_sequence)

    for i in range(length_sequence):
        factor=total_num_combinations
        for appliance in appliance_list:
            #assuming integer division (will cause errors in Python 3x)
            factor=factor//len(centroids[appliance])

            temp=int(states[i])/factor
            hmm_states[appliance][i]=temp%len(centroids[appliance])
            hmm_power[appliance][i]=centroids[appliance][hmm_states[appliance][i]]

    return [hmm_states,hmm_power]

def disaggregate_data(model_tuple, trace):
    power_total=utils.trace_series_to_numpy_array(trace.series)
    [decoded_states, decoded_power]=predict_with_FHMM(model_tuple[0],
            model_tuple[1],power_total)
    for i,v in enumerate(decoded_power['air1']):
        date_time=trace.series.index[i]
        value=trace.series[i]
        data.append({'date':date_time.strftime('%Y-%m-%d %H:%M'),
            'reading': float(v),'dg':float(value)})
    json_string = json.dumps(data, ensure_ascii=False,indent=4,
            separators=(',', ': '))
    return json_string
<commit_msg>fhmm playing<commit_after>from sklearn import hmm
import utils
from copy import deepcopy
import numpy as np
import pandas as pd
from collections import OrderedDict
import itertools
import matplotlib.pyplot as plt

def init_HMM(pi_prior,a_prior,mean_prior,cov_prior):
    '''
    Initializes a trace object from a series and a metadata dictionary.
    Series must be sampled at a particular sample rate
    pi_prior is the starting probability of the HMM
    a_prior is the transition matrix of the HMM
    mean_prior is the initial mean value of each state
    cov_prior is the initial covariance of each state

    For an n-state HMM:

    * pi_prior is a 1-D numpy array of size n
    * a_prior is a 2-D numpy array of size n x n
    * mean_prior is an numpy array of size n
    * cov_prior is a 3-D numpy array that has been tiled into two rows,
      one column, and n third dimensional states.

      * ex) np.tile(1,(2,1,n)) for uniform covariance to start with.
    '''
    model = hmm.GaussianHMM(pi_prior.size,'full',pi_prior,a_prior)
    model.means_ = mean_prior
    model.covars_ = cov_prior
    return model

def fit_trace_to_HMM(model,trace):
    '''
    Fits the given trace to the model. NaNs are turned into zeroes.
    '''
    trace_values = utils.trace_series_to_numpy_array(trace.series)
    model.fit([trace_values])
    startprob, means, covars, transmat = _sort_learnt_parameters(model.startprob_,
            model.means_, model.covars_ , model.transmat_)
    model=hmm.GaussianHMM(startprob.size, 'full', startprob, transmat)
    model.means_ = means
    model.covars_ = covars
    return model

def fit_instance_to_HMM(model,instance):
    '''
    Fits the given instance to the model. NaNs are turned into zeroes.
    '''
    for trace in instance.traces:
        model=fit_trace_to_HMM(model,trace)
    return model

def generate_HMMs_from_type(type,pi_prior,a_prior,
        mean_prior,cov_prior,key_for_model_name=None):
    '''
    Generates a dictionary of HMMs using each instance of given type.
    The key to the dictionary is defined by the parameter 'key_for_model_name'
    which looks at each instances metadata and uses the value from that key
    in order to name the model. If no key is given, the model is named based on
    its index.
    '''
    instance_models=OrderedDict()
    for i,instance in enumerate(type.instances):
        if(key_for_model_name):
            instance_name=instance.traces[0].metadata[key_for_model_name]
        else:
            instance_name=i
        instance_models[instance_name]=init_HMM(pi_prior,a_prior,mean_prior,cov_prior)
        instance_models[instance_name]=fit_instance_to_HMM(instance_models[instance_name],
                instance)
    return instance_models

def generate_FHMM_from_HMMs(type_models):
    '''
    Takes a dictionary of models, where the keys are the device type name, and
    generates an FHMM of these models. It returns the fhmm model as well as
    a dictionary with the key being device type and each value being a list
    containing the means for each state of that device type.
    '''
    list_pi=[]
    list_A=[]
    list_means=[]
    means={}
    for device_type_name in type_models:
        list_pi.append(type_models[device_type_name].startprob_)
        list_A.append(type_models[device_type_name].transmat_)
        list_means.append(type_models[device_type_name].means_.flatten().
            tolist())
        means[device_type_name]=type_models[device_type_name].means_
    pi_combined=_compute_pi_fhmm(list_pi)
    A_combined=_compute_A_fhmm(list_A)
    [mean_combined, cov_combined]=_compute_means_fhmm(list_means)
    model_fhmm=_create_combined_hmm(len(pi_combined),pi_combined,
            A_combined, mean_combined, cov_combined)
    return model_fhmm,means

def predict_with_FHMM(model_fhmm,means,power_total):
    '''
    Predicts the _decoded states and power for the given test data with the
    given FHMM. test_data is a dictionary containing keys for each device
    that is in the FHMM.
    '''
    learnt_states=model_fhmm.predict(power_total)
    [_decoded_states,_decoded_power]=_decode_hmm(len(learnt_states), means,
            means.keys(), learnt_states)
    return _decoded_states,_decoded_power

def plot_FHMM_and_predictions(test_data,_decoded_power):
    '''
    This plots the actual and predicted power based on the FHMM.
    '''
    for i,device_type in enumerate(test_data):
        if(device_type is not 'use'):
            plt.figure()
            plt.plot(test_data[device_type],'g')
            plt.plot(_decoded_power[device_type],'b')
            plt.title('Ground Truth (Green) and Predicted (Blue) for %s' %device_type)
            plt.ylabel('Power (W)')
            plt.xlabel('Time')
            plt.ylim((np.min(test_data[device_type])-10, np.max(test_data[device_type])+10))
            plt.tight_layout()

def get_best_instance_model(instance_models,device_type,key_for_model_name):
    dfs_model = {}
    best_model_score = 0
    for model_name in instance_models:
        instances_of_model = []
        for instance in device_type.instances:
            test_trace = instance.traces[0]
            instance_name = test_trace.metadata[key_for_model_name]
            test = utils.trace_series_to_numpy_array(test_trace.series)
            model_score = instance_models[model_name].score(test)
            instances_of_model.append([model_name,instance_name,model_score])
            if(model_score > best_model_score):
                best_model = instance_models[model_name]
        dfs_model[model_name] = pd.DataFrame(data=instances_of_model,
                columns=['Model_Instance','Test_Instance','Value'])
    model_averages = []
    for key in dfs_model:
        sum=0
        for row in dfs_model[key].iterrows():
            sum = sum+row[1]['Value']
        model_averages.append([key,sum/len(dfs_model[key].index)])
    print
    avg_model_df = pd.DataFrame(data=model_averages,
            columns=['Model_Instance','Avg Probability'])
    print avg_model_df._sort('Avg Probability',ascending=False)
    bestModel = avg_model_df._sort('Avg Probability',
            ascending=False)._sort('Avg Probability',
                    ascending=False).head(1)['Model_Instance'].values[0]
    print str(bestModel) + ' is best.'
    return bestModel

def _sort_startprob(mapping, startprob):
    '''
    _sort the startprob of the HMM according to power means; as returned by mapping
    '''

    num_elements = len(startprob)
    new_startprob = np.zeros(num_elements)
    for i in xrange(len(startprob)):
        new_startprob[i] = startprob[mapping[i]]
    return new_startprob

def _sort_covars(mapping, covars):
    num_elements = len(covars)
    new_covars = np.zeros_like(covars)
    for i in xrange(len(covars)):
        new_covars[i] = covars[mapping[i]]
    return new_covars

def _sort_transition_matrix(mapping, A):
    '''
    sorts the transition matrix of the HMM according to power means; as returned by mapping
    '''
    num_elements = len(A)
    A_new = np.zeros((num_elements, num_elements))
    for i in range(num_elements):
        for j in range(num_elements):
            A_new[i,j] = A[mapping[i], mapping[j]]
    return A_new

def _return_sorting_mapping(means):
    means_copy = deepcopy(means)
    # _sorting
    means_copy = np.sort(means_copy, axis = 0)
    # Finding mapping
    mapping = {}
    mapping_set=set()
    x=0
    for i, val in enumerate(means_copy):
        x= np.where(val==means)[0]
        for val in x:
            if val not in mapping_set:
                mapping_set.add(val)
                mapping[i]=val
                break
    return mapping

def _sort_learnt_parameters(startprob, means, covars, transmat):
    '''
    sorts the learnt parameters for the HMM
    '''
    mapping = _return_sorting_mapping(means)
    means_new = np.sort(means, axis = 0)

    startprob_new = _sort_startprob(mapping, startprob)
    covars_new = _sort_covars(mapping, covars)
    transmat_new = _sort_transition_matrix(mapping, transmat)
    assert np.shape(means_new) == np.shape(means)
    assert np.shape(startprob_new) == np.shape(startprob)
    assert np.shape(transmat_new) == np.shape(transmat)
    return [startprob_new, means_new, covars_new, transmat_new]

def _compute_pi_fhmm(list_pi):
    '''
    Input: list_pi: List of PI's of individual learnt HMMs
    Output: Combined Pi for the FHMM
    '''
    result=list_pi[0]
    for i in range(len(list_pi)-1):
        result=np.kron(result,list_pi[i+1])
    return result

def _compute_A_fhmm(list_A):
    '''
    Input: list_pi: List of PI's of individual learnt HMMs
    Output: Combined Pi for the FHMM
    '''
    result=list_A[0]
    for i in range(len(list_A)-1):
        result=np.kron(result,list_A[i+1])
    return result

def _compute_means_fhmm(list_means):
    '''
    Returns [mu, sigma]
    '''

    #list_of_appliances_centroids=[ [appliance[i][0] for i in range(len(appliance))] for appliance in list_B]
    states_combination=list(itertools.product(*list_means))
    num_combinations=len(states_combination)
    means_stacked=np.array([sum(x) for x in states_combination])
    means=np.reshape(means_stacked,(num_combinations,1))
    cov=np.tile(5*np.identity(1), (num_combinations, 1, 1))
    return [means, cov]

def _create_combined_hmm(n, pi, A, mean, cov):
    combined_model=hmm.GaussianHMM(n_components=n,covariance_type='full', startprob=pi, transmat=A)
    combined_model.covars_=cov
    combined_model.means_=mean
    return combined_model

def _decode_hmm(length_sequence, centroids, appliance_list, states):
    '''
    decodes the HMM state sequence
    '''
    power_states_dict={}
    hmm_states={}
    hmm_power={}
    total_num_combinations=1
    for appliance in appliance_list:
        total_num_combinations*=len(centroids[appliance])

    for appliance in appliance_list:
        hmm_states[appliance]=np.zeros(length_sequence,dtype=np.int)
        hmm_power[appliance]=np.zeros(length_sequence)

    for i in range(length_sequence):
        factor=total_num_combinations
        for appliance in appliance_list:
            #assuming integer division (will cause errors in Python 3x)
            factor=factor//len(centroids[appliance])

            temp=int(states[i])/factor
            hmm_states[appliance][i]=temp%len(centroids[appliance])
            hmm_power[appliance][i]=centroids[appliance][hmm_states[appliance][i]]

    return [hmm_states,hmm_power]

def disaggregate_data(model_tuple, trace):
    data=[]
    power_total=utils.trace_series_to_numpy_array(trace.series)
    [decoded_states, decoded_power]=predict_with_FHMM(model_tuple[0],
            model_tuple[1],power_total)
    for i,v in enumerate(decoded_power['air1']):
        date_time=trace.series.index[i]
        value=trace.series[i]
        data.append({'date':date_time.strftime('%Y-%m-%d %H:%M'),
            'reading': float(v),'dg':float(value)})
    json_string = json.dumps(data, ensure_ascii=False,indent=4,
            separators=(',', ': '))
    return json_string
<|endoftext|>


<commit_before># Modified disorderBook_main.py for use with the C backend. Work in progress...

import json
import optparse
import subprocess

try:
    from bottle import request, response, route, run
except ImportError:
    from bottle_0_12_9 import request, response, route, run     # copy in our repo

# ----------------------------------------------------------------------------------------

INT_MAX = 2147483647

all_venues = dict()         # dict: venue string ---> dict: stock string ---> PIPE
account_ints = dict()       # dict: account string ---> unique int
current_book_count = 0

auth = dict()

direction_ints = {"buy": 1, "sell": 2}
orderType_ints = {"limit": 1, "market": 2, "fill-or-kill": 3, "fok": 3, "immediate-or-cancel": 4, "ioc": 4}

# ----------------------------------------------------------------------------------------

BAD_JSON = {"ok": False, "error": "Incoming data was not valid JSON"}
BOOK_ERROR = {"ok": False, "error": "Book limit exceeded! (See command line options)"}
NO_AUTH_ERROR = {"ok": False, "error": "Server is in +authentication mode but no API key was received"}
AUTH_FAILURE = {"ok": False, "error": "Unknown account or wrong API key"}
AUTH_WEIRDFAIL = {"ok": False, "error": "Account of stored data had no associated API key (this is impossible)"}
NO_SUCH_ORDER = {"ok": False, "error": "No such order for that Exchange + Symbol combo"}
MISSING_FIELD = {"ok": False, "error": "Incoming POST was missing required field"}
URL_MISMATCH = {"ok": False, "error": "Incoming POST data disagreed with request URL"}
BAD_TYPE = {"ok": False, "error": "A value in the POST had the wrong type"}
BAD_VALUE = {"ok": False, "error": "Illegal value (usually a non-positive number)"}

# ----------------------------------------------------------------------------------------

class TooManyBooks (Exception):
    pass

class NoApiKey (Exception):
    pass

def dict_from_exception(e):
    di = dict()
    di["ok"] = False
    di["error"] = str(e)
    return di

def create_book_if_needed(venue, symbol):
    global current_book_count

    if venue not in all_venues:
        if opts.maxbooks > 0:
            if current_book_count + 1 > opts.maxbooks:
                raise TooManyBooks
        all_venues[venue] = dict()

    if symbol not in all_venues[venue]:
        if opts.maxbooks > 0:
            if current_book_count + 1 > opts.maxbooks:
                raise TooManyBooks
        all_venues[venue][symbol] = subprocess.Popen(['disorderCook.exe', venue, symbol],
                                                     shell = False,
                                                     stdin = subprocess.PIPE,
                                                     stdout = subprocess.PIPE,
                                                    )
        current_book_count += 1

def api_key_from_headers(headers):
    try:
        return headers.get('X-Starfighter-Authorization')
    except:
        try:
            return headers.get('X-Stockfighter-Authorization')
        except:
            raise NoApiKey

def get_response_from_process(proc, message):
    assert(isinstance(message, str))

    if not message.endswith("\n"):
        message += "\n"

    b_message = bytes(message, encoding="ascii")

    proc.stdin.write(b_message)
    proc.stdin.flush()

    return str(proc.stdout.readline(), encoding="ascii")

# ----------------------------------------------------------------------------------------

@route("/ob/api/venues/<venue>/stocks/<symbol>/orders", "POST")
def make_order(venue, symbol):

    try:
        data = str(request.body.read(), encoding="utf-8")
        data = json.loads(data)
    except:
        response.status = 400
        return BAD_JSON

    try:

        # Thanks to cite-reader for the following bug-fix:
        # Match behavior of real Stockfighter: recognize both these forms

        if "stock" in data:
            symbol_in_data = data["stock"]
        elif "symbol" in data:
            symbol_in_data = data["symbol"]
        else:
            symbol_in_data = symbol

        # Note that official SF handles POSTs that lack venue and stock/symbol (using the URL instead)

        if "venue" in data:
            venue_in_data = data["venue"]
        else:
            venue_in_data = venue

        # Various types of faulty POST...

        if venue_in_data != venue or symbol_in_data != symbol:
            response.status = 400
            return URL_MISMATCH

        try:
            account = data["account"]
            price = int(data["price"])
            qty = int(data["qty"])
            orderType = data["orderType"]       # FIXME should also accept lowercase ordertype
            direction = data["direction"]
        except KeyError as k:
            response.status = 400
            return MISSING_FIELD
        except TypeError:
            response.status = 400
            return BAD_TYPE

        if price < 0 or price > INT_MAX:
            response.status = 400
            return BAD_VALUE
        if qty < 1 or qty > INT_MAX:
            response.status = 400
            return BAD_VALUE
        if direction not in ("buy", "sell"):
            response.status = 400
            return BAD_VALUE
        if orderType not in ("limit", "market", "fill-or-kill", "immediate-or-cancel", "fok", "ioc"):
            response.status = 400
            return BAD_VALUE

        try:
            create_book_if_needed(venue, symbol)
        except TooManyBooks:
            response.status = 400
            return BOOK_ERROR

        if auth:

            try:
                apikey = api_key_from_headers(request.headers)
            except NoApiKey:
                response.status = 401
                return NO_AUTH_ERROR

            if account not in auth:
                response.status = 401
                return AUTH_FAILURE

            if auth[account] != apikey:
                response.status = 401
                return AUTH_FAILURE

        if account not in account_ints:
            account_ints[account] = len(account_ints)

        # Now call the process and get a response...

        message = "ORDER {} {} {} {} {}".format(account_ints[account], qty, price, direction_ints[direction], orderType_ints[orderType])
        proc = all_venues[venue][symbol]

        raw_response = get_response_from_process(proc, message)

        response.headers["Content-Type"] = "application/json"
        return raw_response

    except Exception as e:
        response.status = 500
        return dict_from_exception(e)

# ----------------------------------------------------------------------------------------

def create_auth_records():
    global auth
    global opts

    with open(opts.accounts_file) as infile:
        auth = json.load(infile)

def main():
    global opts

    opt_parser = optparse.OptionParser()

    opt_parser.add_option(
        "-b", "--maxbooks",
        dest = "maxbooks",
        type = "int",
        help = "Maximum number of books (exchange/ticker combos) [default: %default]")
    opt_parser.set_defaults(maxbooks = 100)

    opt_parser.add_option(
        "-v", "--venue",
        dest = "default_venue",
        type = "str",
        help = "Default venue; always exists [default: %default]")
    opt_parser.set_defaults(default_venue = "TESTEX")

    opt_parser.add_option(
        "-s", "--symbol", "--stock",
        dest = "default_symbol",
        type = "str",
        help = "Default symbol; always exists on default venue [default: %default]")
    opt_parser.set_defaults(default_symbol = "FOOBAR")

    opt_parser.add_option(
        "-a", "--accounts",
        dest = "accounts_file",
        type = "str",
        help = "File containing JSON dict of account names mapped to their API keys [default: none]")
    opt_parser.set_defaults(accounts_file = "")

    opt_parser.add_option(
        "-p", "--port",
        dest = "port",
        type = "int",
        help = "Port [default: %default]")
    opt_parser.set_defaults(port = 8000)

    opts, __ = opt_parser.parse_args()

    create_book_if_needed(opts.default_venue, opts.default_symbol)

    if opts.accounts_file:
        create_auth_records()

    print("disorderCook starting up...\n")
    if not auth:
        print(" -----> Warning: running WITHOUT AUTHENTICATION! <-----\n")

    run(host = "127.0.0.1", port = opts.port)

if __name__ == "__main__":
    main()
<commit_msg>accept lowercase "ordertype"<commit_after># Modified disorderBook_main.py for use with the C backend. Work in progress...

import json
import optparse
import subprocess

try:
    from bottle import request, response, route, run
except ImportError:
    from bottle_0_12_9 import request, response, route, run     # copy in our repo

# ----------------------------------------------------------------------------------------

INT_MAX = 2147483647

all_venues = dict()         # dict: venue string ---> dict: stock string ---> PIPE
account_ints = dict()       # dict: account string ---> unique int
current_book_count = 0

auth = dict()

direction_ints = {"buy": 1, "sell": 2}
orderType_ints = {"limit": 1, "market": 2, "fill-or-kill": 3, "fok": 3, "immediate-or-cancel": 4, "ioc": 4}

# ----------------------------------------------------------------------------------------

BAD_JSON = {"ok": False, "error": "Incoming data was not valid JSON"}
BOOK_ERROR = {"ok": False, "error": "Book limit exceeded! (See command line options)"}
NO_AUTH_ERROR = {"ok": False, "error": "Server is in +authentication mode but no API key was received"}
AUTH_FAILURE = {"ok": False, "error": "Unknown account or wrong API key"}
AUTH_WEIRDFAIL = {"ok": False, "error": "Account of stored data had no associated API key (this is impossible)"}
NO_SUCH_ORDER = {"ok": False, "error": "No such order for that Exchange + Symbol combo"}
MISSING_FIELD = {"ok": False, "error": "Incoming POST was missing required field"}
URL_MISMATCH = {"ok": False, "error": "Incoming POST data disagreed with request URL"}
BAD_TYPE = {"ok": False, "error": "A value in the POST had the wrong type"}
BAD_VALUE = {"ok": False, "error": "Illegal value (usually a non-positive number)"}

# ----------------------------------------------------------------------------------------

class TooManyBooks (Exception):
    pass

class NoApiKey (Exception):
    pass

def dict_from_exception(e):
    di = dict()
    di["ok"] = False
    di["error"] = str(e)
    return di

def create_book_if_needed(venue, symbol):
    global current_book_count

    if venue not in all_venues:
        if opts.maxbooks > 0:
            if current_book_count + 1 > opts.maxbooks:
                raise TooManyBooks
        all_venues[venue] = dict()

    if symbol not in all_venues[venue]:
        if opts.maxbooks > 0:
            if current_book_count + 1 > opts.maxbooks:
                raise TooManyBooks
        all_venues[venue][symbol] = subprocess.Popen(['disorderCook.exe', venue, symbol],
                                                     shell = False,
                                                     stdin = subprocess.PIPE,
                                                     stdout = subprocess.PIPE,
                                                    )
        current_book_count += 1

def api_key_from_headers(headers):
    try:
        return headers.get('X-Starfighter-Authorization')
    except:
        try:
            return headers.get('X-Stockfighter-Authorization')
        except:
            raise NoApiKey

def get_response_from_process(proc, message):
    assert(isinstance(message, str))

    if not message.endswith("\n"):
        message += "\n"

    b_message = bytes(message, encoding="ascii")

    proc.stdin.write(b_message)
    proc.stdin.flush()

    return str(proc.stdout.readline(), encoding="ascii")

# ----------------------------------------------------------------------------------------

@route("/ob/api/venues/<venue>/stocks/<symbol>/orders", "POST")
def make_order(venue, symbol):

    try:
        data = str(request.body.read(), encoding="utf-8")
        data = json.loads(data)
    except:
        response.status = 400
        return BAD_JSON

    try:

        # Thanks to cite-reader for the following bug-fix:
        # Match behavior of real Stockfighter: recognize both these forms

        if "stock" in data:
            symbol_in_data = data["stock"]
        elif "symbol" in data:
            symbol_in_data = data["symbol"]
        else:
            symbol_in_data = symbol

        # Note that official SF handles POSTs that lack venue and stock/symbol (using the URL instead)

        if "venue" in data:
            venue_in_data = data["venue"]
        else:
            venue_in_data = venue

        # Various types of faulty POST...

        if venue_in_data != venue or symbol_in_data != symbol:
            response.status = 400
            return URL_MISMATCH

        try:
            account = data["account"]
            price = int(data["price"])
            qty = int(data["qty"])
            if "orderType" in data:
                orderType = data["orderType"]
            else:
                orderType = data["ordertype"]
            direction = data["direction"]
        except KeyError:
            response.status = 400
            return MISSING_FIELD
        except TypeError:
            response.status = 400
            return BAD_TYPE

        if price < 0 or price > INT_MAX:
            response.status = 400
            return BAD_VALUE
        if qty < 1 or qty > INT_MAX:
            response.status = 400
            return BAD_VALUE
        if direction not in ("buy", "sell"):
            response.status = 400
            return BAD_VALUE
        if orderType not in ("limit", "market", "fill-or-kill", "immediate-or-cancel", "fok", "ioc"):
            response.status = 400
            return BAD_VALUE

        try:
            create_book_if_needed(venue, symbol)
        except TooManyBooks:
            response.status = 400
            return BOOK_ERROR

        if auth:

            try:
                apikey = api_key_from_headers(request.headers)
            except NoApiKey:
                response.status = 401
                return NO_AUTH_ERROR

            if account not in auth:
                response.status = 401
                return AUTH_FAILURE

            if auth[account] != apikey:
                response.status = 401
                return AUTH_FAILURE

        if account not in account_ints:
            account_ints[account] = len(account_ints)

        # Now call the process and get a response...

        message = "ORDER {} {} {} {} {}".format(account_ints[account], qty, price, direction_ints[direction], orderType_ints[orderType])
        proc = all_venues[venue][symbol]

        raw_response = get_response_from_process(proc, message)

        response.headers["Content-Type"] = "application/json"
        return raw_response

    except Exception as e:
        response.status = 500
        return dict_from_exception(e)

# ----------------------------------------------------------------------------------------

def create_auth_records():
    global auth
    global opts

    with open(opts.accounts_file) as infile:
        auth = json.load(infile)

def main():
    global opts

    opt_parser = optparse.OptionParser()

    opt_parser.add_option(
        "-b", "--maxbooks",
        dest = "maxbooks",
        type = "int",
        help = "Maximum number of books (exchange/ticker combos) [default: %default]")
    opt_parser.set_defaults(maxbooks = 100)

    opt_parser.add_option(
        "-v", "--venue",
        dest = "default_venue",
        type = "str",
        help = "Default venue; always exists [default: %default]")
    opt_parser.set_defaults(default_venue = "TESTEX")

    opt_parser.add_option(
        "-s", "--symbol", "--stock",
        dest = "default_symbol",
        type = "str",
        help = "Default symbol; always exists on default venue [default: %default]")
    opt_parser.set_defaults(default_symbol = "FOOBAR")

    opt_parser.add_option(
        "-a", "--accounts",
        dest = "accounts_file",
        type = "str",
        help = "File containing JSON dict of account names mapped to their API keys [default: none]")
    opt_parser.set_defaults(accounts_file = "")

    opt_parser.add_option(
        "-p", "--port",
        dest = "port",
        type = "int",
        help = "Port [default: %default]")
    opt_parser.set_defaults(port = 8000)

    opts, __ = opt_parser.parse_args()

    create_book_if_needed(opts.default_venue, opts.default_symbol)

    if opts.accounts_file:
        create_auth_records()

    print("disorderCook starting up...\n")
    if not auth:
        print(" -----> Warning: running WITHOUT AUTHENTICATION! <-----\n")

    run(host = "127.0.0.1", port = opts.port)

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""Class to gather and analyse various metal line statistics"""

import numpy as np
import hdfsim
import math
import halocat
import spectra
import matplotlib.pyplot as plt

class HaloSpectra(spectra.Spectra):
    """Generate metal line spectra from simulation snapshot"""
    def __init__(self,num, base, repeat = 3, minpart = 400, nbins = 1024, cloudy_dir="/home/spb/codes/ArepoCoolingTables/tmp_spb/"):
        #Load halos to push lines through them
        f = hdfsim.get_file(num, base, 0)
        self.OmegaM = f["Header"].attrs["Omega0"]
        self.box = f["Header"].attrs["BoxSize"]
        self.npart=f["Header"].attrs["NumPart_Total"]+2**32*f["Header"].attrs["NumPart_Total_HighWord"]
        min_mass = self.min_halo_mass(minpart)
        f.close()
        (ind, self.sub_mass, cofm, self.sub_radii) = halocat.find_wanted_halos(num, base, min_mass)
        self.NumLos = np.size(self.sub_mass)*repeat
        #All through y axis
        axis = np.ones(self.NumLos)
        axis[self.NumLos/3:2*self.NumLos/3] = 2
        axis[2*self.NumLos/3:self.NumLos] = 3
        cofm = np.repeat(cofm,repeat,axis=0)
        axis = np.repeat(axis,repeat/3)
        #Perturb the sightlines within a sphere of half the virial radius.
        #We want a representative sample of DLAs.
        maxr = self.sub_radii/2.
        #Generate random sphericals
        theta = 2*math.pi*np.random.random_sample(self.NumLos)-math.pi
        phi = 2*math.pi*np.random.random_sample(self.NumLos)
        rr = np.repeat(maxr,repeat)*np.random.random_sample(self.NumLos)
        #Add them to halo centers
        cofm[:,0]+=rr*np.sin(theta)*np.cos(phi)
        cofm[:,1]+=rr*np.sin(theta)*np.sin(phi)
        cofm[:,2]+=rr*np.cos(theta)
        #Re-seed for repeatability
        np.random.seed(23)

        spectra.Spectra.__init__(self,num, base, cofm, axis, nbins, cloudy_dir)

    def min_halo_mass(self, minpart = 400):
        """Min resolved halo mass in internal Gadget units (1e10 M_sun)"""
        #This is rho_c in units of h^-1 1e10 M_sun (kpc/h)^-3
        rhom = 2.78e+11* self.OmegaM / 1e10 / (1e3**3)
        #Mass of an SPH particle, in units of 1e10 M_sun, x omega_m/ omega_b.
        target_mass = self.box**3 * rhom / self.npart[0]
        min_mass = target_mass * minpart
        return min_mass
<commit_msg>Fix repeating<commit_after># -*- coding: utf-8 -*-
"""Class to gather and analyse various metal line statistics"""

import numpy as np
import hdfsim
import math
import halocat
import spectra
import matplotlib.pyplot as plt

class HaloSpectra(spectra.Spectra):
    """Generate metal line spectra from simulation snapshot"""
    def __init__(self,num, base, repeat = 3, minpart = 400, nbins = 1024, cloudy_dir="/home/spb/codes/ArepoCoolingTables/tmp_spb/"):
        #Load halos to push lines through them
        f = hdfsim.get_file(num, base, 0)
        self.OmegaM = f["Header"].attrs["Omega0"]
        self.box = f["Header"].attrs["BoxSize"]
        self.npart=f["Header"].attrs["NumPart_Total"]+2**32*f["Header"].attrs["NumPart_Total_HighWord"]
        min_mass = self.min_halo_mass(minpart)
        f.close()
        (ind, self.sub_mass, cofm, self.sub_radii) = halocat.find_wanted_halos(num, base, min_mass)
        self.NumLos = np.size(self.sub_mass)
        #All through y axis
        axis = np.ones(self.NumLos)
        axis[self.NumLos/3:2*self.NumLos/3] = 2
        axis[2*self.NumLos/3:self.NumLos] = 3
        cofm = np.repeat(cofm,repeat,axis=0)
        axis = np.repeat(axis,repeat)
        self.NumLos*=repeat
        #Perturb the sightlines within a sphere of half the virial radius.
        #We want a representative sample of DLAs.
        maxr = self.sub_radii/2.
        #Generate random sphericals
        theta = 2*math.pi*np.random.random_sample(self.NumLos)-math.pi
        phi = 2*math.pi*np.random.random_sample(self.NumLos)
        rr = np.repeat(maxr,repeat)*np.random.random_sample(self.NumLos)
        #Add them to halo centers
        cofm[:,0]+=rr*np.sin(theta)*np.cos(phi)
        cofm[:,1]+=rr*np.sin(theta)*np.sin(phi)
        cofm[:,2]+=rr*np.cos(theta)
        #Re-seed for repeatability
        np.random.seed(23)

        spectra.Spectra.__init__(self,num, base, cofm, axis, nbins, cloudy_dir)

    def min_halo_mass(self, minpart = 400):
        """Min resolved halo mass in internal Gadget units (1e10 M_sun)"""
        #This is rho_c in units of h^-1 1e10 M_sun (kpc/h)^-3
        rhom = 2.78e+11* self.OmegaM / 1e10 / (1e3**3)
        #Mass of an SPH particle, in units of 1e10 M_sun, x omega_m/ omega_b.
        target_mass = self.box**3 * rhom / self.npart[0]
        min_mass = target_mass * minpart
        return min_mass
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
def foo():
    r = some_function()
    if r == (-1):
        return(-1)
    return r
def bar():
    r = foo()
    if r == (-1):
        print('Error')
    else:
        pass
#一旦出错，还要一级一级上报，除此之外，可以使用try..except..finall
try:
    print('try...')
    r = 10 / 0
    print('result',r)
except ZeroDivisionError as e:
    print('except:',e)
finally:
    print('finally...')
print('END')
<commit_msg>161128<commit_after># -*- coding: utf-8 -*-
def foo():
    r = some_function()
    if r == (-1):
        return(-1)
    return r
def bar():
    r = foo()
    if r == (-1):
        print('Error')
    else:
        pass
#一旦出错，还要一级一级上报，除此之外，可以使用try..except..finall
try:
    print('try...')
    r = 10 / 2
    print('result',r)
except ZeroDivisionError as e:
    print('except:',e)
finally:
    print('finally...')
print('END')
#当某些代码执行有可能发生错误的时候，可以用try运行该类代码，此时一旦try当中遇到错误，则跳转到except后面代码执行
#然后在执行finally后面的代码，无论是否执行except，都会执行finally后面代码
try:
    print('try...')
    r = 10 / int('a')
    print('result:',r)
except ValueError as e:
    print('ValueError:',e)
except ZeroDivisionError as e:
    print('ZeroDivisionError:',e)
else:print('no error')
finally:
    print('finally...')
print('END')
#可以使用多个except来执行错误发现，如上
def foo(s):
    return 10 / int(s)
def bar(s):
    return foo(s)*2
def main():
    bar('0')
#    try:
#        print(bar('0'))
#    except Exception as e:
#        print('Error:',e)
#    finally:
#        print('finally...')
#main()
#对于多层调用的情况，只需要在调用层进行捕获操作，即可确认问题出现
#如果不用try的话，错误会一直向上抛，直到最终错误出现的代码，可以确认错误从哪里出现
#但是一旦出现错误的话，程序就会异常结束，这样没意义，应当让python打印出错误来
import logging
def foo(s):
    return 10 / int(s)
def bar(s):
    return foo(s)*2
def main():
    try:
        bar('0')
    except Exception as e:
        logging.exception(e)
main()
print('END')
#通过日志记录，可以让问题打印，但是不暂停执行程序，程序正常执行完毕之后才会退出
#抛出错误可以自定义错误的类，然后执行：
<|endoftext|>


<commit_before>import gi, random
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject

class HangmanWindow(Gtk.Window):
    def __init__(self, dictionary_file_name):
        Gtk.Window.__init__(self, title="Hangman")
        self.set_size_request(800, 800)

        self.timeout_id=None

        self.hangman_figure_list=["hangman_figures/Hangman0.png",
                                  "hangman_figures/Hangman1.png",
                                  "hangman_figures/Hangman2.png",
                                  "hangman_figures/Hangman3.png",
                                  "hangman_figures/Hangman4.png",
                                  "hangman_figures/Hangman5.png",
                                  "hangman_figures/Hangman6.png",
                                  "hangman_figures/Hangman7.png"]
        self.dictionary_file_name = dictionary_file_name
        self.hangman_game = HangmanGame(dictionary_file_name)

        main_hbox = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL, spacing = 6)
        self.add(main_hbox)

        self.hangman_image=Gtk.Image.new_from_file("hangman_figures/Hangman0.png")
        main_hbox.pack_start(self.hangman_image, True, True, 0)

        vbox=Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        main_hbox.pack_start(vbox, True, True, 0)

        self.print_entry = Gtk.Label()
        vbox.pack_start(self.print_entry, True, True, 0)

        self.input_dialog=Gtk.Label()
        vbox.pack_start(self.input_dialog, True, True, 0)

        letters_hbox=Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
        vbox.pack_start(letters_hbox, True, True, 0)

        self.letter_spaces=Gtk.Label()
        letters_hbox.pack_start(self.letter_spaces, True, True, 0)

        self.guessed_letters_entry=Gtk.Label()
        letters_hbox.pack_start(self.guessed_letters_entry, True, True, 0)

        self.new_guess = Gtk.Entry()
        self.new_guess.set_max_length(1)
        self.new_guess.connect("activate", self.submit_guess)
        self.new_guess.connect("changed", self.update_guess_text)
        vbox.pack_start(self.new_guess, True, True, 0)

        hbox=Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
        vbox.pack_start(hbox, True, True, 0)

        self.submit_button = Gtk.Button.new_with_label("Submit")
        self.submit_button.connect("clicked", self.submit_guess)
        hbox.pack_start(self.submit_button, True, True, 0)

        self.new_game_button=Gtk.Button.new_with_label("Start New Game")
        self.new_game_button.connect("clicked", self.start_new_game)
        hbox.pack_start(self.new_game_button,True, True, 0)

        self.draw_screen("Welcome to Hangman")

    def submit_guess(self, button):
        guess = self.new_guess.get_text()
        output = self.hangman_game.guess_letter(guess)
        print("guessing " + guess)
        self.draw_screen(output)

    def update_guess_text(self, new_guess):
        user_input=self.new_guess.get_text()
        user_input=user_input.lower()
        if self.hangman_game.is_game_over():
            self.input_dialog.set_text("Game Over")
        elif user_input in self.hangman_game.guessed_letters:
            self.input_dialog.set_text("You have already guessed that!")
        elif user_input=='':
            self.input_dialog.set_text("Guess the next letter!")
        elif not user_input.isalpha():
            self.input_dialog.set_text("Invalid input!")
        else:
            self.input_dialog.set_text("Submit to guess " + user_input + "?")

    def draw_screen(self, last_guess_string):
        self.print_entry.set_text(last_guess_string)
        self.new_guess.set_text('')
        output=list()
        self.hangman_image.set_from_file(self.hangman_figure_list[
            self.hangman_game.total_incorrect_guesses])
        for i in self.hangman_game.guessed_letters:
            if i not in self.hangman_game.hangman_word:
                output.append(i)
        output.sort()
        output=" ,".join(output)

        self.guessed_letters_entry.set_text(output)
        self.letter_spaces.set_text(self.guessed_letters_string())

    def guessed_letters_string(self):
        output=list(self.hangman_game.hangman_word)
        for i in range(0, len(output)):
            if output[i] not in self.hangman_game.guessed_letters:
                output[i] = '_'
        output = "".join(output)
        return output

    def start_new_game(self, button):
        print("Starting a new game")
        self.hangman_game = HangmanGame(self.dictionary_file_name)
        self.draw_screen("Welcome to Hangman")

class HangmanGame():
    def __init__(self, dictionary_file_name):
        with open(dictionary_file_name) as f:
            self.dictionary =f.read().split()
        self.total_incorrect_guesses=0
        self.guessed_letters=set()
        self.hangman_word=random.choice(self.dictionary)
        self.unguessed_letters=set(self.hangman_word)
        self.max_guesses=7

    def is_game_over(self):
        if (len(self.unguessed_letters)==0 or
            self.total_incorrect_guesses>=self.max_guesses):
            return True
        else:
            return False

    def guess_letter(self, guess):
        guess=guess.lower()
        if not self.is_game_over():
            if(len(guess) > 1 or not guess.isalpha()):
                return_string = "Invalid response, stay in the spirit of the game."

            elif guess in self.guessed_letters:
                return_string =  'You already guessed that!'

            elif guess in self.unguessed_letters:
                self.unguessed_letters.remove(guess)
                self.guessed_letters.add(guess)
                return_string = 'You chose wisely'

            else:
                self.total_incorrect_guesses += 1
                self.guessed_letters.add(guess)
                return_string = 'You chose poorly'

        if(len(self.unguessed_letters) == 0):
            return_string = "You win!!"

        elif(self.total_incorrect_guesses >= self.max_guesses):
            return_string = "You have lost"

        return return_string

win=HangmanWindow("hangman_words.txt")
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
<commit_msg>Print the word when game is lost<commit_after>import gi, random
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject

class HangmanWindow(Gtk.Window):
    def __init__(self, dictionary_file_name):
        Gtk.Window.__init__(self, title="Hangman")
        self.set_size_request(800, 800)

        self.timeout_id=None

        self.hangman_figure_list=["hangman_figures/Hangman0.png",
                                  "hangman_figures/Hangman1.png",
                                  "hangman_figures/Hangman2.png",
                                  "hangman_figures/Hangman3.png",
                                  "hangman_figures/Hangman4.png",
                                  "hangman_figures/Hangman5.png",
                                  "hangman_figures/Hangman6.png",
                                  "hangman_figures/Hangman7.png"]
        self.dictionary_file_name = dictionary_file_name
        self.hangman_game = HangmanGame(dictionary_file_name)

        main_hbox = Gtk.Box(orientation = Gtk.Orientation.HORIZONTAL, spacing = 6)
        self.add(main_hbox)

        self.hangman_image=Gtk.Image.new_from_file("hangman_figures/Hangman0.png")
        main_hbox.pack_start(self.hangman_image, True, True, 0)

        vbox=Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        main_hbox.pack_start(vbox, True, True, 0)

        self.print_entry = Gtk.Label()
        vbox.pack_start(self.print_entry, True, True, 0)

        self.input_dialog=Gtk.Label()
        vbox.pack_start(self.input_dialog, True, True, 0)

        letters_hbox=Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
        vbox.pack_start(letters_hbox, True, True, 0)

        self.letter_spaces=Gtk.Label()
        letters_hbox.pack_start(self.letter_spaces, True, True, 0)

        self.guessed_letters_entry=Gtk.Label()
        letters_hbox.pack_start(self.guessed_letters_entry, True, True, 0)

        self.new_guess = Gtk.Entry()
        self.new_guess.set_max_length(1)
        self.new_guess.connect("activate", self.submit_guess)
        self.new_guess.connect("changed", self.update_guess_text)
        vbox.pack_start(self.new_guess, True, True, 0)

        hbox=Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
        vbox.pack_start(hbox, True, True, 0)

        self.submit_button = Gtk.Button.new_with_label("Submit")
        self.submit_button.connect("clicked", self.submit_guess)
        hbox.pack_start(self.submit_button, True, True, 0)

        self.new_game_button=Gtk.Button.new_with_label("Start New Game")
        self.new_game_button.connect("clicked", self.start_new_game)
        hbox.pack_start(self.new_game_button,True, True, 0)

        self.draw_screen("Welcome to Hangman")

    def submit_guess(self, button):
        guess = self.new_guess.get_text()
        output = self.hangman_game.guess_letter(guess)
        print("guessing " + guess)
        self.draw_screen(output)

    def update_guess_text(self, new_guess):
        user_input=self.new_guess.get_text()
        user_input=user_input.lower()
        if self.hangman_game.is_game_over():
            self.input_dialog.set_text("Game Over")
        elif user_input in self.hangman_game.guessed_letters:
            self.input_dialog.set_text("You have already guessed that!")
        elif user_input=='':
            self.input_dialog.set_text("Guess the next letter!")
        elif not user_input.isalpha():
            self.input_dialog.set_text("Invalid input!")
        else:
            self.input_dialog.set_text("Submit to guess " + user_input + "?")

    def draw_screen(self, last_guess_string):
        self.print_entry.set_text(last_guess_string)
        self.new_guess.set_text('')
        output=list()
        self.hangman_image.set_from_file(self.hangman_figure_list[
            self.hangman_game.total_incorrect_guesses])
        for i in self.hangman_game.guessed_letters:
            if i not in self.hangman_game.hangman_word:
                output.append(i)
        output.sort()
        output=" ,".join(output)

        self.guessed_letters_entry.set_text(output)
        self.letter_spaces.set_text(self.guessed_letters_string())

    def guessed_letters_string(self):
        output=list(self.hangman_game.hangman_word)
        for i in range(0, len(output)):
            if output[i] not in self.hangman_game.guessed_letters:
                output[i] = '_'

        output = "".join(output)

        if self.hangman_game.total_incorrect_guesses==7:
            output=str("You word was: \n" + self.hangman_game.hangman_word)

        return output

    def start_new_game(self, button):
        print("Starting a new game")
        self.hangman_game = HangmanGame(self.dictionary_file_name)
        self.draw_screen("Welcome to Hangman")

class HangmanGame():
    def __init__(self, dictionary_file_name):
        with open(dictionary_file_name) as f:
            self.dictionary =f.read().split()
        self.total_incorrect_guesses=0
        self.guessed_letters=set()
        self.hangman_word=random.choice(self.dictionary)
        self.unguessed_letters=set(self.hangman_word)
        self.max_guesses=7

    def is_game_over(self):
        if (len(self.unguessed_letters)==0 or
            self.total_incorrect_guesses>=self.max_guesses):
            return True
        else:
            return False

    def guess_letter(self, guess):
        guess=guess.lower()
        if not self.is_game_over():
            if(len(guess) > 1 or not guess.isalpha()):
                return_string = "Invalid response, stay in the spirit of the game."

            elif guess in self.guessed_letters:
                return_string =  'You already guessed that!'

            elif guess in self.unguessed_letters:
                self.unguessed_letters.remove(guess)
                self.guessed_letters.add(guess)
                return_string = 'You chose wisely'

            else:
                self.total_incorrect_guesses += 1
                self.guessed_letters.add(guess)
                return_string = 'You chose poorly'

        if(len(self.unguessed_letters) == 0):
            return_string = "You win!!"

        elif(self.total_incorrect_guesses >= self.max_guesses):
            return_string = "You have lost"

        return return_string

win=HangmanWindow("hangman_words.txt")
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
<|endoftext|>


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

import logging
import asyncio
import re
import os
import sys
import hangups

import settings

from models.user import User
from models.conversation import Conversation
from models.message import Message
from models.command import Command

from utils.commands import register_commands
from utils.enums import EventType, ConversationType
from utils.textutils import spacing

from datetime import datetime

logger = logging.getLogger(__name__)
logging.basicConfig(format="%(name)s - %(levelname)s: %(asctime)s | %(message)s")
logger.setLevel(logging.DEBUG)

class HangoutsBot(object):

    def __init__(self):
        self.command_matcher = re.compile(settings.COMMAND_MATCH_REGEX)
        register_commands()
        self.client = hangups.client.Client(self.login())
        self.user = User.get_or_create(id=settings.BOT_ID, defaults={'first_name': 'Bot', 'last_name': 'User'})[0]

    def login(self):
        return hangups.auth.get_auth_stdin(settings.COOKIES_FILE_PATH)

    def run(self):
        logger.debug(self.client)
        self.client.on_state_update.add_observer(self.handle_update)
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.client.connect())

    @asyncio.coroutine
    def handle_update(self, state_update):
        logger.debug("Handling event update")
        if state_update.event_notification.event.event_type == EventType.EVENT_TYPE_REGULAR_CHAT_MESSAGE.value:
            yield from self.handle_message(state_update)
        else:
            pass

    @asyncio.coroutine
    def handle_message(self, state_update):
        logger.debug("Handling message")
        conversation = self.get_or_create_conversation(state_update.conversation)
        if state_update.event_notification.event.sender_id.gaia_id == settings.BOT_ID:
            message = Message.create(conversation=conversation, user=self.user, text="".join(
                [seg.text for seg in state_update.event_notification.event.chat_message.message_content.segment]), time=datetime.now())
            message.conversation.logger.info(message.text, extra={
                "username": message.user.username,
                "message_time": datetime.strftime(message.time, "%Y-%m-%d %X"),
            })
            return True
        self.check_conversation_participants(state_update.conversation)
        try:
            sending_user = User.get(User.id == state_update.event_notification.event.sender_id.gaia_id)
        except User.DoesNotExist:
            user_id = state_update.event_notification.event.sender_id.gaia_id
            sending_user = self.create_user_from_id(user_id, state_update.conversation)
        message_body = ""
        for seg in state_update.event_notification.event.chat_message.message_content.segment:
            message_body += seg.text
        message = Message.create(conversation=conversation, user=sending_user, text=message_body, time=datetime.now())
        message.conversation.logger.info(message.text, extra={
            "username": message.user.username,
            "message_time": datetime.strftime(message.time, "%Y-%m-%d %X"),
        })

        matched = self.command_matcher.match(message.text)
        if matched:
            try:
                cmd_to_run = Command.get(name=matched.group(1))
                yield from cmd_to_run.run(bot=self, conversation=message.conversation, user=message.user, args=message.text.split()[1:])
            except Command.DoesNotExist:
                pass
        return True

    def create_user_from_id(self, user_id, conversation):
        logger.debug("Creating User with id {}".format(user_id))
        participant_object = None
        for participant in conversation.participant_data:
            if participant.id.gaia_id == user_id:
                participant_object = participant
                break
        name_split = participant_object.fallback_name.split(" ", 1)
        if len(name_split) > 1:
            user = User.create(id=user_id, first_name=name_split[0], last_name=name_split[1])
        else:
            user = User.create(id=user_id, first_name=name_split[0], last_name="")
        return user

    def get_or_create_conversation(self, conversation):
        try:
            conv = Conversation.get(Conversation.id == conversation.conversation_id.id)
        except Conversation.DoesNotExist:
            logger.debug("Creating Conversation with id {}".format(conversation.conversation_id.id))
            is_group = conversation.type == ConversationType.CONVERSATION_TYPE_GROUP.value
            conv = Conversation.create(id=conversation.conversation_id.id, group=is_group)
        return conv

    def check_conversation_participants(self, conversation):
        logger.debug("Checking Conversation participants")
        conv = self.get_or_create_conversation(conversation)
        for participant in conversation.participant_data:
            try:
                user = User.get(User.id == participant.id.gaia_id)
            except User.DoesNotExist:
                user = self.create_user_from_id(participant.id.gaia_id, conversation)
            if user not in conv.members:
                logger.debug("Adding User {} to Conversation {}".format(user.id, conv.id))
                conv.members.add(user)
        return True

    @asyncio.coroutine
    def send_message(self, conversation, message, filter_to_use):
        if filter_to_use == "spacing":
            message = spacing(message)
        request = hangups.hangouts_pb2.SendChatMessageRequest(
            request_header=self.client.get_request_header(),
            event_request_header=hangups.hangouts_pb2.EventRequestHeader(
                conversation_id=hangups.hangouts_pb2.ConversationId(
                    id=conversation.id
                ),
                client_generated_id=self.client.get_client_generated_id(),
            ),
            message_content=hangups.hangouts_pb2.MessageContent(
                segment=[hangups.ChatMessageSegment(message).serialize()],
            ),
        )
        try:
            yield from self.client.send_chat_message(request)
        except:
            logger.error("Unable to send message to {} with text '{}'".format(conversation, message))

if __name__ == "__main__":
    print("Run the bot using the manage.py file: ./manage.py run")
<commit_msg>replace newlines with space<commit_after>#!/usr/bin/env python3

import logging
import asyncio
import re
import os
import sys
import hangups

import settings

from models.user import User
from models.conversation import Conversation
from models.message import Message
from models.command import Command

from utils.commands import register_commands
from utils.enums import EventType, ConversationType
from utils.textutils import spacing

from datetime import datetime

logger = logging.getLogger(__name__)
logging.basicConfig(format="%(name)s - %(levelname)s: %(asctime)s | %(message)s")
logger.setLevel(logging.DEBUG)

class HangoutsBot(object):

    def __init__(self):
        self.command_matcher = re.compile(settings.COMMAND_MATCH_REGEX)
        register_commands()
        self.client = hangups.client.Client(self.login())
        self.user = User.get_or_create(id=settings.BOT_ID, defaults={'first_name': 'Bot', 'last_name': 'User'})[0]

    def login(self):
        return hangups.auth.get_auth_stdin(settings.COOKIES_FILE_PATH)

    def run(self):
        logger.debug(self.client)
        self.client.on_state_update.add_observer(self.handle_update)
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.client.connect())

    @asyncio.coroutine
    def handle_update(self, state_update):
        logger.debug("Handling event update")
        if state_update.event_notification.event.event_type == EventType.EVENT_TYPE_REGULAR_CHAT_MESSAGE.value:
            yield from self.handle_message(state_update)
        else:
            pass

    @asyncio.coroutine
    def handle_message(self, state_update):
        logger.debug("Handling message")
        conversation = self.get_or_create_conversation(state_update.conversation)
        if state_update.event_notification.event.sender_id.gaia_id == settings.BOT_ID:
            message = Message.create(conversation=conversation, user=self.user, text="".join(
                [seg.text for seg in state_update.event_notification.event.chat_message.message_content.segment]), time=datetime.now())
            message.conversation.logger.info(message.text.replace("\n", " "), extra={
                "username": message.user.username,
                "message_time": datetime.strftime(message.time, "%Y-%m-%d %X"),
            })
            return True
        self.check_conversation_participants(state_update.conversation)
        try:
            sending_user = User.get(User.id == state_update.event_notification.event.sender_id.gaia_id)
        except User.DoesNotExist:
            user_id = state_update.event_notification.event.sender_id.gaia_id
            sending_user = self.create_user_from_id(user_id, state_update.conversation)
        message_body = ""
        for seg in state_update.event_notification.event.chat_message.message_content.segment:
            message_body += seg.text
        message = Message.create(conversation=conversation, user=sending_user, text=message_body, time=datetime.now())
        message.conversation.logger.info(message.text.replace("\n", " "), extra={
            "username": message.user.username,
            "message_time": datetime.strftime(message.time, "%Y-%m-%d %X"),
        })

        matched = self.command_matcher.match(message.text)
        if matched:
            try:
                cmd_to_run = Command.get(name=matched.group(1))
                yield from cmd_to_run.run(bot=self, conversation=message.conversation, user=message.user, args=message.text.split()[1:])
            except Command.DoesNotExist:
                pass
        return True

    def create_user_from_id(self, user_id, conversation):
        logger.debug("Creating User with id {}".format(user_id))
        participant_object = None
        for participant in conversation.participant_data:
            if participant.id.gaia_id == user_id:
                participant_object = participant
                break
        name_split = participant_object.fallback_name.split(" ", 1)
        if len(name_split) > 1:
            user = User.create(id=user_id, first_name=name_split[0], last_name=name_split[1])
        else:
            user = User.create(id=user_id, first_name=name_split[0], last_name="")
        return user

    def get_or_create_conversation(self, conversation):
        try:
            conv = Conversation.get(Conversation.id == conversation.conversation_id.id)
        except Conversation.DoesNotExist:
            logger.debug("Creating Conversation with id {}".format(conversation.conversation_id.id))
            is_group = conversation.type == ConversationType.CONVERSATION_TYPE_GROUP.value
            conv = Conversation.create(id=conversation.conversation_id.id, group=is_group)
        return conv

    def check_conversation_participants(self, conversation):
        logger.debug("Checking Conversation participants")
        conv = self.get_or_create_conversation(conversation)
        for participant in conversation.participant_data:
            try:
                user = User.get(User.id == participant.id.gaia_id)
            except User.DoesNotExist:
                user = self.create_user_from_id(participant.id.gaia_id, conversation)
            if user not in conv.members:
                logger.debug("Adding User {} to Conversation {}".format(user.id, conv.id))
                conv.members.add(user)
        return True

    @asyncio.coroutine
    def send_message(self, conversation, message, filter_to_use):
        if filter_to_use == "spacing":
            message = spacing(message)
        request = hangups.hangouts_pb2.SendChatMessageRequest(
            request_header=self.client.get_request_header(),
            event_request_header=hangups.hangouts_pb2.EventRequestHeader(
                conversation_id=hangups.hangouts_pb2.ConversationId(
                    id=conversation.id
                ),
                client_generated_id=self.client.get_client_generated_id(),
            ),
            message_content=hangups.hangouts_pb2.MessageContent(
                segment=[hangups.ChatMessageSegment(message).serialize()],
            ),
        )
        try:
            yield from self.client.send_chat_message(request)
        except:
            logger.error("Unable to send message to {} with text '{}'".format(conversation, message))

if __name__ == "__main__":
    print("Run the bot using the manage.py file: ./manage.py run")
<|endoftext|>


<commit_before>"""
Demonstrates implementation of SHA1 Hash function in a Python class and gives utilities
to find hash of string or hash of text from a file.
Usage: python sha1.py --string "Hello World Welcome to Cryptography"
       pyhton sha1.py --file "hello_world.txt"
       Without any arguments prints the hash of the string "Hello World"
Also contains a Test class to verify that the generated Hash is same as that
returned by the hashlib library
Reference: https://deadhacker.com/2006/02/21/sha-1-illustrated/

The Algorithm as described in the reference:
First we start with a message. The message is padded and the length of the message
is added to the end. It is then split into blocks of 512 bits. The blocks are then
processed one at a time. Each block must be expanded and compressed.
The value after each compression is added to a 160bit buffer called the current hash
state. After the last block is processed the current hash state is returned as
the final hash.
"""

import argparse
import hashlib #hashlib is only used inside the Test class

class SHA1:
    """
    Class to contain the entire pipeline for SHA1 Hashing Algorithm
    """
    def __init__(self, data):
        self.data = data
        self.current_hash = ''

    def padding(self):
        return

    def split_block(self):
        return

    def expand_block(self):
        return

    def compress_block(self):
        return

    def final_hash(self):
        assert True #everything done till now
        # return self.current_hash
        return hashlib.sha1(bytes(self.data, 'utf-8')).hexdigest()

class SHA1Test:
    """
    Test class for the SHA1 class
    """
    def __init__(self, data):
        self.data = data

    def calculated_hash(self):
        return SHA1(self.data).final_hash()

    def hashlib_hash(self):
        return hashlib.sha1(self.data.byte_encode()).hexdigest()

    def byte_encode(self):
        return bytes(self.data, 'utf-8')

    def match_hashes(self):
        # self.assertEqual(self.calculated_hash(), self.hashlib_hash())
        return self.calculated_hash() == self.hashlib_hash()

def run_test_case(hash_input = 'Hello World'):
    """
    Pulled this out of main because we probably dont want to run the Unit Test
    each time we want to calculate hash.
    """
    print(SHA1Test(hash_input).match_hashes())

def main():
    parser = argparse.ArgumentParser(description='Process some strings or files')
    parser.add_argument('--string', dest='input_string', default='Hello World',
                        help='Hash the string')
    parser.add_argument('--file', dest='input_file', help='Hash contents of a file')
    args = parser.parse_args()
    input_string = args.input_string
    if args.input_file:
        hash_input = open(args.input_file, 'r').read()
    else:
        hash_input = input_string
    print(SHA1(hash_input).final_hash())

if __name__ == '__main__':
    main()
<commit_msg>moved constants inside the class<commit_after>"""
Demonstrates implementation of SHA1 Hash function in a Python class and gives utilities
to find hash of string or hash of text from a file.
Usage: python sha1.py --string "Hello World Welcome to Cryptography"
       pyhton sha1.py --file "hello_world.txt"
       Without any arguments prints the hash of the string "Hello World"
Also contains a Test class to verify that the generated Hash is same as that
returned by the hashlib library

The Algorithm as described in the reference:
First we start with a message. The message is padded and the length of the message
is added to the end. It is then split into blocks of 512 bits. The blocks are then
processed one at a time. Each block must be expanded and compressed.
The value after each compression is added to a 160bit buffer called the current hash
state. After the last block is processed the current hash state is returned as
the final hash.
Reference: https://deadhacker.com/2006/02/21/sha-1-illustrated/
"""

import argparse
import hashlib #hashlib is only used inside the Test class

class SHA1Hash:
    """
    Class to contain the entire pipeline for SHA1 Hashing Algorithm
    """

    H0 - 01100111010001010010001100000001
    H1 - 11101111110011011010101110001001
    H2 - 10011000101110101101110011111110
    H3 - 00010000001100100101010001110110
    H4 - 11000011110100101110000111110000

    def __init__(self, data):
        self.data = data
        self.current_hash = ''

    def padding(self):
        return

    def split_block(self):
        return

    def expand_block(self):
        return

    def compress_block(self):
        return

    def final_hash(self):
        return 'This is in my To Do list'

class SHA1HashTest:
    """
    Test class for the SHA1 class
    """
    def __init__(self, data):
        self.data = data

    def calculated_hash(self):
        return SHA1Hash(self.data).final_hash()

    def hashlib_hash(self):
        return hashlib.sha1(self.data.byte_encode()).hexdigest()

    def byte_encode(self):
        return bytes(self.data, 'utf-8')

    def match_hashes(self):
        # self.assertEqual(self.calculated_hash(), self.hashlib_hash())
        return self.calculated_hash() == self.hashlib_hash()

def run_test_case(hash_input = 'Hello World'):
    """
    Pulled this out of main because we probably dont want to run the Test
    each time we want to calculate hash.
    """
    print(SHA1HashTest(hash_input).match_hashes())

def main():
    parser = argparse.ArgumentParser(description='Process some strings or files')
    parser.add_argument('--string', dest='input_string', default='Hello World',
                        help='Hash the string')
    parser.add_argument('--file', dest='input_file', help='Hash contents of a file')
    args = parser.parse_args()
    input_string = args.input_string
    if args.input_file:
        hash_input = open(args.input_file, 'r').read()
    else:
        hash_input = input_string
    print(SHA1Hash(hash_input).final_hash())

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# vim: tabstop=4 softtabstop=4 shiftwidth=4 textwidth=80 smarttab expandtab
import psutil
import os
import sys
import subprocess
import time

VIM_EXTENSIONS = ( 'c', 'cpp', 'sh', 'cs', 'py', 'pl', 'rb', 'js' )

def setColor(c):
    blynux_bin = 'blynux'
    cmd = [blynux_bin, '--device', '0', '--color', c]
    subprocess.call(cmd)

def is_vim_coding(proc):
    if proc.name != 'vim':
        return False
    fname = proc.cmdline[1]
    i = fname.rfind('.')
    if i < 0:
        f = open(fname, 'r')
        if f.read(2) == '#!':
            return True
    elif fname[i+1:] in VIM_EXTENSIONS:
        return True
    return False

timeout = 15
timer = 0
busy = False
setColor('green')
try:
    while True:
        vim_found = False
        for proc in psutil.process_iter():
            if is_vim_coding(proc):
                vim_found = True
                break

        if vim_found:
            if not busy:
                setColor('red')
                busy = True
                timer = timeout

        elif busy and timer > 0:
            timer = timer - 1
            if timer == 0:
                busy = False
                setColor('green')

        time.sleep(1)
except:
    pass

<commit_msg>Find the open vim file in the correct directory<commit_after>#!/usr/bin/env python
# vim: tabstop=4 softtabstop=4 shiftwidth=4 textwidth=80 smarttab expandtab
import psutil
import os
import sys
import subprocess
import time

VIM_EXTENSIONS = ( 'c', 'cpp', 'sh', 'cs', 'py', 'pl', 'rb', 'js' )

def setColor(c):
    blynux_bin = 'blynux'
    cmd = [blynux_bin, '--device', '0', '--color', c]
    subprocess.call(cmd)

def is_vim_coding(proc):
    if proc.name != 'vim':
        return False
    fname = proc.cmdline[1]
    i = fname.rfind('.')
    if i < 0:
        try:
            ffname = proc.getcwd() + os.sep + fname
            f = open(ffname, 'r')
            if f.read(2) == '#!':
                return True
        except:
            pass
    elif fname[i+1:] in VIM_EXTENSIONS:
        return True
    return False

timeout = 15
timer = 0
busy = False
setColor('green')
try:
    while True:
        vim_found = False
        for proc in psutil.process_iter():
            if is_vim_coding(proc):
                vim_found = True
                break

        if vim_found:
            if not busy:
                setColor('red')
                busy = True
                timer = timeout

        elif busy and timer > 0:
            timer = timer - 1
            if timer == 0:
                busy = False
                setColor('green')

        time.sleep(1)
except KeyboardInterrupt:
    pass

<|endoftext|>