import copy
import bidict
import math
import wfa.wfa_exceptions as wfa_exceptions

from typing import List, Optional, Set, TypeVar, Generic, Callable
from collections import deque, defaultdict

StateType = TypeVar("StateType")
SymbolType = TypeVar("SymbolType")
StateFloatMapType = dict[StateType, float]
StateFloatMapOptType = Optional[dict[StateType, float]]
TransFunctionType = dict[StateType, dict[SymbolType, Set[StateType]]]

class Transition(Generic[StateType, SymbolType]):
    """!
    Class for the represention of a WFA transition.
    """

    def __init__(self, src: StateType, dest: StateType, sym: SymbolType, weight: float):
        """!
        Constructor

        @param src: Source state
        @param dest: Destination state
        @param sym: Symbol
        @param weight: Weight of the transition
        """
        self.src = src
        self.dest = dest
        self.symbol = sym
        self.weight = weight
        self.count = 0

    def __str__(self) -> str:
        """!
        String representation

        @return String representation of the transition
        """
        return "({0}, {1}, {2}, {3})".format(self.src, self.dest, self.symbol, self.weight)

    def __repr__(self) -> str:
        """!
        String representation

        @return String representation of the transition
        """
        return self.__str__()

    def __eq__(self, other: object) -> bool:
        """!
        Equality of two transitions

        @param other: Other transition

        @return True -- both transitions are equal
        """
        if not isinstance(other, Transition):
            raise NotImplementedError("__eq__ for this type of object is not defined")
        return (self.src == other.src) and (self.dest == other.dest) and (self.symbol == other.symbol) and (self.weight == other.weight)

    def __ne__(self, other: object) -> bool:
        """!
        Inequality of two transitions

        @param other: Other transition

        @return True -- both transitions are NOT equal
        """
        return not self.__eq__(other)

    def __hash__(self):
        """!
        Hash method

        @return Hash
        """
        return hash((self.src, self.dest, self.symbol, self.weight))

class CoreWFA(Generic[StateType, SymbolType]):
    """!
    Basic class for representation of WFA
    """

    def __init__(self, transitions: List[Transition]=None, finals: StateFloatMapOptType=None, start: StateFloatMapType = dict(), alphabet: Optional[List[SymbolType]]=None):
        """!
        Constructor

        @param transitions: Transitions
        @param finals: Final states with weights
        @param start: Initial state
        @param alphabet: Alphabet
        """
        self._transitions: List[Transition] = []
        if transitions is None:
            self._transitions = []
        else:
            self._transitions = transitions

        self._finals: StateFloatMapType = dict()
        if finals is None:
            self._finals = dict()
        else:
            self._finals = finals

        # if start is None:
        #     self._start = {0: 1.0}
        # else:
        self._start = start
        self._states_dict = None

        self._alphabet: List[SymbolType] = []
        if alphabet is None:
            self._alphabet = self.get_alphabet()
        else:
            self._alphabet = alphabet
        self._states: List[StateType] = self._get_states()

    def __eq__(self, other: object) -> bool:
        """!
        Equality of two WFAs

        @param other: Other WFA

        @return True -- both WFAs are equal
        """
        if not isinstance(other, CoreWFA):
            raise NotImplementedError("__eq__ for this type of object is not defined")
        return (self._transitions == other._transitions) and \
            (self._finals == other._finals) and \
            (self._start == other._start) and \
            (self._alphabet == other._alphabet)

    def __hash__(self):
        """!
        Hash method

        @return Hash
        """
        return hash((tuple(self._transitions), tuple(self._finals), tuple(self._start), tuple(self._alphabet)))

    def get_transitions(self) -> List[Transition]:
        """!
        Get all transitions of the WFA.

        @return List of all transitions
        """
        return self._transitions

    def set_all_finals(self) -> None:
        """!
        Set all states to be final (all having the accepting weight 1.0)
        """
        self._finals = dict()
        for st in self.get_states():
            self._finals[st] = 1.0

    def get_finals(self) -> StateFloatMapType:
        """!
        Get all final states of the WFA.

        @return Final states with accepting weights -- Dictionary: Final state -> float (weight)
        """
        return self._finals

    def set_finals(self, finals: StateFloatMapType) -> None:
        """!
        Set final states of the WFA.

        @param finals: Dictionary of final states and their weight of accepting.
        """
        self._finals = finals

    def get_starts(self) -> StateFloatMapType:
        """!
        Get the start state (only one start state is allowed).

        @return Start state.
        """
        return self._start

    def set_starts(self, start: StateFloatMapType):
        """!
        Set the initial state.

        @param start: New initial state
        """
        self._start = start

    def set_alphabet(self, alph: List[SymbolType]) -> None:
        """!
        Set the alphabet

        @param alph: New alphabet
        """
        self._alphabet = alph

    def get_alphabet(self) -> List[SymbolType]:
        """!
        Get alphabet used by the WFA. If the alphabet is not explicitly
        given (in constructor), the alphabet is computed from the transitions.

        @return List of symbols.
        """
        alph: List[SymbolType] = []
        if self._alphabet != None and len(self._alphabet) > 0:
            return self._alphabet
        for transition in self._transitions:
            if transition.symbol not in alph:
                alph.append(transition.symbol)
        return alph

    def rename_alphabet(self, dct):
        """!
        Rename alphabet of the automaton (in place).

        @param dct: Mapping of the new symbols
        """
        self._alphabet = None
        tran = list()

        self._transitions = list(map (lambda x: Transition(x.src, x.dest, \
            dct.inverse[x.symbol], x.weight), self._transitions))

    def _get_states(self) -> List[StateType]:
        """!
        Get all states of the WFA (the list of states is computed from the
        transitions).

        @return List of states.
        """
        states = set([])
        for start, _ in self._start.items():
            if start not in states:
                states.add(start)
        for final, _ in self._finals.items():
            if final not in states:
                states.add(final)
        for transition in self._transitions:
            if transition.src not in states:
                states.add(transition.src)
            if transition.dest not in states:
                states.add(transition.dest)

        self._states = list(states)
        return list(states)

    def get_states(self) -> List[StateType]:
        """!
        Get all states of the WFA (the list of states is computed from the
        transitions).

        @return List of states.
        """
        return self._states

    def get_rename_dict(self) -> Optional[dict[object, object]]:
        """!
        Get the dictionary containing original state labels and renamed state
        labels. The dictionary is created after method rename_states is invoked.

        @return Dictionary: State (original) -> State (renamed).
        """
        return self._states_dict

    def get_single_dictionary_transitions(self) -> dict[StateType, List[Transition]]:
        """!
        Get the transitions (ommiting transitions that differ only on the
        symbol) in the form of dictinary (for each state there is a list of
        transitions leading from this state).

        @return Dictionary assigning State -> List(Transitions)
        """
        tr_dict: dict[StateType, List[Transition]] = dict()
        destinations: dict[StateType, Set[StateType]] = dict()

        states = self.get_states()
        for st in states:
            tr_dict[st] = []
            destinations[st] = set([])

        for transition in self._transitions:
            if transition.dest not in destinations[transition.src]:
                tr_dict[transition.src].append(transition)
                destinations[transition.src].add(transition.dest)
        return tr_dict

    def get_dictionary_transitions(self) -> dict[StateType, List[Transition]]:
        """!
        Get transitions in the form of dictionary (for each state there is a
        list of transitions leading from this state).

        @return Dictionary assigning State -> List(Transitions)
        """
        tr_dict: dict[StateType, List[Transition]] = dict()

        states = self.get_states()
        for st in states:
            tr_dict[st] = []

        for transition in self._transitions:
            tr_dict[transition.src].append(transition)
        return tr_dict

    def get_state_symbol_dict(self) -> TransFunctionType:
        """!
        Get transitions in the form of dictionary (for each state there is a
        dictionary assigning to symbols a set of transitions)

        @return Dictionary assigning State -> (Dictionary: Symbol -> Set of transitions)
        """
        tr_dict: TransFunctionType = dict()

        states = self.get_states()
        for st in states:
            tr_dict[st] = dict()

        for transition in self._transitions:
            try:
                tr_dict[transition.src][transition.symbol].add(transition)
            except KeyError:
                tr_dict[transition.src][transition.symbol] = set([transition])
        return tr_dict

    def get_rev_transitions_aut(self) -> "CoreWFA":
        """!
        Get automaton with reversed directions of transitios.

        @return WFA with reversed transitions.
        """
        rev_transitions = []
        for transition in self.get_transitions():
            rev_transitions.append(Transition(transition.dest, transition.src, \
                transition.symbol, transition.weight))

        return CoreWFA(rev_transitions, copy.copy(self._finals), copy.copy(self._start), copy.copy(self.get_alphabet()))

    def rename_states(self):
        """!
        Rename states of the WFA. Assign to the states numbers from 0 to n-1 (n
        is the number of states). The start state has number 0. The renamed and
        original states are stored in the states_dict dictionary.
        """
        self._states_dict = dict()
        new_transitions = []
        new_finals = dict()
        new_starts = dict()
        count = 0

        for st, weight in self._start.items():
            self._states_dict[st] = count
            new_starts[count] = weight
            count += 1

        for state in self.get_states():
            if state not in self._states_dict:
                self._states_dict[state] = count
                count += 1

        for (state, prob) in self._finals.items():
            dest = self._states_dict[state]
            new_finals[dest] = prob

        for transition in self._transitions:
            new_transitions.append(Transition( \
                self._states_dict[transition.src], \
                self._states_dict[transition.dest], \
                transition.symbol, transition.weight))

        self._transitions = new_transitions
        self._finals = new_finals
        self._start = new_starts
        self._states = self._get_states()

    def product(self, aut: "CoreWFA") -> "CoreWFA":
        """!
        Perform the product of two WFAs.

        @param aut: Second automaton for the product.

        @return WFA representing the product of WFAs
        """
        #queue = deque([])
        queue = []
        ret_finals = dict()
        ret_start = dict()
        ret_transitions = []

        self_finals = set(self._finals.keys())
        aut_finals = set(aut.get_finals().keys())

        for st1, weight1 in self._start.items():
            for st2, weight2 in aut.get_starts().items():
                queue.append((st1, st2))
                ret_start[(st1, st2)] = weight1 * weight2

        finished = set([])
        tr_dict1 = self.get_dictionary_transitions()
        tr_dict2 = aut.get_dictionary_transitions()

        while len(queue) > 0:
            act = queue.pop(0)
            finished.add(act)

            if (act[0] in self_finals) \
                and (act[1] in aut_finals):
                ret_finals[act] = self._finals[act[0]] \
                    * aut.get_finals()[act[1]]

            for tr1 in tr_dict1[act[0]]:
                for tr2 in tr_dict2[act[1]]:
                    if tr2.symbol != tr1.symbol:
                        continue

                    dest_state = (tr1.dest, tr2.dest)
                    ret_transitions.append(Transition(act, dest_state, \
                        tr1.symbol, tr1.weight * tr2.weight))

                    if (dest_state not in finished): #and (dest_state not in queue):
                        queue.append(dest_state)

        alphabet = set(self.get_alphabet()) & set(aut.get_alphabet())
        return CoreWFA(ret_transitions, ret_finals, ret_start, list(alphabet))

    def breadth_first_search(self, state: StateType, visited: Set[StateType], tr_dict: dict[StateType, List[Transition]]):
        """!
        BFS in the automaton graph.

        @param state: The start state of the BFS.
        @param visited: The list of visited states (out parameter).
        @param tr_dict: Transition dictionary.

        @return Out parameter visited (the list of visited states).
        """
        queue = deque([state])
        if tr_dict is None:
            tr_dict = self.get_single_dictionary_transitions()
        while queue:
            head = queue.popleft()
            visited.add(head)
            for transition in tr_dict[head]:
                if (transition.dest not in visited) \
                    and (transition.dest not in queue):
                    queue.append(transition.dest)

    def get_coaccessible_states(self, tr_dict: Optional[dict[StateType, List[Transition]]]=None) -> Set[StateType]:
        """!
        Get coaccessible states of the WFA.

        @param tr_dict: Transition dictionary.

        @return The list of coaccessible states.
        """
        visited: Set[StateType] = set([])
        reverse_aut = self.get_rev_transitions_aut()
        if tr_dict is None:
            tr_dict = reverse_aut.get_single_dictionary_transitions()
        for state, _ in reverse_aut.get_finals().items():
            reverse_aut.breadth_first_search(state, visited, tr_dict)
        return visited

    def get_accessible_states(self, tr_dict: Optional[dict[StateType, List[Transition]]]=None) -> Set[StateType]:
        """!
        Get accessible states of the WFA.

        @param tr_dict: Transition dictionary.

        @return The list of accessible states.
        """
        visited: Set[StateType] = set([])
        if tr_dict is None:
            tr_dict = self.get_single_dictionary_transitions()
        for state, _ in self.get_starts().items():
            self.breadth_first_search(state, visited, tr_dict)
        return visited

    def get_automata_restriction(self, states: Set[StateType]) -> "CoreWFA":
        """!
        Get WFA restriction to only states in states.

        @param states: The list of states of the new WFA.

        @return WFA (restriction to states in the list states)
        """
        rest_transitions = []
        rest_finals = dict()
        rest_initials = dict()
        alphabet = self.get_alphabet()
        for transition in self._transitions:
            if (transition.src in states) and (transition.dest in states):
                rest_transitions.append(Transition(transition.src, transition.dest,\
                    transition.symbol, transition.weight))

        for state, weight in self._finals.items():
            if state in states:
                rest_finals[state] = weight

        #Since some NFA formalisms do not allow an NFA without an initial state,
        #if the list states do not contain any initial state, we add new initial
        #state (but only if the original NFA contains at least one intial state).
        for state, weight in self._start.items():
            if state in states:
                rest_initials[state] = weight
        if len(rest_initials) == 0 and len(self._start) > 0:
            single_ini = list(self._start.keys())[0]
            rest_initials[single_ini] = self._start[single_ini]

        return CoreWFA(rest_transitions, rest_finals,\
            rest_initials, alphabet)

    def get_trim_automaton(self) -> "CoreWFA":
        """!
        Get trimed WFA.

        @return Trimmed WFA.
        """
        sts = self.get_coaccessible_states() & self.get_accessible_states()
        return self.get_automata_restriction(sts)

    def get_predecessors(self, state: StateType) -> Set[StateType]:
        """!
        Operation that finds predessors of the state state.

        @param state: The state whose predessors are found.

        @return List of predecessors
        """
        ret = set([])
        transitions = self.get_transitions()
        for tr in transitions:
            if tr.dest == state:
                ret.add(tr.src)
        return ret

    def get_predecessors_transitions(self) -> dict[StateType, List[Transition]]:
        """!
        Get predecessors of all states of the WFA.

        @return Dict: State -> List(State)
        """
        predecessors: dict[StateType, List[Transition]] = {}
        for state in self.get_states():
            predecessors[state] = []

        for transition in self.get_transitions():
            predecessors[transition.dest].append(transition)

        return predecessors

    def is_deterministic(self) -> bool:
        """!
        Is the WFA deterministic

        @return True deterministic, otherwise False
        """
        if len(self._start) > 1:
            return False
        tr_dict = self.get_state_symbol_dict()
        for st, sym_dict in tr_dict.items():
            for symbol, trs in sym_dict.items():
                if len(trs) > 1:
                    return False
        return True

    def string_prob_deterministic(self, word: List[SymbolType]) -> Optional[float]:
        """!
        Compute the probability of the word word.

        @param word: Word

        @return Probability of word
        """
        prob = 0.0
        tr_dict = self.get_state_symbol_dict()
        act = list(self._start.keys())[0]
        prob = math.log(self._start[act])
        try:
            for sym in word:
                n_tr = list(tr_dict[act][sym])[0]
                prob += math.log(n_tr.weight)
                act = n_tr.dest
            prob += math.log(self._finals[act])
        except ValueError:
            return None
        except KeyError:
            return None
        return prob

    def map_symbols(self, fnc: Callable):
        """!
        Apply the function fnc on the symbols of all transitions

        @param fnc: Function applied on symbols
        """
        for tr in self.get_transitions():
            tr.symbol = fnc(tr.symbol)

    def get_most_probable_string(self) -> List[SymbolType]:
        """!
        Compute the most probable word of the DPA

        @return A word with a highest probability
        """

        assert(self.is_deterministic())

        val: dict[StateType, float] = defaultdict(lambda: 0.0)
        words: dict[StateType, List[SymbolType]] = dict()

        if len(self._finals) == 0:
            return [], 0.0

        for k, v in self._finals.items():
            val[k] = v
            words[k] = []

        changed = True
        while changed:
            changed = False
            for tr in self.get_transitions():
                if val[tr.src] < val[tr.dest]*tr.weight:
                    val[tr.src] = val[tr.dest]*tr.weight
                    words[tr.src] = [tr.symbol] + words[tr.dest]
                    changed = True

        ini = list(self._start.keys())[0]
        return words[ini], val[ini]

    def set_ones(self) -> None:
        """!
        Set the weight of all transitions to 1.0
        """

        for tr in self._transitions:
            tr.weight = 1.0

    def complete_wfa(self, trap: StateType) -> None:
        """!
        Complete the automaton. New transitions have the weight 0.0

        @param trap: New trap (sink) state (assuming not to be in the set of states)
        """

        alphabet = self.get_alphabet()
        trans = copy.deepcopy(self._transitions)

        succ = dict()
        for st in self.get_states():
            for al in alphabet:
                succ[(st,al)] = False

        for tr in self._transitions:
            succ[(tr.src,tr.symbol)] = True

        for k, v in succ.items():
            if not v:
                trans.append(Transition(k[0], trap, k[1], 0.0))

        for al in alphabet:
            trans.append(Transition(trap, trap, al, 0.0))
        self._transitions = trans
        self._states = self._get_states()

    def difference_dwfa(self, diff: "CoreWFA") -> "CoreWFA":
        """!
        Compute the difference weighted automaton. First, convert the second
        automaton to a complete WFA with all transitions 1.0. Then, switch the
        accepting states to obtain a complementary automaton. Finally, return the
        product with the original automaton.

        @param diff: Second automaton
        @return Difference automaton
        """

        assert(self.is_deterministic())
        assert(diff.is_deterministic())

        but = copy.deepcopy(diff)

        alp = set(but.get_alphabet() + self.get_alphabet())
        but.set_alphabet(list(alp))
        but.complete_wfa(-1)
        but.set_ones()

        nfin = dict()
        for st in but.get_states():
            if st not in but.get_finals():
                nfin[st] = 1.0
        but.set_finals(nfin)

        return self.product(but).get_trim_automaton()


#!/usr/bin/env python

from scipy.sparse import coo_matrix

class Matrix:
    """A sparse matrix class (indexed from zero). Replace with NumPy arrays."""
    def __init__(self, matrix=None, size=None):
        """Size is a tuple (m,n) representing m rows and n columns."""
        if matrix is None:
            self.data = {}
            if size is None:
                self.column_count = 0
                self.row_count = 0
                self.size = (self.row_count, self.column_count)
            else:
                self.row_count, self.column_count = size[:2]
                self.size = size
        else:
            """Initialize to be a clone of the given matrix."""
            self.column_count = matrix.column_count
            self.data = matrix.data
            self.row_count = matrix.row_count
            self.size = matrix.size

    def get(self, subscript):
        """Return the matrix element indexed by the given (valid) subscript."""
        row, column = subscript[:2]
        if self.__is_valid(subscript):
            # Get the value if it's present, else a zero.
            result = self.data.get(subscript, 0)
        else:
            raise IndexError
        return result

    def set(self, subscript, value):
        """Set the matrix element indexed by the given (valid) subscript."""
        if value != 0 and self.__is_valid(subscript):
            self.data[subscript] = value
        else:
            raise IndexError

    def __is_valid(self, subscript):
        """Return whether the given subscript is within the matrix's bounds."""
        return ((0,0) <= subscript and subscript < self.size)

    def __is_valid_row(self, row_number):
        """Return whether the given row is within the matrix's bounds."""
        return self.__is_valid((row_number, 0))

    def __str__(self):
        """Return a NumPy-like matrix representation."""
        result = ""
        for row in range(self.size):
            current = []
            for column in range(self.size):
                subscript = (row, column)
                current.append(self.get(subscript))
            if result == "":
                result = "[{}".format(current)
            else:
                result = "{0}\n {1}".format(result, current)
        return "{}]".format(result)

    def extend_columns(self, matrix):
        raise NotImplementedError

    def extend_rows(self, matrix):
        """Extend the current matrix with the given matrix."""
        row_count, column_count = matrix.size[:2]
        if column_count != self.column_count:
            raise ValueError
        self.row_count += row_count
        self.size = (self.row_count, self.column_count)
        base_row_count = self.row_count
        for key, value in matrix.data.items():
            row, column = key[:2]
            self.set((base_row_count + row, column), value)
        return self

    def replace_row(self, row_number, vector):
        """Replace the specified row with the given vector."""
        if not self.__is_valid_row(row_number):
            raise ValueError
        row_count, column_count = vector.size[:2]
        if row_count != 1 and column_count != 1:
            raise ValueError
        # Eliminate current row entries.
        for col in [col for (row, col) in self.data.items()
                    if row == row_number]:
            self.data.pop(row_number, col)
        # Update row with vector elements.
        if row_count == 1:
            new_row = vector.transpose()
        else:
            new_row = vector
        for key, value in new_row.data.items():
            row, _ = key[:2]
            self.set((row_number, row), value)
        return self

    def submatrix(self, row_set, column_set):
        """Return a submatrix with the given rows and columns."""
        submatrix = Matrix(len(row_set), len(column_set))
        raise NotImplementedError

    def to_vec(self):
        """Return an m*n length vector comprising all the matrix's columns."""
        column_count = self.column_count
        vector = Matrix(size=(self.row_count * column_count, 1))
        for key, value in self.data.items():
            row, column = key[:2]
            subscript = (column * column_count + row, 0)
            vector.set(subscript, value)
        return vector

    def to_ijv(self):
        """Return the matrix in ijv (triplet) array format."""
        row_indices = []
        column_indices = []
        nonzero_elements = []
        k = 0
        for key, value in self.data.items():
            if value == 0:
                continue
            row, col = key[:2]
            row_indices.append(row)
            column_indices.append(col)
            nonzero_elements.append(value)
            k += 1
        return row_indices, column_indices, nonzero_elements

    def to_coo_matrix(self):
        """Return the matrix in COOrdinate format."""
        row_indices, column_indices, nonzero_elements = self.to_ijv()
        return coo_matrix((nonzero_elements, (row_indices, column_indices)),
                          shape=(self.size, self.size))

    def transpose(self):
        """Transpose the matrix."""
        m, n = self.size[:2]
        transposed_size = (n, m)
        transposed_matrix = {}
        for key, value in matrix.data.items():
            i, j = key[:2]
            transposed_key = (j, i)
            transposed_matrix[transposed_key] = value
        self.matrix = transposed_matrix
        self.size = transposed_size


import csv
from django.http import HttpResponse
from django.contrib import admin
from django.contrib.auth.models import User, Group
from .models import UserExtend,Menu,VegOrNonVeg,Shop,FoodCategory, ShopPayment
# Register your models here.
admin.site.unregister(Group)
admin.site.site_header = 'CMOS Admin Page'
admin.site.site_title = 'CMOS Admin Page'
# admin.site.site_url = '/admin_new/'
class ExportCsvMixin:
    def export_as_csv(self, request, queryset):

        meta = self.model._meta
        field_names = [field.name for field in meta.fields]

        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
        writer = csv.writer(response)

        writer.writerow(field_names)
        for obj in queryset:
            row = writer.writerow([getattr(obj, field) for field in field_names])

        return response

    export_as_csv.short_description = "Export Selected"

class ShopPaymentAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = ['vendor', 'purchasedate', 'shop']

    # list_editable = ['status']
    # search_fields = ['user', 'cloth_menu']
    list_filter = ['vendor', 'shop', 'purchasedate']

    actions = ["export_as_csv"]

    def export_as_csv(self, request, queryset):
        meta = self.model._meta
        field_names = [field.name for field in meta.fields]

        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
        writer = csv.writer(response)

        writer.writerow(field_names)
        for obj in queryset:
            row = writer.writerow([getattr(obj, field) for field in field_names])

        return response

    export_as_csv.short_description = "Export Selected"

class ShopAdmin(admin.ModelAdmin, ExportCsvMixin):
    list_display = ['shop_name', 'shop_image', 'shop_description', 'shop_price', 'shop_size', 'shop_status', 'vendor']
    # list_editable = ['shop_description', 'shop_price', 'shop_size', 'shop_status', 'vendor']
    # # search_fields = ['user', 'cloth_menu']
    # list_filter = ['vendor']
    actions = ["export_as_csv"]

    def export_as_csv(self, request, queryset):
        meta = self.model._meta
        field_names = [field.name for field in meta.fields]

        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
        writer = csv.writer(response)

        writer.writerow(field_names)
        for obj in queryset:
            row = writer.writerow([getattr(obj, field) for field in field_names])

        return response

    export_as_csv.short_description = "Export Selected"

class UserExtends(admin.ModelAdmin):
    list_display = ['userref', 'gender', 'acceptance']
    list_editable = ['acceptance']

admin.site.register(Shop, ShopAdmin)
admin.site.register(VegOrNonVeg)
admin.site.register(Group)
admin.site.register(ShopPayment, ShopPaymentAdmin)
admin.site.register(UserExtend, UserExtends)


# kubectl_tool.py
# A langchain tool that use kubectl
#
from langchain.agents import Tool
from langchain.utilities import BashProcess
import json

def kubectl_tool(command) -> str:
    bash = BashProcess()
    result = bash.run(command)
    return result

name = "kubectl_tool"
description = "This is a tool for kubernetes cluster. The input is the kubectl command with jsonpath-as-json format, e.g. kubectl get pod --output=jsonpath-as-json={{.items..metadata.name}}  The output will be a JSON data structure."

# create an instance of the custom langchain tool
Kubectl = Tool(
    name=name,
    func=kubectl_tool,
    description=description,
    return_direct=False
)

if __name__ == '__main__':
    print(kubectl_tool("kubectl get pod"))


from datetime import date

from nominations.models import ArtNomination, VocalNomination

def base_context(request):
	start = False

	dte = date.today()
	dte_deadline = date(2023,10,13)
	register_block = True
	if dte<dte_deadline:
		register_block = False

	if not request.user.is_authenticated:
		start = True

	arts = ArtNomination.objects.all()
	vocals = VocalNomination.objects.all()

	args = {
		'start': start,
		'register_block': register_block,
		'arts': arts,
		'vocals': vocals
	}

	return args


"""@package AFolder.py
Created 2023-04-27

@author: castells
@description:

When this is ran, it prepares a staging area with all the folders for each experiment.
It also prepares the experiments.json file and places it in the default directory.

When it is ran again, only newly created experiment folders are added.
Folders are not removed.

If a new structure is needed, we may want to rebuild a  new staging area and rerun the programs

The staging area is a metadata folder with a folder per experiment.

This is for experiments only.
I am not sure metdata is experiment.

"""

import json

import os
import stat
import sys
import _connect
import settings

class Expt:
    """The class that will define an experiment and we can use that to make the folder. The row is the result of a query in the table
    SELECT id, field_id, code, name, start_year, end_year, glten_id, key_ref_code, purpose, description, folder
    FROM eraSandpit.dbo.experiments;

    """
    def __init__(self, row):
        self.experiment_name = row.name
        self.KeyRefCode = row.key_ref_code
        self.exptID = row.code
        self.folder =  ''.join(ch for ch in row.code if ch.isalnum()).lower()
        self.station = self.folder[0]

    def asExptJson(self):
        '''
        "exptID": "rcs408",
        "Title": "Miscanthus sinensis giganteus study",
        "station": "r"
        '''
        expt =  {
              "Experiment": self.experiment_name,
              "KeyRefCode": self.KeyRefCode,
              "exptID": self.folder,
              "expt_Code": self.exptID,
              "ExptFolder": self.folder,
              "Title": self.experiment_name,
              "station": self.station
            }
        return expt

    '''
    def mkExptDir(self):
        status = " created"
        newDir = settings.STAGE+'metadata/'+self.exptID
        if not os.path.isdir(newDir):
            os.makedirs(newDir,  exist_ok = True)
            os.chmod(newDir, stat.S_IRWXO)
            status = " created"
        else:
            os.chmod(newDir, stat.S_IRWXO)
            status = " here"
        return newDir + status
    '''

def getExperiments():
    """This gets the experiments. We only need experiments and farms

    SELECT id, field_id, code, name, start_year, end_year, glten_id, key_ref_code, purpose, description, folder
    FROM eraSandpit.dbo.experiments;

    """
    cnx = _connect.connect()
    cur = cnx.cursor()

    sql = f'Select * from experiments where glten_id > 0 order by name '
    cur.execute(sql)
    results = cur.fetchall()

    presults = []

    for row in results:
        presults.append(row)
    return presults #a list of named tuples that behave like a list of objects.

def makeJSON(results):
    expts =  []
    for row in results:
        ex = Expt(row)
        expts.append(ex.asExptJson())
    return expts

def makeIndexHtmlstr(newDir):
    '''idea to buid a specific html page to redirect people who are at the root of our directories to the actual experiment '''
    strIndex = 'copy index.html '+newDir+'\index.html'

    return strIndex

def makeDir(newDir):
    '''checks the directory location exists and if it does not, creates it and prepares a strings that tell us what it did'''
    status = " created"
    if not os.path.isdir(newDir):
        os.makedirs(newDir,  exist_ok = True)
        os.chmod(newDir, stat.S_IRWXO)
        status = " created"
    else:
        os.chmod(newDir, stat.S_IRWXO)
        status = " already here"
    return newDir + status

def makedirectories(results):

    testString = ""
    default = "metadata/default/"
    stations = ["default", "rothamsted", "broomsbarn", "woburn", "saxmundham"]
    experiments =  [ "met", "rms", "bms", "wms", "sms", "rro"]

    for item in stations:
        defaultDir = stage+'metadata/'+item
        testString += makeDir(defaultDir) +'\n'
    for item in experiments:
        exptDir = stage+'metadata/'+item
        testString += makeDir(exptDir) +'\n'
        exptRepoDir = repo+'metadata/'+item
        testString += makeDir(exptRepoDir) +'\n'

    for row in results:
        ex = Expt(row)
        exptDir = stage+'metadata/'+ex.folder
        testString += makeDir(exptDir) +'\n'
        exptRepoDir = repo+'metadata/'+ex.folder
        testString += makeDir(exptRepoDir) +'\n'

    return testString

def makeCopyString(results):

    copyList = []
    default = "metadata\\default\\"
    stations = ["default", "rothamsted", "broomsbarn", "woburn", "saxmundham"]
    experiments =  [ "met", "rms", "bms", "wms", "sms", "rro", "rrn2"]

    for item in stations:
        defaultDir = 'metadata\\'+item
        copyList.append(makeIndexHtmlstr(defaultDir))
    for item in experiments:
        exptDir = 'metadata\\'+item
        copyList.append(makeIndexHtmlstr(exptDir))

    for row in results:
        ex = Expt(row)
        exptDir = 'metadata\\'+ex.folder
        copyList.append(makeIndexHtmlstr(exptDir))

    return copyList

if __name__ == '__main__':
    #config = configparser.ConfigParser()
    #config.read('config.ini')

    # stage = "d:/eRAWebStage/eraGilbert01/"
    # repo = "d:/eRAWebRepo/repo08/"
    stage = settings.STAGE
    repo = settings.REPO
    #stage = config['STAGE']['STAGE']
    #repo = config['STAGE']['REPO']
    status = " created"
    #newDir = stage+'includes'
    newDir = stage+'metadata/default/'
    if not os.path.isdir(newDir):
        os.makedirs(newDir,  exist_ok = True)
        os.chmod(newDir, stat.S_IRWXO)
        status = " created"
    else:
        os.chmod(newDir, stat.S_IRWXO)
        status = " already here"
    print (newDir + status)

    results = getExperiments()
    expts = makeJSON(results)
    strJsonExpts =  json.dumps(expts, indent=4)
    xname = stage+'metadata/default/experiments.json'
    fxname = open(xname,'w+')
    fxname.write(strJsonExpts)
    fxname.close()
    print('Experiment file saved in '+xname)

    dirs = makedirectories(results)
    copyStr = []

    print(strJsonExpts)
    print("-----Directory Creation-----")
    print(dirs)

    settings.bye()
    exit = input(" All done - Hit return to close window")

    #cpLs = makeCopyString(results)
    #for lines in cpLs:
        #print(lines)


import os
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)

import config
from attributes_cleaner import NumAttributesCleaner
from attributes_cleaner import CatAttributesCleaner
from attributes_cleaner import CatAttributesEncoder

import joblib
import pandas as pd
import numpy as np

from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LinearRegression
from sklearn import metrics

def run(fold):
    df = pd.read_csv(config.AIRBNB_TRAIN_FOLDS_FILE).drop("id", axis=1)

    attribs = [f for f in df.columns if f not in ["price", "kfold"]]
    cat_attribs = ["zipcode",
                   "neighbourhood_cleansed",
                   "room_type",
                   "bed_type",
                   "cancellation_policy",
                   "security_deposit"]

    num_attribs = [f for f in attribs if f not in cat_attribs]

    df_train, df_valid = df[df.kfold != fold], df[df.kfold == fold]

    X_train, y_train = df_train[attribs].copy(), df_train["price"].copy()
    X_valid, y_valid = df_valid[attribs].copy(), df_valid["price"].copy()

    num_transformer = Pipeline([
        ("num_cleaner", NumAttributesCleaner(num_attribs)),
        ("std_scaler", StandardScaler())])

    cat_transformer = Pipeline([
        ("cat_cleaner", CatAttributesCleaner(cat_attribs)),
        ("cat_encoder", CatAttributesEncoder(cat_attribs))])

    transformer = ColumnTransformer([
        ("num", num_transformer, num_attribs),
        ("cat", cat_transformer, cat_attribs)])

    X_train_tr = transformer.fit_transform(X_train)
    X_valid_tr = transformer.transform(X_valid)

    model = LinearRegression()
    model.fit(X_train_tr, y_train)
    train_preds = model.predict(X_train_tr)
    valid_preds = model.predict(X_valid_tr)

    train_scores = {"r2_score": metrics.r2_score(y_train, train_preds),
                    "rmse_score": np.sqrt(metrics.mean_squared_error(y_train, train_preds))}

    valid_scores = {"r2_score": metrics.r2_score(y_valid, valid_preds),
                    "rmse_score": np.sqrt(metrics.mean_squared_error(y_valid, valid_preds))}

    print(f"Fold={fold} (train): ",
          f"r2_score = {train_scores['r2_score'].round(2)}", "--- ",
          f"rmse_score = {train_scores['rmse_score'].round(2)}")

    print(f"Fold={fold} (valid): ",
          f"r2_score = {valid_scores['r2_score'].round(2)}", "--- ",
          f"rmse_score = {valid_scores['rmse_score'].round(2)}")
    print("")
    joblib.dump(model, os.path.join(config.MODEL_OUTPUT, f"lr_{fold}.bin"))

if __name__ == "__main__":
    for fold in range(5):
        run(fold)


import sys
from itertools import combinations
import numpy as np

import lentil

class Field:
    """
    Two-dimensional discretely sampled complex field.

    Parameters
    ----------
    data : array_like
        Array containing the sampled field. Note that real-valued data is
        cast to complex.
    pixelscale : float or None, optional
        Data array spatial sampling. If None (default), the field is assumed to
        be broadcastable to any legal shape without interpolation.
    offset : (2,) array_like of ints or None, optional.
        Shift of the Field in (row, column) from (0, 0). If None (default),
        offset = (0, 0).
    tilt : list, optional
        List of objects which implement a ``shift`` method. This method should
        accept the following parameters:

        ``shift(xs, ys, z, wavelength)``

        and return an updated x and y shift. If None (default), tilt = [].

    """
    __slots__ = ('data', 'offset', 'tilt', '_pixelscale', '_extent')

    def __init__(self, data, pixelscale=None, offset=None, tilt=None):
        self.data = np.asarray(data, dtype=complex)
        self.pixelscale = pixelscale
        self.offset = offset if offset is not None else [0, 0]
        self.tilt = tilt if tilt else []
        self._extent = extent(self.shape, self.offset)

    @property
    def pixelscale(self):
        """
        Physical (row, col) sampling of each pixel in the Field.

        If ``pixelscale = ()``, the Field does not have a pixelscale and is
        assumed to be broadcastable to any legal shape without interpolation.

        Returns
        -------
        pixelscale : ndarray or None
        """
        return self._pixelscale

    @pixelscale.setter
    def pixelscale(self, value):
        if value is not None:
            self._pixelscale = lentil.sanitize_shape(value)
        else:
            self._pixelscale = ()

    @property
    def shape(self):
        """
        Tuple of Field dimensions

        Returns
        -------
        shape : tuple
        """
        return self.data.shape

    @property
    def ndim(self):
        """
        Number of Field dimensions

        Returns
        -------
        ndim : int
        """
        return self.data.ndim

    @property
    def size(self):
        """
        Number of elements in the Field

        Returns
        -------
        size : int
        """
        return self.data.size

    @property
    def extent(self):
        """
        The array indices defining the extent of the shifted Field.

        Returns
        -------
        rmin, rmax, cmin, cmax : int

        Notes
        -----
        To use the values returned by ``extent()`` in a slice, ``rmax`` and ``cmax``
        should be increased by 1.
        """
        return self._extent
        #return extent(self.shape, self.offset)

    def __mul__(self, other):
        return multiply(self, other)

    def overlap(self, other):
        """
        Returns True if two fields overlap

        Parameters
        ----------
        other : `~lentil.Field`
            Other Field to check for overlap.

        Returns
        -------
        overlap : bool
        """
        return overlap(self, other)

    def shift(self, z, wavelength, pixelscale, oversample, indexing='ij'):
        """
        Compute Field shift due to associated :class:`~lentil.Tilt` objects

        Parameters
        ----------
        z : float
            Propagation distance
        wavelength : float
            Wavelength
        pixelscale : (2,) float
            Output plane spatial sampling
        oversample : int
            Output plane oversampling factor
        indexing : {'ij', 'xy'}, optional
            Cartesian ('xy') or matrix ('ij', default) indexing of output.

        Returns
        -------
        shift : tuple of floats
            Shifted location of the center of the field

        Notes
        -----
        This function is capable of doing the conversion between the (x, y) coordinates
        of a Tilt and the (r, c) coordinates of a Field.

        """
        if indexing not in ('xy', 'ij'):
            raise ValueError("Valid values for `indexing` are 'xy' and 'ij'")

        if pixelscale is None:
            raise ValueError('pixelscale must be defined to compute shift')

        x, y = 0, 0

        for tilt in self.tilt:
            x, y = tilt.shift(xs=x, ys=y, z=z, wavelength=wavelength)

        pixelscale = lentil.sanitize_shape(pixelscale)
        out = x/pixelscale[0] * oversample, y/pixelscale[1] * oversample

        if indexing == 'ij':
            out = -out[1], out[0]

        return out

def extent(shape, offset):
    """
    Compute shifted array extent

    Parameters
    ----------
    shape : array_like
        Array shape
    offset : array_like
        Array offset

    Returns
    -------
    rmin, rmax, cmin, cmax : int
        Indices that define the span of the shifted array.

    Notes
    -----
    To use the values returned by ``extent()`` in a slice, ``rmax`` and ``cmax``
    should be increased by 1.

    See Also
    --------
    lentil.field.boundary : compute the extent around a number of Fields

    """
    if len(shape) < 2:
        shape = (1, 1)

    rmin = int(-(shape[0]//2) + offset[0])
    cmin = int(-(shape[1]//2) + offset[1])
    rmax = int(rmin + shape[0] - 1)
    cmax = int(cmin + shape[1] - 1)

    return rmin, rmax, cmin, cmax

def overlap(a, b):
    """
    True if two Fields overlap, otherwise False

    Parameters
    ----------
    a, b : `~lentil.Field`
        Input fields.

    Returns
    -------
    overlap : bool
    """
    armin, armax, acmin, acmax = a.extent
    brmin, brmax, bcmin, bcmax = b.extent
    return armin <= brmax and armax >= brmin and acmin <= bcmax and acmax >= bcmin

def boundary(*fields):
    """
    Compute the bounding extents around a number of Field objects.

    Parameters
    ----------
    fields : :class:`~lentil.field.Field` objects
        Fields to compute boundary around

    Returns
    -------
    rmin, rmax, cmin, cmax : int
        Indices that define the extent of the shifted arrays.

    Notes
    -----
    To use the values returned by ``boundary()`` in a slice, ``rmax`` and ``cmax``
    should be increased by 1.

    See Also
    --------
    lentil.field.extent : Compute the extent of a Field

    """
    rmin, rmax, cmin, cmax = sys.maxsize, 0, sys.maxsize, 0

    for field in fields:
        frmin, frmax, fcmin, fcmax = field.extent
        rmin = frmin if frmin < rmin else rmin
        rmax = frmax if frmax > rmax else rmax
        cmin = fcmin if fcmin < cmin else cmin
        cmax = fcmax if fcmax > cmax else cmax

    return rmin, rmax, cmin, cmax

def insert(field, out, intensity=False, weight=1, indexing='ij'):
    """

    Parameters
    ----------
    field : :class:`~lentil.field.Field`
        Field to insert into ``out``
    out : ndarray
        Array to insert ``field`` into
    intensity : bool, optional
        If True, compute intensity of ``field`` before placing it in ``out``. Default is
        False.
    weight : float, optional
        Weight to apply to ``field`` before it is inserted into ``out``
    indexing : 'ij', 'xy', optional
        Cartesian ('xy') or matrix ('ij', default) indexing of output

    Returns
    -------
    out : ndarray

    """
    if indexing not in ('xy', 'ij'):
        raise ValueError("Valid values for `indexing` are 'xy' and 'ij'")

    if field.shape == out.shape and np.array_equal(field.offset, [0, 0]):
        field_slice = Ellipsis
        out_slice = Ellipsis
    else:

        out_shape = np.asarray(out.shape)
        field_shape = np.asarray(field.shape)
        field_offset = np.asarray(field.offset)

        if indexing == 'xy':
            field_offset = -field_offset[1], field_offset[0]

        # Output coordinates of the upper left corner of the shifted data array
        field_shifted_ul = (out_shape // 2) - (field_shape // 2) + field_offset

        # Field slice indices
        field_rmin = int(0)
        field_rmax = int(field_shape[0])
        field_cmin = int(0)
        field_cmax = int(field_shape[1])

        # Output insertion slice indices
        out_rmin = int(field_shifted_ul[0])
        out_rmax = int(field_shifted_ul[0] + field_shape[0])
        out_cmin = int(field_shifted_ul[1])
        out_cmax = int(field_shifted_ul[1] + field_shape[1])

        # reconcile the field and output insertion indices
        if out_rmin < 0:
            field_rmin = -1 * out_rmin
            out_rmin = 0

        if out_rmax > out_shape[0]:
            field_rmax -= out_rmax - out_shape[0]
            out_rmax = out_shape[0]

        if out_cmin < 0:
            field_cmin = -1 * out_cmin
            out_cmin = 0

        if out_cmax > out_shape[1]:
            field_cmax -= out_cmax - out_shape[1]
            out_cmax = out_shape[1]

        out_slice = slice(out_rmin, out_rmax), slice(out_cmin, out_cmax)
        field_slice = slice(field_rmin, field_rmax), slice(field_cmin, field_cmax)

    if intensity:
        out[out_slice] += (np.abs(field.data[field_slice]**2) * weight)
    else:
        out[out_slice] += (field.data[field_slice] * weight)
    return out

def merge(a, b, check_overlap=True):
    """
    Merge two Fields

    Parameters
    ----------
    a, b : :class:`~lentil.field.Field` objects
        Fields to merge
    check_overlap : bool, optional
        If True (default), a ``ValueError`` is raised if ``a`` and ``b`` do not overlap

    Returns
    -------
    out : :class:`~lentil.field.Field`
        New ``Field`` that represents the union of ``a`` and ``b``
    """
    if not np.all(a.pixelscale == b.pixelscale):
        raise ValueError(f'pixelscales {a.pixelscale} and '
                         f'{b.pixelscale} are not equal')
    if check_overlap and not overlap(a, b):
        raise ValueError("can't merge non-overlapping fields")

    out = np.zeros(_merge_shape(a, b), dtype=complex)
    a_slc, b_slc = _merge_slices(a, b)
    out[a_slc] = a.data
    out[b_slc] += b.data
    return Field(data=out, pixelscale=a.pixelscale,
                 offset=_merge_offset(a, b))

def _merge_shape(*fields):
    # shape required to merge fields
    rmin, rmax, cmin, cmax = boundary(*fields)
    # faster than np.any([rmin, rmax, cmin, cmax])
    if rmin == 0 and rmax == 0 and cmin == 0 and cmax == 0:
        return ()
    else:
        return rmax - rmin + 1, cmax - cmin + 1

def _merge_slices(*fields):
    # slices in the merged array where fields go
    rmin, rmax, cmin, cmax = boundary(*fields)
    out = []
    # faster than np.any([rmin, rmax, cmin, cmax])
    if rmin == 0 and rmax == 0 and cmin == 0 and cmax == 0:
        out.append(Ellipsis)
    else:
        for field in fields:
            frmin, frmax, fcmin, fcmax = field.extent
            row = slice(frmin-rmin, frmax-rmin+1)
            col = slice(fcmin-cmin, fcmax-cmin+1)
            out.append((row, col))
    return out

def _merge_offset(*fields):
    # common offset of the resulting merged array
    rmin, rmax, cmin, cmax = boundary(*fields)
    nrow = rmax - rmin + 1
    ncol = cmax - cmin + 1
    return rmin + nrow//2, cmin + ncol//2

def multiply(x1, x2):
    """
    Multiply fields element-wise.

    Parameters
    ----------
    x1, x2 : :class:`~lentil.field.Field`
        Fields to be multiplied. If ``x1.shape != x2.shape``, they must
        be broadcastable to a common shape (which becomes the shape of the
        output).

    Returns
    -------
    y : :class:`~lentil.field.Field`
        The product of ``x1`` and ``x2``, appropriately sized and offset.

    Notes
    -----
    The output Field data and offset are computed according to the following
    rules:

        * If both operands are scalars, the result is 0 unless the operands
          share the same offset.
        * A single scalar operand is broadcast to the other operand's shape and
          inherits the other operand's offset. This enables default planar
          fields (``data = 1+0j``, offset = [0, 0]) to automatically grow in
          size when multiplied by a "real" field.

    """
    pixelscale = multiply_pixelscale(x1.pixelscale, x2.pixelscale)
    tilt = x1.tilt + x2.tilt

    if x1.size == 1 and x2.size == 1:
        data, offset = _mul_scalar(x1, x2)
    else:
        # Note that _mul_array is optimized to also handle scalar * array
        data, offset = _mul_array(x1, x2)

    return Field(data=data, pixelscale=pixelscale, offset=offset, tilt=tilt)

def multiply_pixelscale(a_pixelscale, b_pixelscale):
    # pixelscale reduction for multiplication
    if a_pixelscale == () and b_pixelscale == ():
        out = ()
    elif a_pixelscale == ():
        out = b_pixelscale
    elif b_pixelscale == ():
        out = a_pixelscale
    else:
        if a_pixelscale[0] == b_pixelscale[0] and a_pixelscale[1] == b_pixelscale[1]:
            out = a_pixelscale
        else:
            raise ValueError(f"can't multiply with inconsistent pixelscales: {a_pixelscale} != {b_pixelscale}")

    return out

def _mul_scalar(a, b):
    if np.array_equal(a.offset, b.offset):
        data = a.data * b.data
        offset = a.offset
    else:
        data = 0
        offset = [0, 0]
    return data, offset

def _broadcast_arrays(a, b):
    # if one array is a scalar, it is broadcast to a compatible shape
    # with the other array. as a part of this operation, the broadcasted
    # Field inherits the other Field's offset as well
    a_data, a_offset = a.data, a.offset
    b_data, b_offset = b.data, b.offset
    if a.shape != b.shape:
        if a.size == 1:
            a_data = np.broadcast_to(a_data, b.shape)
            a_offset = b_offset
        if b.size == 1:
            b_data = np.broadcast_to(b_data, a.shape)
            b_offset = a.offset
    return a_data, a_offset, b_data, b_offset

def _mul_array(a, b):
    a_data, a_offset, b_data, b_offset = _broadcast_arrays(a, b)
    a_extent = extent(a_data.shape, a_offset)
    b_extent = extent(b_data.shape, b_offset)

    a_slice, b_slice = _mul_slices(a_extent, b_extent)
    offset = _mul_offset(a_extent, b_extent)
    data = a_data[a_slice] * b_data[b_slice]

    if data.size == 0:
        data = np.array(0, dtype=complex)
        offset = [0, 0]

    return data, offset

def _mul_boundary(a_extent, b_extent):
    # bounding  array indices to be multiplied
    armin, armax, acmin, acmax = a_extent
    brmin, brmax, bcmin, bcmax = b_extent

    rmin, rmax = max(armin, brmin), min(armax, brmax)
    cmin, cmax = max(acmin, bcmin), min(acmax, bcmax)

    return rmin, rmax, cmin, cmax

def _mul_slices(a_extent, b_extent):
    rmin, rmax, cmin, cmax = _mul_boundary(a_extent, b_extent)

    armin, armax, acmin, acmax = a_extent
    brmin, brmax, bcmin, bcmax = b_extent

    arow = slice(rmin-armin, rmax-armin+1)
    acol = slice(cmin-acmin, cmax-acmin+1)
    brow = slice(rmin-brmin, rmax-brmin+1)
    bcol = slice(cmin-bcmin, cmax-bcmin+1)

    return (arow, acol), (brow, bcol)

def _mul_offset(a_extent, b_extent):
    rmin, rmax, cmin, cmax = _mul_boundary(a_extent, b_extent)
    nrow = rmax - rmin + 1
    ncol = cmax - cmin + 1
    return rmin + nrow//2, cmin + ncol//2

class NDField:
    __slots__ = 'fields'

    # NDField looks like a standard field but may actually contain multiple
    # possibly overlapping fields that aren't combined until the data attribute
    # is accessed
    def __init__(self, field):
        self.fields = [field]

    @property
    def data(self):
        # can use _merge shape and merge slices
        out = np.zeros(self.shape, dtype=complex)
        slices = _merge_slices(*self.fields)
        for field, slc in zip(self.fields, slices):
            out[slc] += field.data
        return out

    @property
    def offset(self):
        return _merge_offset(*self.fields)

    @property
    def extent(self):
        return boundary(*self.fields)

    @property
    def shape(self):
        return _merge_shape(*self.fields)

    def append(self, field):
        self.fields.append(field)

    def overlap(self, other):
        return overlap(self, other)

def reduce(*fields):
    """
    Reduce a number of disjoint Fields into a potentially smaller set where overlapping
    Fields are merged.

    Parameters
    ----------
    fields :class:`~lentil.field.Field` or :class:`~lentil.field.NDField` objects
        Fields to reduce

    Returns
    -------
    fields : list
        List of :class:`~lentil.field.NDField` objects
    """
    fields = [NDField(field) if not isinstance(field, NDField) else field for field in fields]
    for m, n in combinations(range(len(fields)), 2):
        if overlap(fields[m], fields[n]):
            fields[m].append(fields[n])
            fields.pop(n)
            return reduce(*fields)

    return fields


import random

from collections import defaultdict
from tqdm import tqdm

from pysat.solvers import Maplesat as PysatSolver

import formula_builder as FB

import hyperparameters as H

def find_unbalancedness_for_graph_nodes(g):
    print("Random sampling unbalanced nodes, {} samples".format(H.RANDOM_SAMPLE_SIZE))

    random.seed(42)
    complete_input_range = range(2 ** g.n_inputs)
    random_sample_size =  min(len(complete_input_range), H.RANDOM_SAMPLE_SIZE)
    random_sample = random.sample(complete_input_range, random_sample_size)

    had_true_on_node = defaultdict(int)

    for i, input in enumerate(
        tqdm(random_sample, desc="Random sampling unbalanced nodes")
    ):
        gate_values_on_input = g.calculate_schema_on_inputs(input)
        for name, value in gate_values_on_input.items():
            if value:
                had_true_on_node[name] += 1

    # map each gate to its saturation
    # fractions : [(disbalance, gate_name)]
    fractions = list(
        map(
            lambda name_cnt: (name_cnt[1] / random_sample_size, name_cnt[0]),
            had_true_on_node.items(),
        )
    )

    return list(filter(lambda item: not item[1].startswith("i"), fractions))

# Returns names of nodes that are unbalanced enough, based on DISBALANCE_THRESHOLD.
def find_unbalanced_gates(g):
    fractions = find_unbalancedness_for_graph_nodes(g)

    fractions = list(filter(lambda a: not a[1].startswith("i"), fractions))

    fractions = list(sorted(fractions))

    unbalanced = fractions

    unbalanced_gates = list(map(lambda p: p[1], unbalanced))

    buckets = [
        unbalanced_gates[x : x + H.BUCKET_SIZE]
        for x in range(0, len(unbalanced_gates), H.BUCKET_SIZE)
    ]

    return buckets

# Calculates a list of tuples:
# (saturation, bucket, domain, tag)
# saturation - value (0-1]
# bucket - list of node names, of which the bucket consists
# domain - list of positive ints, every int is a bitvector of length len(bucket)
# tag - either L or R for the left or right half of a miter schema, accordingly
def calculate_domain_saturations(g, buckets, tag, start_from):
    print("Total buckets selected for {} schema: {}".format(tag, len(buckets)))

    domains = list()

    pool = FB.TPoolHolder(start_from=start_from)
    formula = FB.make_formula_from_my_graph(g, pool)

    shift = -1
    for clause in formula.clauses:
        for var in clause:
            shift = max(shift, abs(var))

    # bucket : [gate_name]
    # domains : [(bucket, [bit_vector])]
    with PysatSolver(bootstrap_with=formula.clauses) as solver:
        for bucket_id, bucket in enumerate(
            tqdm(buckets, desc="Calculating saturation for bucket")
        ):
            domain = list()

            cur_bucket_size = len(bucket)
            for i in range(0, 2 ** cur_bucket_size):
                assumptions = list()
                for gate_in_bucket_id, gate_name in enumerate(bucket):
                    if (i & (1 << gate_in_bucket_id)) > 0:
                        modifier = 1
                    else:
                        modifier = -1
                    assumptions.append(modifier * pool.v_to_id(gate_name))

                if solver.solve(assumptions=assumptions):
                    domain.append(i)

            domains.append((bucket, domain))

    # calculate saturation for each domain
    # domains : [(saturation, bucket, [bit_vector], tag)]
    domains_with_saturation = list(
        map(lambda p: (len(p[1]) / (2 ** len(p[0])), p[0], p[1], tag), domains)
    )
    return domains_with_saturation, shift

def find_incompatible_nodes(g1, g2):
    random.seed(42)
    complete_input_size = range(2 ** g1.n_inputs)
    random_sample = random.sample(
        complete_input_size, min(len(complete_input_size), 10)
    )

    incompatible_pairs = list()
    incompatible_pairs.append(list())
    incompatible_pairs.append(list())
    incompatible_pairs[0].append(set())
    incompatible_pairs[0].append(set())
    incompatible_pairs[1].append(set())
    incompatible_pairs[1].append(set())

    for i, input in enumerate(
        tqdm(random_sample, desc="Random sampling unbalanced nodes")
    ):
        results_1 = g1.calculate_schema_on_inputs(input)
        results_2 = g2.calculate_schema_on_inputs(input)

        for name_1 in g1.node_names:
            for name_2 in g2.node_names:
                conj = [results_1[name_1], results_2[name_2]]

                if conj == [False, False]:
                    incompatible_pairs[0][0].add((name_1, name_2))
                elif conj == [False, True]:
                    incompatible_pairs[0][1].add((name_1, name_2))
                elif conj == [True, False]:
                    incompatible_pairs[1][0].add((name_1, name_2))
                elif conj == [True, True]:
                    incompatible_pairs[1][1].add((name_1, name_2))

                # if results_1[name_1] != results_2[name_2]:
                #     incompatible_pairs.add((name_1, name_2))

    return incompatible_pairs


import re
from datetime import datetime, timedelta, timezone, tzinfo
from typing import Mapping, Match, Optional, Pattern, cast

__all__ = ['parse']

# Adapted from http://delete.me.uk/2005/03/iso8601.html
RE_ISO8601: Pattern = re.compile(  # noqa
    r'(?P<year>[0-9]{4})(-(?P<month>[0-9]{1,2})(-(?P<day>[0-9]{1,2})'
    r'((?P<separator>.)(?P<hour>[0-9]{2}):(?P<minute>[0-9]{2})'
    r'(:(?P<second>[0-9]{2})(\.(?P<microsecond>[0-9]+))?)?'
    r'(?P<timezone>Z|(([-+])([0-9]{2}).?([0-9]{2})))?)?)?)?')
RE_TIMEZONE: Pattern = re.compile(
    '(?P<prefix>[+-])(?P<hours>[0-9]{2}).?(?P<minutes>[0-9]{2})$')

class InvalidTZ(Exception):
    """Isoformat date does not have a valid timezone."""

def parse(datetime_string: str) -> datetime:
    """Parse and convert ISO 8601 string into a datetime object."""
    m = RE_ISO8601.match(datetime_string)
    if not m:
        raise ValueError(
            f'unable to parse date string {datetime_string!r}')
    groups = cast(Mapping[str, str], m.groupdict())
    return datetime(
        int(groups['year']),
        int(groups['month']),
        int(groups['day']),
        int(groups['hour'] or 0),
        int(groups['minute'] or 0),
        int(groups['second'] or 0),
        int(groups['microsecond'] or 0),
        parse_tz(groups['timezone']) if groups['timezone'] else None,
    )

def parse_tz(tz: str) -> tzinfo:
    if tz == 'Z':
        return timezone.utc
    match: Optional[Match] = RE_TIMEZONE.match(tz)
    if match is not None:
        prefix, hours, minutes = match.groups()
        return _apply_tz_prefix(prefix, int(hours), int(minutes))
    raise InvalidTZ(f'Missing or invalid timezone information: {tz!r}')

def _apply_tz_prefix(prefix: str, hours: int, minutes: int) -> tzinfo:
    if prefix == '-':
        hours = -hours
        minutes = -minutes
    return timezone(timedelta(minutes=(minutes + (hours * 60))))


from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView
from django.conf import settings
from django.conf.urls.static import static

def trigger_error(request):
    division_by_zero = 1 / 0

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", TemplateView.as_view(template_name="main.html")),
    path("members/", include("members.urls")),
    path("leaves/", include("leaves.urls")),
    path("orders/", include("orders.urls")),
    path("grants/", include("grants.urls")),
    path("signs/", include("signs.urls")),
    path("push/", include("push.urls")),
    path('paul-sentry-debug/', trigger_error),
]

if settings.DEBUG:
    import debug_toolbar
    urlpatterns += [
        path('__debug__/', include(debug_toolbar.urls))
    ]
    # 미디어 서빙(디버깅)
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)


# coding: utf-8

import math
import os
import time
import circuit
import projet
import arborescence
import numpy as np
import bornes
import matplotlib.pyplot as plt
import approche
from scipy import stats
plt.rcParams['backend'] = "Qt4Agg"

def getTime(function, *args):
    start = time.time()
    function(*args)
    #print('res : ', res)
    end = time.time()
    return end - start

def getData(filename):
    f = open(filename,'r')
    matrice = []
    for line in f:
        matrice.append([float(x) for x in line.split(' ')])
    f.close()
    t1, t2 = matrice[0], matrice[1:]
    nbTaches = (int)(t1[0])
    M = np.array(t2)
    return nbTaches, M

def read_graphe_file(*Lfilename):
    dirname = 'dataGraphe/'
    L = []
    time = []
    cpt = 1
    for filename in Lfilename:
        fichier = dirname + filename
        f = open(fichier, 'r')
        for line in f:
            if cpt % 2 != 0 or cpt == 2:
                L.append([float(x) for x in line.split(' ')])
            cpt += 1
        f.close()
    L_nbTaches = L[1]
    print(L_nbTaches)
    del L[1]
    return L_nbTaches, L

def mesure_time(methode, typeGen, nbTachesMax,nbInstances, step, debug=False,*args):
    print('args : ', args)
    prefix = 'Instances/' + typeGen + '/' + 'instances'
    numTache = step
    L_time = []
    L_nbTaches = []
    sumTime = 0
    while (numTache <= nbTachesMax):
        #print('numTache : ', numTache)
        directory = prefix + (str)(numTache) + '/'
        if debug:
            print('directory : ', directory)
        for i in range(nbInstances):
            filename = directory + 'test' + (str)(i)
            if debug:
                print('filename : ', filename)
            n, M = getData(filename)
            print('n : ', n)
            t = getTime(methode, n, M,*args)
            sumTime += t
        L_nbTaches.append(numTache)
        L_time.append(sumTime / (1.0 * nbInstances))
        sumTime = 0
        numTache += step
    return L_nbTaches, L_time

def compare_methodes(methode1, methode2, name1, name2, nbTachesMax, nbInstances, step):
    L_label= ['',"Données non-corrélées", "Corrélation sur les durées d'éxécution", "Corrélation sur les machines"]
    for i in range(1,4):
        data_type = 'type' + (str)(i)
        L_nbTaches, L_time1 = mesure_time(methode1,data_type, nbTachesMax, nbInstances, step)
        L_nbTaches, L_time2 = mesure_time(methode2,data_type, nbTachesMax, nbInstances, step)
        plt.plot(L_nbTaches, L_time1, label=L_label[i] + ' ' + name1)
        plt.plot(L_nbTaches, L_time2, label=L_label[i] + ' ' + name2)
    plt.xlabel('Nombre de taches')
    plt.ylabel('Temps de calcul')
    plt.legend()
    plt.show()

def compare_node(methode1, methode2, name1, name2, nbTachesMax, nbInstances, step):
    L_label= ['',"Données non-corrélées", "Corrélation sur les durées d'éxécution", "Corrélation sur les machines"]
    for i in range(1,4):
        data_type = 'type' + (str)(i)
        L_nbTaches, L_time1 = mesure_node(methode1,data_type, nbTachesMax, nbInstances, step)
        L_nbTaches, L_time2 = mesure_node(methode2,data_type, nbTachesMax, nbInstances, step)
        plt.plot(L_nbTaches, L_time1, label=L_label[i] + ' ' + name1)
        plt.plot(L_nbTaches, L_time2, label=L_label[i] + ' ' + name2)
    plt.xlabel('Nombre de taches')
    plt.ylabel('Nombre de noeud explorés')
    plt.legend()
    plt.show()

def mesure_node(methode, typeGen, nbTachesMax, nbInstances, step, debug=False, *args):
    print('args : ', args)
    prefix = 'Instances/' + typeGen + '/' + 'instances'
    numTache = step
    L_cpt = []
    L_nbTaches = []
    sumCpt = 0
    while (numTache <= nbTachesMax):
        #print('numTache : ', numTache)
        directory = prefix + (str)(numTache) + '/'
        if debug:
            print('directory : ', directory)
        for i in range(nbInstances):
            filename = directory + 'test' + (str)(i)
            if debug:
                print('filename : ', filename)
            n, M = getData(filename)
            print('n : ', n)
            cpt =  methode(n, M,*args)
            sumCpt += cpt
        L_nbTaches.append(numTache)
        L_cpt.append(sumCpt / (1.0 * nbInstances))
        sumCpt = 0
        numTache += step
    return L_nbTaches, L_cpt

def mesure_approximation(methode, typeGen, nbTachesMax, nbInstances, step, debug=False):
    #print('args : ', args)
    prefix = 'Instances/' + typeGen + '/' + 'instances'
    numTache = step
    L_exacte = []
    L_res = []
    L_nbTaches = []
    sumRes = 0
    sumExacte = 0
    while (numTache <= nbTachesMax):
        #print('numTache : ', numTache)
        directory = prefix + (str)(numTache) + '/'
        if debug:
            print('directory : ', directory)
        for i in range(nbInstances):
            filename = directory + 'test' + (str)(i)
            if debug:
                print('filename : ', filename)
            n, M = getData(filename)
            print('n : ', n)
            P =  methode(n, M)
            c = circuit.Circuit(P, M)
            res = c.resolve()
            opt, exacte = arborescence.arborescence_mix(n, M)
            #print('exacte : ', exacte)
            #print('opt ', opt)
            sumRes += res
            sumExacte += exacte

        L_nbTaches.append(numTache)
        L_exacte.append(2*(sumExacte / (1.0*nbInstances)))
        L_res.append(sumRes / (1.0*nbInstances))
        sumRes = 0
        sumExacte = 0
        numTache += step
    return L_nbTaches, L_res, L_exacte

def graphe_approximation(methode, name, numMax, nbInstances, step, xlabel='Nombre de taches', ylabel="Resultat de l'ordonnancement", courbe_label="type"):
    prefix = 'type'
    M = []
    for i in range(1,4):
        data_type = prefix + (str)(i)
        L_label= ['',"Données non-corrélées", "Corrélation sur les durées d'éxécution", "Corrélation sur les machines"]
        L_nbTaches, L_res, L_exacte = mesure_approximation(methode, data_type, numMax, nbInstances, step)
        #s = name + '_' + data_type
        plt.plot(L_nbTaches, L_res, label=L_label[i] + ' Johnson')
        plt.plot(L_nbTaches, L_exacte, label=L_label[i] + ' 2*opt')
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.legend()
    plt.show()

def save_graphe_data(filename, L_nbTaches, L_time, dirname='dataGraphe/'):
    if not(os.path.exists(dirname)):
        os.mkdir(dirname)
    fichier = dirname + filename
    f = open(fichier, 'w')
    s1 = ''
    s2 = ''
    for i in range(len(L_time)):
        s1 += (str)(L_time[i]) + ' '
        s2 += (str)(L_nbTaches[i]) + ' '
    s1 = s1[:-1]
    s2 = s2[:-1]
    f.write(s1 + '\n')
    f.write(s2)
    print('les données sont sauvegardées avec succès !')
    f.close()

def draw(L_nbTaches, L_time,xlabel='Nombre de taches', ylabel='Temps de calcul'):
    plt.plot(L_nbTaches, L_time)
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.show()

def multipledraw(L_nbTaches, M_cpt,xlabel='Nombre de taches', ylabel='Temps de calcul',courbe_label='type'):
    i = 1
    L_label= ['',"Données non-corrélées", "Corrélation sur les durées d'éxécution", "Corrélation sur les machines"]
    for L_cpt in M_cpt:
        plt.plot(L_nbTaches, L_cpt,label=L_label[i])
        i += 1
    plt.xlabel(xlabel)
    plt.ylabel(ylabel)
    plt.legend()
    plt.show()

def test():
    L1 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
    L2 = list(map(lambda x: x**2, L1))
    print(L1)
    print(L2)
    verifComplexite(L1, L2)

def verifComplexite(L_nbTaches, L_time):
    t1 = L_nbTaches[::]
    t2 = L_time[::]
    for i in range(len(t2)):
        t1[i] = math.log(t1[i])
        t2[i] = math.log(t2[i])
    x = np.array(t1)
    y = np.array(t2)
    slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
    print('slope : ', slope)
    draw(t1,t2,' Log(nombre de taches)','Log(temps de résolution)')

def build_graphe(methode,name, numMax ,nbInstances, step, xlabel='nombre de taches', ylabel='temps de calcul', courbe_label='type',*args):
    prefix = 'type'
    L = []
    M = []
    for i in range(1,4):
        data_type = prefix + (str)(i)
        L_nbTaches, L_time = mesure_time(methode, data_type, numMax, nbInstances, step,*args)
        s = name + '_' + data_type
        L.append(s)
        M.append(L_time)
        save_graphe_data(s,L_nbTaches, L_time)
    print('L : ', L_nbTaches)
    print('M: ', M)
    multipledraw(L_nbTaches, M, xlabel, ylabel, courbe_label)

def main():
    #test()
    #L_nbTaches, L_time = mesure_time(projet.Johnson, 'type1', 200,10,5)
    #q = verifComplexite(L_nbTaches, L_time)
    #print('q : ', q)
    #build_graphe(approche.branch_and_greed,'branch_and_greed',20,5,5,'nombre de taches', 'temps de calcul', 'type', 10)
    #build_graphe(arborescence.arborescence_mix, 'b2', 8,5,1,'nombre de taches', 'temps de calcul', 'type', bornes.borneMax)
    #graphe_approximation(projet.Johnson, "approché vs exact", 8, 5 , 1)
    #compare_methodes(arborescence.arborescence_mix, arborescence.arborescence_resolve, 'initialisation', 'sans initialisation',7,5,1)
    #compare_node(arborescence.get_noeud_explore, arborescence.get_noeud_explore_b2, 'borne b1', 'borne b2',7,5,1)
    #L_nbTaches, L_time = mesure_time(projet.Johnson, 'type3', 200, 10, 5)
    #save_graphe_data('Johnson_type3', L_nbTaches, L_time)
    #L_nbTaches, L_time = mesure_time(arborescence.arborescence_resolve, 'type3', 5, 5, 1)
    #save_graphe_data('exacte_type3_b1', L_nbTaches, L_time)
    #L_nbTaches, L_time = mesure_time(arborescence.arborescence_mix, 'type3', 9, 5, 1)
    #save_graphe_data('mix_type3_b1', L_nbTaches, L_time)
    #draw(L_nbTaches, L_time)
    #print('L_nbTaches : ', L_nbTaches)
    #print('L_time : ', L_time)
    L_nbTaches, M = read_graphe_file('exacte_type1_b1','exacte_type2_b1', 'exacte_type3_b1')
    multipledraw(L_nbTaches, M, 'Nombre de taches','Temps de calcul', 'methode')
    #draw(L_nbTaches, M)
    #print(M)
    #L_nbTaches, L_cpt = mesure_node(arborescence.get_noeud_explore, 'type3', 7, 5, 1)
    #print('L_nbTaches : ', L_nbTaches)
    #print('L_cpt : ', L_cpt)
    #save_graphe_data('node_type3_b1', L_nbTaches, L_cpt)
    #draw(L_nbTaches, L_cpt,'nombre de taches','nombre de noeuds')

main()


from time import sleep
import multiprocessing
import os

dummy_io = os.environ.get('DUMMY_IO') == 'true'
pinMap = {
  "release": 4,
  "button_led": 18
}
ioMap = {}

if dummy_io == False:
  from gpiozero import Button
  from gpiozero import LED
  button_led = LED(pinMap['button_led'])
  button = Button(pinMap['release'])
  ioMap = {
    "release": button,
    "button_led": button_led
  }

def listen_to_button(id, listener):
  if dummy_io:
    return

  if id in ioMap.keys():
    ioMap[id].when_pressed = listener

def led_on(id):
  if dummy_io:
    return

  if id in ioMap.keys():
    ioMap[id].on()

def led_off(id):
  if dummy_io:
    return

  if id in ioMap.keys():
    ioMap[id].off()

def _led_blink(id):
  if id not in ioMap.keys():
    return

  while True:
    ioMap[id].on()
    sleep(1)
    ioMap[id].off()
    sleep(1)

thread = None

def led_blink(id, onoff):
  global thread

  if onoff == True:
    if thread != None:
      return

    thread = multiprocessing.Process(target=_led_blink, args=(id,))
    thread.start()
  else:
    if thread == None:
      return

    thread.terminate()
    thread = None
    ioMap[id].off()


from nltk.sentiment.vader import SentimentIntensityAnalyzer as SA
import argparse
import pandas as pd
from tqdm import tqdm
from xml.etree import ElementTree as ET
parser = argparse.ArgumentParser(description="Compute score of each tweet using vader library")
parser.add_argument("input_file", type=argparse.FileType("r"), help="XML file input of tokenized tweets")
parser.add_argument("output_file", type=argparse.FileType("w+"), nargs='?', default='data/csv/tweets_score_vader.csv',
                    help="CSV output file of tweets score")
args = parser.parse_args()

if __name__ == '__main__':
    tweets = ET.parse(args.input_file.name).getroot()

    tweets_scores = []

    sentiment_scores = SA().polarity_scores

    for tweet in tqdm(tweets):

        # intial score
        tweet_score = 0.0

        # get plain text and ID of tweet
        tweet_id = tweet.attrib['ID']
        tweet_text = tweet.find('PLAIN_TEXT').text

        tweet_sentiment_analysis = dict()
        tweet_sentiment_analysis['id'] = tweet_id

        # count number of emojis
        tweet_emojis = tweet.find('EMOJIS').text
        if tweet_emojis:
            num_emojis = len(tweet_emojis.split())
        else:
            num_emojis = 0

        if tweet_text is not None:
            pos = sentiment_scores(tweet_text)['pos']
            neg = sentiment_scores(tweet_text)['neg']
            tweet_score = pos - neg

        # consider emojis and emoticons
        if tweet_score < 0:
            tweet_score -= num_emojis*0.2
        elif tweet_score > 0:
            tweet_score += num_emojis*0.2
        else:
            if tweet_emojis:
                tweet_score += num_emojis*0.2

        tweet_sentiment_analysis['score'] = tweet_score
        if tweet_score > 0:
            tweet_sentiment_analysis['polarity'] = "Positive"
        elif tweet_score < 0:
            tweet_sentiment_analysis['polarity'] = "Negative"
        else:
            tweet_sentiment_analysis['polarity'] = "Neutral"

        tweets_scores.append(tweet_sentiment_analysis)

    df = pd.DataFrame(tweets_scores)
    df.set_index('id', inplace=True)

    df.to_csv(args.output_file.name)


#-*-coding:utf-8-*-
import os
import pdb
import urllib2

import requests
from bs4 import BeautifulSoup
from lxml import etree
from PIL import Image
from ZFCheckCode import recognizer, trainner

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
    'Referer': 'http://jwgl1.hbnu.edu.cn/(S(nxuiogv1kq4coqvvhltax145))/default2.aspx?'
}

baseurl = 'http://jwgl1.hbnu.edu.cn'
s=requests.Session()
html = s.get(baseurl, headers=headers, allow_redirects=False )
loc = html.headers['location']
loginurl = baseurl + loc
codeu = loginurl[0:54]
codeurl = codeu + '/CheckCode.aspx?'

# 获取验证码并自动识别
def checkcode():
    img=s.get(codeurl, stream=True, headers=headers)
    with open('checkcode.gif','wb') as f:
        f.write(img.content)
    trainner.update_model()
    code = recognizer.recognize_checkcode('/home/fty/new-system/checkcode.gif')
    #print(code)
    return code

def spider_login(id, passwd):
    #构造表单字典
    payload={'__VIEWSTATE':'',
        'txtUserName':'',
        'Textbox1':'',
        'TextBox2':'',
        'txtSecretCode':'',
        'RadioButtonList1':'',
        'Button1':'',
        'lbLanguage':'',
        'hidPdrs':'',
        'hidsc':'',
        '__EVENTVALIDATION':'',
        }

    #获取表单字典数据
    index = s.get(loginurl, headers=headers)
    soup = BeautifulSoup(index.content,'lxml')
    value1=soup.find('input',id='__VIEWSTATE')['value']
    value2=soup.find('input',id='__EVENTVALIDATION')['value']
    payload['txtUserName']=id
    payload['TextBox2']=passwd
    code = checkcode()
    payload['txtSecretCode']= code
    payload['RadioButtonList1']=u"学生".encode('gb2312','replace')
    payload['__VIEWSTATE']=value1
    payload['__EVENTVALIDATION']=value2
    payload['RadioButtonList1']= '%D1%A7%C9%FA'

    loginresponse = s.post(loginurl, data=payload, headers=headers)
    content = loginresponse.content.decode('gb2312')
    soup = BeautifulSoup(content, 'lxml')
    uname=soup.find('span', id='xhxm')
    xsxm =  uname.text

    # 返回学生姓名
    return xsxm

def getgrades(id, name):

    payload1={'__VIEWSTATE':'',
          'ddlXN':'',
          'ddlXQ':'' ,
          'Button1':'',
          '__EVENTVALIDATION':'',

}
    #url2 = spider_login(id, passwd)
    name = name[0:9]
    cname = urllib2.quote(name.encode('gb2312'))
    xingming = urllib2.quote(cname)

    req_url = codeu + '/xscj_gc.aspx?xh=' + str(id) + '&xm=' + xingming + '&gnmkdm=N121603'
    req2 = s.get(req_url, headers=headers)

    soup = BeautifulSoup(req2.content,'lxml')
    value3=soup.find('input',id='__VIEWSTATE')['value']
    value4=soup.find('input',id='__EVENTVALIDATION')['value']
    payload1['__VIEWSTATE']=value3
    payload1['__EVENTVALIDATION']=value4
    pos = s.post(req_url, data=payload1, headers=headers)
    grades = pos.content.decode('gbk')

    return grades

def parser(id, grades):

    # 根据HTML网页字符串创建BeautifulSoup
    soup = BeautifulSoup(
        grades,  # HTML文档字符串
        'html.parser',  # HTML解析器
    )

    tables = soup.findAll('table')
    filename = '/home/fty/new-system/templates/score/'+ str(id) +'.html'
    #filename = '/home/fty/new-system/templates/score/'+ id +'.html'
    with open(filename, 'w') as f:  # 如果filename不存在会自动创建， 'w'表示写数据，写之前会清空文件中的原有数据！
        tab = tables[0]
        list = [6, 10, 14, 16]
        f.write("{% extends 'student.html' %}")
        f.write('\n')
        f.write("{% block page_name %}成绩{% endblock %}")
        f.write('\n')
        f.write('{% block body_part2 %}')
        f.write('\n')
        f.write('
')
        for tr in tab.findAll('tr'):
            count = 0
            f.write('
')
            for td in tr.findAll('td'):
                count = count + 1
                if (count not in list):
                    f.write('')
                    f.write(' ')
                    f.write(td.getText().encode('utf-8'))
                    f.write('	')
            f.write('
')
            f.write('\n')
        f.write('
')
        f.write('\n')
        f.write('{% endblock %}')

'''a = raw_input('学号：')
b = raw_input('密码：')
name = '付同永同学'
'''
# 将unicode编码编码成utf8
#getname = spider_login(a, b).encode('utf8')
# 将utf8解码成unicode
#name = name.decode('utf8')


#!/home/corr/miniconda3/envs/LLC/bin/python

from pymodbus.client.sync import ModbusTcpClient as ModbusClient

from VVMsubs import vvmInit, VVM_MEAS

import time

#this program will load data to the adam to control the line stretcher
#it will do this by intaking a decimal number (0-4095)
#converting it to a 12 bit binary number
#reversing it, and sending it to the ADAM

#do I need all this?
hostname = '128.171.166.181'
port = 502
UNIT = 0x1
WR = 0
CS = 1
A0 = 2
A1 = 3
DB0 = 4
DB1 = 5
DB2 = 6
DB3 = 7
DB4 = 8
DB5 = 9
DB6 = 10
DB7 = 11
DB8 = 12
DB9 = 13
DB10 = 14
DB11 = 15

decimal = 0
channel = 1

def send_to_adam(decimal, channel):
    #this function converts the decimal number passed in to a
    #12 bit binary number
    #decimal should be a decimal number from 0-4095

    #convert decimal to 12 bit binary here
    binary = (bin(decimal)[2:])

    #turn binary int into array
    binary_array = list(map(int, str(binary)))

    #flip it around
    flipped = binary_array[::-1]

    #turn into 12 bit number
    for i in range(12-len(flipped)):
        flipped.append(0)

    #call all functions to load data per the manual
    load_data_mode()
    time.sleep(0.1)
    load_data(flipped)
    select_channel(channel)
    chip_select()

    time.sleep(0.1)
    client.write_coils(WR, [1], unit=UNIT)
    time.sleep(0.1)

#create a function for each step in the manual a,b,c,d

def load_data_mode():
    #step a: change W/R from 1(default) to 0(load data mode)
    time.sleep(0.1)
    client.write_coils(WR, [0], unit=UNIT)
    time.sleep(0.1)

def load_data(flipped):
    #takes in 12 bit binary number and loads it to DB0-DB11

    #step b: load data to DB0-DB11

    ports = [DB0, DB1, DB2, DB3, DB4, DB5, DB6, DB7, DB8, DB9, DB10, DB11]

    # for i in range(12):
    #     if flipped[i] == 0:
    #         client.write_coils(ports[i], [0], unit=UNIT)
    #     else:
    #         client.write_coils(ports[i], [1], unit=UNIT)
    time.sleep(0.1)
    client.write_coils(DB0,flipped,unit=UNIT)
    time.sleep(0.1)

def select_channel(channel):
    #takes in channel number and sets A0 and A1 accordingly

    #step c: set A1, A0 to select output channel
    # channel  A1   A0
    #    1      0    0
    #    2      0    1
    #    3      1    0
    #    4      1    1

    if (channel == 1):
        client.write_coils(A0, [0,0], unit=UNIT)
        time.sleep(0.1)
    if (channel == 2):
        client.write_coils(A0, [1,0], unit=UNIT)
        time.sleep(0.1)
    if (channel == 3):
        client.write_coils(A0, [0,1], unit=UNIT)
        time.sleep(0.1)
    if (channel == 4):
        client.write_coils(A0, [1,1], unit=UNIT)
        time.sleep(0.1)

def chip_select():
    #step d: change C/S (chip select) from 1(default) to 0(select chip)
    #and back to 1 again.

    client.write_coils(CS, [0], unit=UNIT)
    time.sleep(0.1)
    client.write_coils(CS, [1], unit=UNIT)
    time.sleep(0.1)

client=ModbusClient(hostname,port)
time.sleep(0.1)
client.connect()
time.sleep(0.1)
send_to_adam(decimal,channel)
time.sleep(0.1)
client.close()

#write_holding_registers(channel, 16bit)
#channel 0 1 2 3
#16 bit- could only do half of this, since output is 10V and ls can only take 5V


import numpy as np
import pandas as pd
import scipy

if __name__ == '__main__':
    # Pearson系数的取值范围为[-1,1]，
    # 当值为负时，为负相关，当值为正时，为正相关，绝对值越大，则正/负相关的程度越大。
    # 若数据无重复值，且两个变量完全单调相关时，spearman相关系数为+1或-1。
    # 当两个变量独立时相关系统为0，但反之不成立
    aa = np.array([2, 3, 9, 6, 8])
    bb = np.array([5, 6, 3, 7, 9])
    cc = np.array([aa, bb])
    print(cc)

    cc_mean = np.mean(cc, axis=0)  # axis=0,表示按列求均值 ——— 即第一维
    cc_std = np.std(cc, axis=0)
    cc_zscore = (cc - cc_mean) / cc_std  # 标准化

    cc_zscore_corr = np.corrcoef(cc_zscore)  # 相关系数矩阵
    print(cc_zscore_corr)

    cc_pd = pd.DataFrame(cc_zscore.T, columns=['c1', 'c2'])
    cc_corr = cc_pd.corr(method='pearson')  # 相关系数矩阵
    print(cc_corr['c1'])  # 某个因子与其他因子的相关系数
    print(cc_pd.c1.cov(cc_pd.c2))  # 协方差
    print(cc_pd.c1.corr(cc_pd.c2))  # 两个因子的相关系数
    y_cov = cc_pd.cov()  # 协方差矩阵
    x = [2, 3, 9, 6, 8]
    y = [5, 6, 3, 7, 9]

    df = pd.DataFrame({'x': x, 'y': y})
    # print(df.x.corr(df.y))
    # print(df.x.corr(df.y, method='spearman'))
    # print(df.x.corr(df.y, method='kendall'))
    # print(df.corr())
    # print(df.corr('spearman'))
    # print(df.corr('kendall'))
    print(scipy.stats.pearsonr(x, y))
    print(scipy.stats.spearmanr(x, y))
    print(scipy.stats.kendalltau(x, y))
    # 总结 相关性绝对值越大 显著性越小 越相关


import xml.etree.ElementTree as et
from distutils.util import strtobool

singledimdtypes = ('U32', 'I32', 'U16', 'I16', 'U8', 'I8', 'DBL', 'Boolean', 'String')

def dtcast(val, dtype):
    '''
    '''
    if dtype in ('U32', 'I32', 'U16', 'I16', 'U8', 'I8'):
        val = int(val)
    elif dtype in ('DBL'):
        val = float(val)
    elif dtype in ('Boolean'):
        val = strtobool(val)
    else:
        pass
    return val

def parse(xmlfile):
    '''
    '''
    tree = et.parse(xmlfile)
    root = tree.getroot()

    params = {}

    i = 0

    for cluster in root.iter('Cluster'):
        try:
            key = cluster.find('String').find('Val').text
            key = key.replace('\n',' ')
            variant = cluster.find('LvVariant')
            dtype = variant[1].tag
            if dtype in singledimdtypes:
                val = variant[1].find('Val').text
                val = dtcast(val, dtype)
            elif dtype in ('Array'):
                ds = variant[1].find('Dimsize')
                for dt in singledimdtypes:
                    if variant[1].find(dt) is None:
                        continue
                    else:
                        val = []
                        for v in variant[1].iter(dt):
                            val.append(dtcast(v[1].text, dt))
        except AttributeError:
            i+=1
            continue
        params[key] = val
    return params


# coding: utf-8

# In[6]:

import numpy as np
import pandas as pd
import sklearn
from sklearn.linear_model import Perceptron
x = np.array([ [0, 0], [0, 1], [1, 0], [1, 1] ])
y = np.array([0, 1, 1, 1])
model = Perceptron()
model.fit(x, y)
print('Output: %d' % int(model.predict([[0, 0]])))

# In[ ]:

# In[14]:

from matplotlib import pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')

import numpy as np

class Perceptron(object):

    def __init__(self, no_of_inputs, n=100, learning_rate=0.05):
        '''
        Objective: To initialize data memebers
        Input Parameters: s
            self - object of type Perceptron
            no_of_inputs, epochs, learning_rate - int
        Return Value: None
        '''
        self.epochs = n
        self.learning_rate = learning_rate
        self.weights = 0.05 * np.random.randn(no_of_inputs + 1)# weights corr to num_inputs + 1 for bias
        print("Initial values of weights",self.weights)
    def predict(self, inputs):
        '''
        Objective: To predict the output
        Input Parameters:
            self - object of type Perceptron
            inputs - numpy array
        Return Value: Binary
        '''
        summation = np.dot(self.weights[1:].T, inputs) + self.weights[0]
        if summation > 0:
          activation = 1
        else:
          activation = 0
        return activation

    def train(self, training_inputs, labels):
        '''
        Objective: To train the model so as to tune weights
        Input Parameters:
                self - object of type Perceptron
                training_inputs, labels - np array
        Return Value: None
        '''
        for _ in range(self.epochs):
            deltaWeights = np.array([0,0]).astype('float64')
            deltaBias = 0.0
            nInstances = training_inputs.shape[0]
            for inputs, label in zip(training_inputs, labels):
                prediction = self.predict(inputs)
                deltaWeights += self.learning_rate * (label - prediction) * inputs
                deltaBias += self.learning_rate * (label - prediction)
            self.weights[1:] += (1/nInstances)*deltaWeights
            self.weights[0] += (1/nInstances)*deltaBias

        b, w1, w2 = self.weights[0], self.weights[1], self.weights[2]
        x = np.array([i for i in range(-1,3)])
        y = (-1)*(b+w1*x)/w2
        plt.plot(x, y)

# In[20]:

training_inputs = np.array([ [0, 0], [0, 1], [1, 0], [1, 1] ])
labels = np.array([0, 0, 0, 1])
for i,j in zip(training_inputs, labels):
    print(i, j)

# In[15]:

a = np.array([[1, 0], [0, 1]])
b = np.array([4, 1])
np.dot(a, b)

# In[21]:

training_inputs = np.array([ [0, 0], [0, 1], [1, 0], [1, 1] ])
labels = np.array([0, 0, 0, 1])
#labels = np.array([0, 1, 1, 1])
plt.scatter([i for i, j in training_inputs], [j for i, j in training_inputs])

perceptron = Perceptron(2)
perceptron.train(training_inputs, labels)
result = perceptron.predict(np.array([0, 1]))
print("Output",result)

plt.show()


"""
Driver class
"""
import xml.etree.ElementTree as ET
import os

from numpy import source

from models.sms import SMS
import pandas as pd
from utils import regex_match

def get_sms_list():
    # file_path = os.environ.get('SMS_FILE')
    file_path = '/Users/ashutoshgoel/workspace/expense_manager_workspace/data.xml'
    root = ET.parse(file_path).getroot()
    sms_list = []
    for child in root:
        sms = SMS(
            address=child.attrib['address'],
            timestamp=child.attrib['date'],
            body=child.attrib['body']
        )
        sms_list.append(sms)

    return sms_list

def get_dataframe(sms_list):
    sms_dict_list = []
    for sms in sms_list:
        sms_dict_list.append(
            {
                'address': sms.address,
                'timestamp': sms.timestamp,
                'body': sms.body
            }
        )

    sms_df = pd.DataFrame(sms_dict_list, columns=['address', 'timestamp', 'body'])
    return sms_df

sms_list = get_sms_list()
sms_df = get_dataframe(sms_list)

from extractors.amount_extractor import AmountExtractor
from extractors.src_extractor import SourceExtractor
from extractors.dest_extractor import DestinationExtractor
from utils import is_false_positive
src_extractor = SourceExtractor()
src_extractor.create_source_set(sms_list)
dest_extractor = DestinationExtractor()

for sms in sms_list:
    amount  = AmountExtractor.extract_amount(sms.body)
    if amount and not is_false_positive(sms):
        src = src_extractor.extract_source(sms)

    if amount and not is_false_positive(sms) and src:
        if src[1] == 'hdfc':
            dest = dest_extractor.extract_destination(sms)
            print(sms.address, sms.body)
            print('amount extracted is :',amount)
            print('source is : {source}'.format(source=src))
            print('destination is: {destination}'.format(destination=dest))
            print('\n')

# print(src_extractor.get_source_set())


import argparse

from os import path
from smartconf.conf import load_conf, dict_to_args, args_to_dict

INI_FILE = path.join(path.dirname(__file__), 'sample.ini')
CONF_FILE = path.join(path.dirname(__file__), 'defaults')

def main():
    conf = load_conf('example.defaults', INI_FILE)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Parsing')
    parser.add_argument('-l', '--list', action='store_true')
    parser.add_argument('settings', nargs='*')

    ns = parser.parse_args()
    conf = load_conf('example.defaults', INI_FILE)

    if ns.list:
        print('\n'.join(conf.to_args()))

    conf.update_from_vars(ns.settings)
    print(conf)