"""
    Written by Jonny Hyman, 2020
        www.jonnyhyman.com
        www.github.com/jonnyhyman

    MIT License

    This code shows three ways of understanding the logistic
    map : cobweb plot, time series, and bifurcation plot

"""

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QHBoxLayout,
                             QLabel, QSizePolicy, QSlider, QSpacerItem,
                             QVBoxLayout, QWidget)

from PyQt5 import QtWidgets, QtCore, QtGui
import pyqtgraph as pg

from numba import jit, prange, njit
import numpy as np

from pathlib import Path
import sys

from time import time
import types

colors =  {
            'lightest':"#eeeeee",
            'lighter':"#e5e5e5",
            'light':"#effffb",
            'himid':"#50d890",
            'midmid':"#1089ff",
            'lomid':"#4f98ca",
            'dark' :"#272727",
            'darker' :"#23374d",
}

numlabelsize = 22
txtlabelsize = 20

# STYLING
numfont = QtGui.QFont("Avenir Next") # requires macos
numfont.setPixelSize(numlabelsize)

txtfont = QtGui.QFont("Avenir Next") # requires macos
txtfont.setPixelSize(txtlabelsize)

brushes = { k: pg.mkBrush(c) for k, c in colors.items() }

pg.setConfigOptions(antialias=True)
pg.setConfigOption('background', colors['dark'])
pg.setConfigOption('foreground', colors['light'])

QPushButton_style = f"""
QPushButton{{
	color: {colors['light']};
	background-color: transparent;
	border: 1px solid #4589b2;
	padding: 5px;

}}

QPushButton::hover{{
	background-color: rgba(255,255,255,.2);
}}

QPushButton::pressed{{
	border: 1px solid {colors['himid']};
	background-color: rgba(0,0,0,.3);
}}"""

QLabel_style = f"""
QLabel{{
    color: {colors['light']};
}}
"""

QCheckBox_style = f"""
QCheckBox{{
    background-color: {colors['darker']};
    color: {colors['light']};
    padding:5px;
}}
"""

def custom_axis_item_resizeEvent(self, ev=None):
    """ custom implementation of AxisItem.resizeEvent to control `nudge`

        this overwrites the instance method for `AxisItem`
    """

    #s = self.size()

    ## Set the position of the label
    nudge = 15

    br = self.label.boundingRect()
    p = QtCore.QPointF(0, 0)
    if self.orientation == 'left':
        p.setY(int(self.size().height()/2 + br.width()/2))
        p.setX(-nudge)
    elif self.orientation == 'right':
        p.setY(int(self.size().height()/2 + br.width()/2))
        p.setX(int(self.size().width()-br.height()+nudge))
    elif self.orientation == 'top':
        p.setY(-nudge)
        p.setX(int(self.size().width()/2. - br.width()/2.))
    elif self.orientation == 'bottom':
        p.setX(int(self.size().width()/2. - br.width()/2.))
        p.setY(int(self.size().height()-br.height()+nudge))
    self.label.setPos(p)
    self.picture = None

@njit
def linear_interp(x, in_min, in_max, out_min, out_max, lim=True, dec=None):
    y = (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

    if dec is not None:
        y = round(y, dec)

    if not lim:
        return y

    else:
        y = max(out_min, y)
        y = min(out_max, y)

        return y

@jit(cache=True, nopython=True) # pragma: no cover
def logistic_map(pop, rate):
    """
    From pynamical `https://github.com/gboeing/pynamical`
    Define the equation for the logistic map.

    Arguments
    ---------
    pop: float
        current population value at time t
    rate: float
        growth rate parameter values

    Returns
    -------
    float
        scalar result of logistic map at time t+1
    """

    return pop * rate * (1 - pop)

def get_function_points(model, r, n, start, end):
    """
    From pynamical
    Calculate model results for n population values evenly spaced between start and end values.

    Arguments
    ---------
    model: function
        defining an iterated map to simulate
    r: float
        growth rate parameter value to pass to the map
    n: int
        number of iterations to run
    start: float
        lower limit of the function range
    end: float
        upper limit of the function range

    Returns
    -------
    tuple
        x_vals, y_vals
    """

    x_vals = np.linspace(start, end, n)
    y_vals = [model(x, r) for x in x_vals]
    return x_vals, y_vals

def get_cobweb_points(model, r, x, n):
    """
    From pynamical `https://github.com/gboeing/pynamical`
    Calculate the vertices of cobweb lines for a cobweb plot.

    Steps in the calculation:
    1) Let x = 0.5
    2) Start on the x-axis at the point (x, 0).
    3) Draw a vertical line to the red function curve: this point has the coordinates (x, f(x)).
    4) Draw a horizontal line from this point to the gray diagonal line: this point has the coordinates (f(x), f(x)).
    5) Draw a vertical line from this point to the red function curve: this point has the coordinates (f(x), f(f(x))).
    6) Repeat steps 4 and 5 recursively one hundred times.

    Arguments
    ---------
    model: function
        defining an iterated map to simulate
    r: float
        growth rate parameter value to pass to the map
    x: float
        starting population value
    n: int
        number of iterations to run

    Returns
    -------
    tuple
        cobweb_x_vals, cobweb_y_vals
    """

    cobweb_points = [(x, 0)]
    for _ in range(n):
        y1 = model(x, r)
        cobweb_points.append((x, y1))
        cobweb_points.append((y1, y1))
        y2 = model(y1, r)
        cobweb_points.append((y1, y2))
        x = y1
    return zip(*cobweb_points)

def cobweb_plot(plt, idx=-1,
                model=logistic_map, r=0, cobweb_x=0.5,

                function_n=1000,

                cobweb_n=100, num_discard=0,
                title='', filename='', show=True, save=True,
                start=0, end=1, figsize=(6,6), diagonal_linewidth=1.35,
                cobweb_linewidth=1, function_linewidth=1.5,
                folder='images', dpi=300, bbox_inches='tight', pad=0.1):

    plt.clear()

    initial_pop = float(cobweb_x)

    stride_idx = (idx-1)*3

    func_x_vals, func_y_vals = get_function_points(
                        model=model, r=r, n=function_n, start=start, end=end)
    cobweb_x_vals, cobweb_y_vals = get_cobweb_points(
                        model=model, r=r, x=cobweb_x, n=cobweb_n)

    cobweb_x_vals = cobweb_x_vals[:stride_idx]
    cobweb_y_vals = cobweb_y_vals[:stride_idx]

    plt.setTitle(f"Cobweb Plot")

    diagonal_line = plt.plot((0,1), (0,1))
    diagonal_line.setPen(width=diagonal_linewidth)

    function_line = pg.PlotDataItem(x=func_x_vals, y=func_y_vals)
    function_line.setPen(color=colors['lomid'], width=3.0)
    function_line = plt.addItem(function_line)

    sizes = 1/np.linspace(.1,1,len(cobweb_x_vals))
    sizes = np.maximum(5, sizes)

    cobweb_line = plt.plot(cobweb_x_vals, cobweb_y_vals, symbol='o', symbolSize=sizes)
    cobweb_line.setPen(color=colors['lomid'], width=cobweb_linewidth)
    cobweb_line.setSymbolPen(color=(1,1,1,0), width=0.0)
    cobweb_line.setSymbolBrush(color=colors['himid'])

    xaxis = plt.getAxis("bottom")
    #xaxis.setTickSpacing(4,4)

    xaxis.tickFont = numfont
    xaxis.setStyle(tickTextOffset = 20)

    yaxis = plt.getAxis("left")
    #yaxis.setTickSpacing(.2, .2)

    yaxis.resizeEvent = types.MethodType(custom_axis_item_resizeEvent, yaxis)

    yaxis.tickFont = numfont
    yaxis.setStyle(tickTextOffset = 10, tickLength=10)

    xaxis.label.setFont(txtfont)
    yaxis.label.setFont(txtfont)
    plt.titleLabel.item.setFont(txtfont)

    return np.concatenate(([initial_pop,], np.array(cobweb_y_vals[1::3])))

def series_plot(plt, y_vals, idx=100, r=0, xall=False):

    plt.clear()
    plt.setTitle("Population vs Time, growth rate: {:4.2f}".format(r))

    t = np.arange(len(y_vals))
    y = y_vals[:idx]
    t = t[:idx]

    if len(t) < 20:
        plt.setXRange(*[0,20])
    else:
        if not xall:
            plt.setXRange(*[len(t)-20, len(t)])
        else:
            plt.setXRange(*[0, 30])

    plt.setYRange(*[0,1])
    plt.showGrid(x=True, y=True)

    s = 20/len(t)
    s = max(10,s)

    line = plt.plot(x=t, y=y)
    line.setPen(color=colors['lomid'], width=3.0)

    scat = pg.ScatterPlotItem(x=t, y=y, size=s, name='series')
    scat.setPen(color=(1,1,1,0), width=0.0)
    scat.setBrush(color=colors['himid'])
    plt.addItem(scat)

    xaxis = plt.getAxis("bottom")
    #xaxis.setTickSpacing(4,4)

    xaxis.tickFont = numfont
    xaxis.setStyle(tickTextOffset = 20)

    yaxis = plt.getAxis("left")
    #yaxis.setTickSpacing(.2, .2)

    yaxis.resizeEvent = types.MethodType(custom_axis_item_resizeEvent, yaxis)

    yaxis.tickFont = numfont
    yaxis.setStyle(tickTextOffset = 10, tickLength=10)

    xaxis.label.setFont(txtfont)
    yaxis.label.setFont(txtfont)
    plt.titleLabel.item.setFont(txtfont)

def bifurc_plot(plt, y_vals, r=0, ipop=0.5, discard=64):

    if (y_vals.shape[0]) < discard:
        return

    ys = y_vals[discard:]
    xs = np.repeat(r,len(ys))
    s = 1
    new_s = 5

    if len(plt.items) == 0:
        # __init__
        bifurcation = pg.ScatterPlotItem(x=xs, y=ys, size=new_s, antialias=True, name='bifurc')
        bifurcation.setBrush(color=colors['himid'], alpha=0.5, width=1)
        bifurcation.setPen(color=(0,0,0,0), width=0, alpha=0.5)
        plt.addItem(bifurcation)

        plt.titleLabel.item.setFont(txtfont)

        xaxis = plt.getAxis("bottom")
        xaxis.setTickSpacing(1, .5)

        xaxis.tickFont = numfont
        xaxis.setStyle(tickTextOffset = 20)

        yaxis = plt.getAxis("left")
        #yaxis.setTickSpacing(.2, .2)

        yaxis.tickFont = numfont
        yaxis.setStyle(tickTextOffset = 10, tickLength=10)

        xaxis.label.setFont(txtfont)
        yaxis.label.setFont(txtfont)

    else:
        # __update__
        bifurcation = plt.items[0]

        n_new = len(xs)

        xs = np.concatenate((xs, bifurcation.data['x']))
        ys = np.concatenate((ys, bifurcation.data['y']))

        ss = np.repeat(1,len(xs))
        ss[0:n_new] = new_s

        bs = [brushes['lomid'] for b in range(len(xs))]
        bs[0:n_new] = [brushes['himid'] for _ in range(n_new)]

        bifurcation.setData(xs,ys, size=ss, brush=bs)

    plt.setXRange(*[0,4])
    plt.setYRange(*[0,1])

class Controls(QWidget):
    def __init__(self, variable='', parent=None):
        super(Controls, self).__init__(parent=parent)
        self.verticalLayout = QVBoxLayout(self)

        self.l1 = QVBoxLayout()
        self.l1.setAlignment(Qt.AlignTop)

        self.cobweb_box = QtWidgets.QCheckBox('ðŸ•¸ï¸� Plot', parent=self)
        self.l1.addWidget(self.cobweb_box)
        self.cobweb_box.setChecked(0)

        self.series_box = QtWidgets.QCheckBox("ðŸ“ˆ Plot", parent=self)
        self.l1.addWidget(self.series_box)
        self.series_box.setChecked(1)

        self.bifurc_box = QtWidgets.QCheckBox("â�„ï¸� Plot", parent=self)
        self.l1.addWidget(self.bifurc_box)
        self.bifurc_box.setChecked(0)

        self.verticalLayout.addLayout(self.l1)

        self.l2 =  QVBoxLayout()
        self.l2.setAlignment(Qt.AlignTop)

        self.animlabel = QLabel(self)
        self.l2.addWidget(self.animlabel)
        self.animlabel.setText("Animation FPS")

        self.animrate = QtWidgets.QSlider(self)
        self.animrate.setOrientation(Qt.Horizontal)
        self.l2.addWidget(self.animrate)
        self.animrate.setFixedWidth(self.animrate.width())

        self.verticalLayout.addLayout(self.l2)

        self.l3 =  QVBoxLayout()
        self.l3.setAlignment(Qt.AlignTop)

        self.sub1 = QHBoxLayout()
        self.sub1.setAlignment(Qt.AlignLeft)
        self.rate_txt = QLabel("Rate", self)

        self.rate_box = QtWidgets.QDoubleSpinBox(self)
        self.rate_box.setSingleStep(0.01)
        self.rate_box.setDecimals(2)

        self.sub1.addWidget(self.rate_txt)
        self.sub1.addWidget(self.rate_box)

        self.l3.addLayout(self.sub1)

        self.rate = QSlider(self)
        self.rate.setOrientation(Qt.Horizontal)
        self.l3.addWidget(self.rate)

        self.verticalLayout.addLayout(self.l3)

        self.l4 =  QVBoxLayout()
        self.l4.setAlignment(Qt.AlignTop)

        self.sub2 = QHBoxLayout()
        self.sub2.setAlignment(Qt.AlignLeft)

        self.ipoptxt = QLabel(self)
        self.sub2.addWidget(self.ipoptxt)
        self.ipoptxt.setAlignment(Qt.AlignHCenter)
        self.ipoptxt.setText("Initial\nPop.")

        self.ipop_box = QtWidgets.QDoubleSpinBox()
        self.ipop_box.setSingleStep(0.01)
        self.ipop_box.setDecimals(2)
        self.ipop_box.setValue(0.5)
        self.sub2.addWidget(self.ipop_box)

        self.l4.addLayout(self.sub2)

        self.ipop = QSlider(self)
        self.ipop.setOrientation(Qt.Horizontal)
        self.l4.addWidget(self.ipop)
        self.ipop.setValue(50)

        self.verticalLayout.addLayout(self.l4)

        self.resize(self.sizeHint())

        self.setFixedWidth(self.animrate.width() + 20)

        self.rate.valueChanged.connect(lambda: self.setValues('rate_slider'))
        self.rate_box.valueChanged.connect(lambda: self.setValues('rate_box'))
        self.ipop.valueChanged.connect(lambda: self.setValues('ipop_slider'))
        self.ipop_box.valueChanged.connect(lambda: self.setValues('ipop_box'))

        self.rateval = None

        self.l5 =  QVBoxLayout()
        self.l5.setAlignment(Qt.AlignTop)

        self.animb = QtWidgets.QPushButton('Play', parent=self)
        self.l5.addWidget(self.animb)
        self.animb.setFixedWidth(self.animlabel.width())

        self.reset = QtWidgets.QPushButton('Reset', parent=self)
        self.l5.addWidget(self.reset)
        self.reset.setFixedWidth(self.animlabel.width())

        self.clear = QtWidgets.QPushButton('Clear', parent=self)
        self.clear.setCheckable(False)
        self.clear.setFixedWidth(self.animlabel.width())
        self.l5.addWidget(self.clear)

        self.verticalLayout.addLayout(self.l5)

        # STYLING
        self.clear.setStyleSheet(QPushButton_style)
        self.animb.setStyleSheet(QPushButton_style)
        self.reset.setStyleSheet(QPushButton_style)

        self.animlabel.setStyleSheet(QLabel_style)
        self.rate_txt.setStyleSheet(QLabel_style)
        self.ipoptxt.setStyleSheet(QLabel_style)

        self.cobweb_box.setStyleSheet(QCheckBox_style)
        self.series_box.setStyleSheet(QCheckBox_style)
        self.bifurc_box.setStyleSheet(QCheckBox_style)

    def resizeEvent(self, event):
        super(Controls, self).resizeEvent(event)

    def setValues(self, kind=''):

        if kind == 'rate_slider':
            self.rateval = linear_interp(self.rate.value(),
                                            0, 99, 0, 3.99, lim=1, dec=2)
            self.rate_box.blockSignals(True)
            self.rate_box.setValue(self.rateval)
            self.rate_box.blockSignals(False)

        elif kind == 'rate_box':
            self.rateval = linear_interp(self.rate_box.value(),
                                            0, 3.99, 0, 3.99, lim=1, dec=2)
            self.rate.blockSignals(True)
            self.rate.setValue( int(linear_interp(self.rateval,
                                            0, 3.99, 0, 99, lim=1, dec=2)) )
            self.rate.blockSignals(False)

        elif kind == 'ipop_slider':
            self.ipopval = linear_interp(self.ipop.value(),
                                            0, 100, 0, 1, lim=1)

            self.ipop_box.blockSignals(True)
            self.ipop_box.setValue(float(self.ipopval))
            self.ipop_box.blockSignals(False)

        elif kind == 'ipop_box':
            self.ipopval = self.ipop_box.value()

            self.ipop.blockSignals(True)
            self.ipop.setValue( int(linear_interp(self.ipopval,
                                            0, 1, 0, 100, lim=1)) )
            self.ipop.blockSignals(False)

        else:
            # defaults
            self.rate_box.setValue(1.0)
            self.ipop_box.setValue(0.5)
            self.setValues('rate_box')
            self.setValues('ipop_box')

class Widget(QWidget):
    def __init__(self, app, parent=None):
        super(Widget, self).__init__(parent=parent)

        self.setStyleSheet(f"Widget {{ background-color: {colors['dark']}; }}")

        self.app = app

        self.horizontalLayout = QHBoxLayout(self)
        self.controls = Controls(parent=self)

        self.controls.setValues()
        self.horizontalLayout.addWidget(self.controls)

        self.win = pg.GraphicsLayoutWidget()

        self.setWindowTitle("Logistic Map ðŸ¤¯")
        self.horizontalLayout.addWidget(self.win)

        self.plots = [
                        self.win.addPlot(col=1, title="Cobwebb",
                                        labels={'left':"Population Next",
                                                'bottom':"Population"}),

                        self.win.addPlot(col=2, title="Population vs Time",
                                        labels={'left':"Population",
                                                'bottom':"Time"}),

                        self.win.addPlot(col=3, title="Bifurcations",
                                        labels={'left':"Equilibrium Population",
                                                'bottom':"Rates"}),
        ]

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.animate_plot)
        self.animate = False
        self.f = 0

        self.update_plot()

        self.controls.rate.valueChanged.connect(self.update_plot)
        self.controls.rate_box.valueChanged.connect(self.update_plot)
        self.controls.ipop.valueChanged.connect(self.update_plot)
        self.controls.cobweb_box.stateChanged.connect(self.update_plot)
        self.controls.series_box.stateChanged.connect(self.update_plot)
        self.controls.bifurc_box.stateChanged.connect(self.update_plot)
        self.controls.reset.pressed.connect(self.reset)
        self.controls.clear.pressed.connect(self.clear)
        self.controls.animb.pressed.connect(self.animate_toggle)

    def clear(self):
        print('Clear')
        for p in self.plots:
            p.clear()
        self.update_plot()

    def reset(self):
        print('Reset')
        self.animate = False
        self.timer.stop()
        self.f = 0
        self.update_plot()

    def animate_toggle(self):

        self.animate = not self.animate

        if self.animate:
            print('Animation play')
            self.update_plot()
            self.controls.animb.setText('Pause')
        else:
            print("Animation pause")
            self.timer.stop()
            self.controls.animb.setText('Play')

    def keyPressEvent(self, event):

        if event.key() == 32: # Space
            self.animate_toggle()

        elif event.key() == 16777219: # Backspace
            self.reset()

        else:
            print(f'Unknown keypress: {event.key()}, "{event.text()}"')

    def update_plot(self):

        if self.animate and self.f == 0:
            # start animate
            self.animspeed = self.controls.animrate.value()
            self.animspeed = max(1, self.animspeed)
            self.animspeed = 1000/self.animspeed # sec/frame -> frames/msec

            self.f = 0
            self.fmax = 100
            self.timer.start(int(self.animspeed))

            self.redraw_plots()

        elif self.animate and self.f != 0:

            # continue animate
            self.animspeed = self.controls.animrate.value()
            self.animspeed = max(1, self.animspeed)
            self.animspeed = 1000/self.animspeed

            self.timer.start(int(self.animspeed))

        elif not self.animate and self.f == 0:

            self.redraw_plots()

    def redraw_plots(self, index=0):

        """ redraw plots ; controlled by checkmarks """

        rate = self.controls.rateval
        ipop = self.controls.ipopval

        y_vals = cobweb_plot(self.plots[0], idx=0, r=rate, cobweb_x=ipop)

        if self.controls.cobweb_box.isChecked():
            self.plots[0].setVisible(True)
        else:
            self.plots[0].setVisible(False)

        if self.controls.series_box.isChecked():
            self.plots[1].setVisible(True)
            series_plot(self.plots[1], y_vals, r=rate, xall=True)
        else:
            self.plots[1].setVisible(False)

        if self.controls.bifurc_box.isChecked():
            self.plots[2].setVisible(True)
            bifurc_plot(self.plots[2], y_vals, r=rate, ipop=ipop)
        else:
            self.plots[2].setVisible(False)

    def animate_plot(self):

        rate = self.controls.rateval
        ipop = self.controls.ipopval

        y_vals = cobweb_plot(self.plots[0], idx=1 + self.f, r=rate, cobweb_x=ipop)

        if self.controls.cobweb_box.isChecked():
            self.plots[0].setVisible(True)
        else:
            self.plots[0].setVisible(False)

        if self.controls.series_box.isChecked():
            self.plots[1].setVisible(True)
            series_plot(self.plots[1], y_vals, idx =1 + self.f, r=rate)
        else:
            self.plots[1].setVisible(False)

        if self.controls.bifurc_box.isChecked():
            self.plots[2].setVisible(True)
            bifurc_plot(self.plots[2], y_vals, r=rate, ipop=ipop)
        else:
            self.plots[2].setVisible(False)

        self.f += 1

        if self.f >= self.fmax:
            self.timer.stop()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget(app)
    w.show()
    sys.exit(app.exec_())


import unittest, h5py, submitted
from gradescope_utils.autograder_utils.decorators import weight
import numpy as np

# TestSequence
class TestStep(unittest.TestCase):
    def setUp(self):
        self.h5 = h5py.File('solutions.hdf5','r')
        with h5py.File('data.hdf5','r') as f:
            self.sfreq = f['sfreq'][0]
            self.onesecond = f['onesecond'][:]
        self.filterlength = 1
        self.evenlength = 200
        self.oddlength = 201
        self.omegaL = 0.785398163397448

    @weight(7.15)
    def test_lpf_even(self):
        h_even = submitted.todo_lpf_even(self.evenlength, self.omegaL)
        e = np.sum(np.abs(h_even-self.h5['h_even']))/np.sum(np.abs(self.h5['h_even']))
        self.assertTrue(e < 0.04, 'todo_lpf_even wrong by more than 4% (visible case)')

    @weight(7.15)
    def test_lpf_odd(self):
        h_odd = submitted.todo_lpf_odd(self.oddlength, self.omegaL)
        e = np.sum(np.abs(h_odd-self.h5['h_odd']))/np.sum(np.abs(self.h5['h_odd']))
        self.assertTrue(e < 0.04, 'todo_lpf_odd wrong by more than 4% (visible case)')

    @weight(7.14)
    def test_h_theta(self):
        h_theta = submitted.todo_h_theta(self.sfreq, self.filterlength)
        e = np.sum(np.abs(h_theta-self.h5['h_theta']))/np.sum(np.abs(self.h5['h_theta']))
        self.assertTrue(e < 0.04, 'todo_h_theta wrong by more than 4% (visible case)')

    @weight(7.14)
    def test_convolve(self):
        h_theta = self.h5['h_theta']
        thetawaves = submitted.todo_convolve(self.onesecond, h_theta)
        e = np.sum(np.abs(thetawaves-self.h5['thetawaves']))/np.sum(np.abs(self.h5['thetawaves']))
        self.assertTrue(e < 0.04, 'todo_convolve wrong by more than 4% (visible case)')

    @weight(7.14)
    def test_h_alpha(self):
        h_alpha = submitted.todo_h_alpha(self.sfreq, self.filterlength)
        alphawaves = submitted.todo_convolve(self.onesecond, h_alpha)
        e = np.sum(np.abs(h_alpha-self.h5['h_alpha']))/np.sum(np.abs(self.h5['h_alpha']))
        self.assertTrue(e < 0.04, 'todo_h_alpha wrong by more than 4% (visible case)')
        e = np.sum(np.abs(alphawaves-self.h5['alphawaves']))/np.sum(np.abs(self.h5['alphawaves']))
        self.assertTrue(e < 0.04, 'todo_h_alpha alphawaves by more than 4% (visible case)')

    @weight(7.14)
    def test_h_beta(self):
        h_beta = submitted.todo_h_beta(self.sfreq, self.filterlength)
        betawaves = submitted.todo_convolve(self.onesecond, h_beta)
        e = np.sum(np.abs(h_beta-self.h5['h_beta']))/np.sum(np.abs(self.h5['h_beta']))
        self.assertTrue(e < 0.04, 'todo_h_beta wrong by more than 4% (visible case)')
        e = np.sum(np.abs(betawaves-self.h5['betawaves']))/np.sum(np.abs(self.h5['betawaves']))
        self.assertTrue(e < 0.04, 'todo_h_beta betawaves by more than 4% (visible case)')

    @weight(7.14)
    def test_h_gamma(self):
        h_gamma = submitted.todo_h_gamma(self.sfreq, self.filterlength)
        gammawaves = submitted.todo_convolve(self.onesecond, h_gamma)
        e = np.sum(np.abs(h_gamma-self.h5['h_gamma']))/np.sum(np.abs(self.h5['h_gamma']))
        self.assertTrue(e < 0.04, 'todo_h_gamma wrong by more than 4% (visible case)')
        e = np.sum(np.abs(gammawaves-self.h5['gammawaves']))/np.sum(np.abs(self.h5['gammawaves']))
        self.assertTrue(e < 0.04, 'todo_h_gamma gammawaves by more than 4% (visible case)')


import cv2
import os

video = cv2.VideoCapture(0,)
frames=1;
face_cascade=cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml');

while True:
    frames+=1;
    check,frame=video.read()

    #gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    faces=face_cascade.detectMultiScale(frame,scaleFactor=1.5,minNeighbors=5)
    for x,y,w,h in faces:

        gray=cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),3)

    cv2.imshow('Capturing',frame)

    if cv2.waitKey(1)==27:
        break

print(frames)
video.release()
cv2.destroyAllWindows()


# -*- coding: utf-8 -*-

from airflow.operators.mssql_operator import MsSqlOperator

class MsSqlTableOperator(MsSqlOperator):
    template_fields = ('sql_template_params', )

    def __init__(
        self,
        project,
        table,
        sql_template_params,
        mssql_conn_id,
        database,
        sql,
        build_query,
        autocommit=True,
        *args, **kwargs
    ):
        self.project = project
        self.table = table
        self.sql_template_params = sql_template_params
        self.build_query = build_query(self)

        MsSqlOperator.__init__(
            self,
            mssql_conn_id=mssql_conn_id,
            database=database,
            sql=sql,
            autocommit=autocommit,
            *args,
            **kwargs
        )

    def execute(self, context):
        self.sql = self.build_query(context).format(**self.sql_template_params)

        MsSqlOperator.execute(self, context)


"""Configuration helper functions."""
import os
import tiktoken

# Load the environment variables if working in weird environments
def load_from_env_file():
    """Load environment variables from a file."""
    # Load environment variables from project root .env file
    # Get the current file's directory
    current_dir = os.path.dirname(os.path.abspath(__file__))
    # Get the parent directory of the current file's directory
    parent_dir = os.path.abspath(os.path.join(current_dir, os.pardir))
    # Set path of .env file
    env_path = os.path.join(parent_dir, ".env")
    try:
        # Load environment variables from .env file
        load_env_vars(env_path)
    except FileNotFoundError:
        pass

def load_env_vars(path):
    """Load environment variables from a file."""
    with open(path) as f:
        for line in f:
            if "=" in line and not line.startswith("#"):
                # Split the line into the variable name and value
                var, value = line.split("=")

                # Strip leading and trailing whitespace from the variable name and value
                var = var.strip()
                value = value.strip()

                if var and value:
                    # Set the environment variable
                    os.environ[var] = value

# OpenAI method for counting tokens
def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0301"):
    """Returns the number of tokens used by a list of messages."""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        encoding = tiktoken.get_encoding("cl100k_base")
    if model == "gpt-3.5-turbo-0301":  # note: future models may deviate from this
        num_tokens = 0
        for message in messages:
            num_tokens += 4  # every message follows <im_start>{role/name}\n{content}<im_end>\n
            for key, value in message.items():
                num_tokens += len(encoding.encode(value))
                if key == "name":  # if there's a name, the role is omitted
                    num_tokens += -1  # role is always required and always 1 token
        num_tokens += 2  # every reply is primed with <im_start>assistant
        return num_tokens
    else:
        raise NotImplementedError(f"""num_tokens_from_messages() is not presently implemented for model {model}.
  See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens.""")


#-------------------------------------------------------------------------------
# bob: benchmark/bench1.py
#
# Benchmark interpreter vs. compiler/VM
#
# Eli Bendersky (eliben@gmail.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
import sys, os
from utils import vm_compiler_runner, interpreter_runner, make_barevm_runner

sys.path.insert(0, '../..')
from bob.utils import Timer
barevm_path = "../barevm/barevm.exe"

code_str = '''
(define (divides k n)
    (= (modulo n k) 0))

(define (primecheck num)
    (define (auxprimecheck divisor)
        (cond
            ((= divisor num) #t)
            ((divides divisor num) #f)
            (else (auxprimecheck (+ 1 divisor)))))
    (auxprimecheck 2))

(write (primecheck 5903))  ; it's a prime!
'''

# Since the interpreter isn't tail-recursive, this is required
sys.setrecursionlimit(200000)

#with Timer('interp'):
    #interpreter_runner(code_str, None)

with Timer('comp_vm'):
    vm_compiler_runner(code_str, None)

with Timer('barevm'):
    make_barevm_runner(barevm_path)(code_str, None)


from torch.utils import data
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision import transforms as T
import torch

class MNIST_Data(data.Dataset):
    def __init__(self, data, labels):
        super().__init__()
        self.data = data
        self.labels = labels

    def __len__(self):
        return len(self.data)

    def __getitem__(self, index):
        x = self.data[index]
        y = self.labels[index]
        return x,y

def load_mnist(mode):
    transform = []
    transform.append(T.ToTensor())
    transform.append(T.Normalize(mean=[0.5], std=[0.5]))
    transform = T.Compose(transform)
    if mode == "train":
        dataset = datasets.MNIST(root="../data", train=True, transform=transform, download=True)
    elif mode == "test":
        dataset = datasets.MNIST(root="../data", train=False, transform=transform, download=True)

    x = dataset.data.float()
    y = dataset.targets

    return x,y

def get_loader(batch_size, mode, num_workers):
    x,y = load_mnist(mode)
    datasets = MNIST_Data(x,y)
    data_loader = DataLoader(dataset = datasets,
                            batch_size = batch_size,
                            shuffle = (mode=="train"),
                            num_workers = num_workers)
    return data_loader


from collections import defaultdict
from copy import copy

def split(s, where=","):
    return s.split(where)

def fill_between(edges):
    cave = defaultdict(dict)

    for i in range(len(edges) - 1):
        start = tuple(map(int, edges[i]))
        stop = tuple(map(int, edges[i + 1]))
        dx = stop[0] - start[0]
        dy = stop[1] - start[1]
        if dx == 0:
            x = start[0]
            if dy < 0:
                ys = {y: "#" for y in range(stop[1], start[1] + 1)}
            else:
                ys = {y: "#" for y in range(start[1], stop[1] + 1)}
            cave[x] |= ys
        elif dy == 0:
            y = start[1]
            ys = {y: "#"}
            if dx < 0:
                xs = range(stop[0], start[0] + 1)
            else:
                xs = range(start[0], stop[0] + 1)
            for x in xs:
                cave[x] |= ys

    return cave

def print_cave(cave):
    min_x = min(cave.keys())
    min_y = min([y for v in cave.values() for y in v.keys()])
    max_x = max(cave.keys())
    max_y = max([y for v in cave.values() for y in v.keys()])
    for y in range(min_y, max_y + 1):
        for x in range(min_x, max_x + 1):
            c = cave.get(x)
            if c is not None:
                c = c.get(y, ".")
            else:
                c = "."
            print(c, end="")
        print()

def parse(filename):
    cave = defaultdict(dict)
    for line in open(filename).readlines():
        edges = list(map(split, map(str.strip, line.split("->"))))
        for x, ys in fill_between(edges).items():
            cave[x] |= ys
    return cave

def count_sand(cave):
    s = 0
    for x in cave.keys():
        for c in cave[x].values():
            if c == "o":
                s += 1
    return s

def part_a(cave, b=False):
    init_sand = {"x": 500, "y": 0}
    n_sand = 0

    max_y = max([y for v in cave.values() for y in v.keys()])

    if b:
        max_y += 1

    sand = copy(init_sand)
    while True:
        # drop down
        x = sand["x"]
        y = sand["y"] + 1

        if y > max_y:
            if b:
                cave[sand["x"]][sand["y"]] = "o"
                n_sand += 1
                sand = copy(init_sand)
                continue
            # fall into abyss
            else:
                break

        if y not in cave[x]:
            sand["y"] = y

        # drop down and left
        elif y not in cave[x - 1]:
            sand["y"] = y
            sand["x"] -= 1

        # drop down and right
        elif y not in cave[x + 1]:
            sand["y"] = y
            sand["x"] += 1

        else:
            # sand is at rest
            cave[sand["x"]][sand["y"]] = "o"
            n_sand += 1
            if sand == {"x": 500, "y": 0}:
                break
            sand = copy(init_sand)

    return count_sand(cave)

if __name__ == "__main__":
    ex = parse("examples/14.txt")
    f = parse("build/14")
    assert part_a(copy(ex)) == 24
    print(part_a(copy(f)))
    assert part_a(copy(ex), b=True) == 93
    print(part_a(copy(f), b=True))


import numpy as np
from scipy import sparse
from collections import Counter
from sklearn.metrics import accuracy_score, precision_recall_fscore_support
from sklearn.model_selection import train_test_split
import nltk
from nltk.corpus import stopwords
import string
import pandas as pd

stop_words = []
with open('./stop_words.txt', 'r') as f:
    for word in f.readlines():
        stop_words.append(word)
stop_words = set(stop_words + list(string.punctuation))

# Q1-2
def tokenize(text):
    '''
    :param text: a doc with multiple sentences, type: str
    return a word list, type: list
    https://textminingonline.com/dive-into-nltk-part-ii-sentence-tokenize-and-word-tokenize
    e.g.
    Input: 'It is a nice day. I am happy.'
    Output: ['it', 'is', 'a', 'nice', 'day', 'i', 'am', 'happy']
    '''
    tokens = []
    # YOUR CODE HERE

    return tokens

# Q1-3
def get_bagofwords(data, vocab_dict):
    '''
    :param data: a list of words, type: list
    :param vocab_dict: a dict from words to indices, type: dict
    return a word (sparse) matrix, type: scipy.sparse.csr_matrix
    https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.lil_matrix.html
    https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.csr_matrix.html
    '''
    data_matrix = sparse.lil_matrix((len(data), len(vocab_dict)))
    # YOUR CODE HERE

    return data_matrix

# Q1-1 Note that, here you need to use Q1-2 and Q1-3.
def read_data(file_name, vocab=None):
    """
    https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html
    """
    df = pd.read_csv(file_name)
    df['words'] = df['text'].apply(tokenize)

    if vocab is None:
        vocab = set()
        for i in range(len(df)):
            for word in df.iloc[i]['words']:
                vocab.add(word)
    vocab_dict = dict(zip(vocab, range(len(vocab))))

    data_matrix = get_bagofwords(df['words'], vocab_dict)

    return df['id'], df['label'], data_matrix, vocab

# Q2-1
def normalize(P):
    """
    normalize P to make sure the sum of the first dimension equals to 1
    e.g.
    Input: [1,2,1,2,4]
    Output: [0.1,0.2,0.1,0.2,0.4] (without laplace smoothing) or [0.1333,0.2,0.1333,0.2,0.3333] (with laplace smoothing)

    Numpy Sum https://numpy.org/doc/stable/reference/generated/numpy.sum.html
    """
    # YOUR CODE HERE

    return None

# Q2-2, Q2-3
def train_NB(data_label, data_matrix):
    '''
    :param data_label: [N], type: list
    :param data_matrix: [N(document_number) * V(Vocabulary number)], type:  scipy.sparse.csr_matrix
    return the P(y) (an K array), P(x|y) (a V*K matrix)
    '''
    N = data_matrix.shape[0]
    K = max(data_label) # labels begin with 1
    # YOUR CODE HERE

    return P_y, P_xy

# Q3
def predict_NB(data_matrix, P_y, P_xy):
    '''
    :param data_matrix: [N(document_number), V(Vocabulary number)], type:  scipy.sparse.csr_matrix
    :param P_y: [K(class number)], type: np.ndarray
    :param P_xy: [V, K], type: np.ndarray
    return data_pre (a N array)
    '''
    # compute the label probabilities using the P(y) and P(x|y) according to the naive Bayes algorithm
    # YOUR CODE HERE

    # get labels for every document by choosing the maximum probability
    # YOUR CODE HERE
    return None

def evaluate(y_true, y_pre):
    assert len(y_true) == len(y_pre)
    acc = accuracy_score(y_true, y_pre)
    # average='macro', calculate the average precision, recall, and F1 score of all categories.
    precision, recall, f1, _ = precision_recall_fscore_support(y_true, y_pre, average="macro")
    return acc, precision, recall, f1

def evaluate_each_category(y_true, y_pre):
    assert len(y_true) == len(y_pre)
    acc = accuracy_score(y_true, y_pre)
    # average='macro', calculate the precision, recall, and F1 score of each category.
    precision, recall, f1, _ = precision_recall_fscore_support(y_true, y_pre, average=None)
    return acc, precision, recall, f1

if __name__ == '__main__':
    # Read train.csv
    train_id_list, train_data_label, train_data_matrix, vocab = read_data("data/train.csv")
    # Divide train.csv into train set(80%) and validation set (20%).
    X_train, X_validation, y_train, y_validation = train_test_split(train_data_matrix, train_data_label, test_size=0.2)
    print("Vocabulary Size:", len(vocab))
    print("Training Set Size:", len(y_train))
    print("Validation Set Size:", len(y_validation))
    # Read test.csv
    test_id_list, _, test_data_matrix, _ = read_data("data/test.csv", vocab)
    print("Test Set Size:", len(test_id_list))

    # training
    P_y, P_xy = train_NB(y_train, X_train)
    train_data_pre = predict_NB(X_train, P_y, P_xy)
    acc, precision, recall, f1 = evaluate(y_train, train_data_pre)
    print("Evalution in train set: Accuracy: %f\tPrecision: %f\tRecall: %f\tMacro-F1: %f" % (acc, precision, recall, f1))

    # validation
    validation_data_pre = predict_NB(X_validation, P_y, P_xy)
    acc, precision, recall, f1 = evaluate(y_validation, validation_data_pre)
    print("Evalution in Validation set: Accuracy: %f\tPrecision: %f\tRecall: %f\tMacro-F1: %f" % (acc, precision, recall, f1))

    acc, precision, recall, f1 = evaluate_each_category(y_validation, validation_data_pre)
    print("Evalution in test set in each category: \nAccuracy:",acc,"\nPrecision:",precision, "\nRecall:",recall, '\nF1:',f1)

    # Predict the label of each documents in the test set
    test_data_pre = predict_NB(test_data_matrix, P_y, P_xy)

    sub_df = pd.DataFrame()
    sub_df["id"] = test_id_list
    sub_df["pred"] = test_data_pre
    sub_df.to_csv("submission.csv", index=False)
    print("Predict Results are saved, please check the submission.csv")


# encoding=utf-8
import hashlib
import os
import random
from collections import OrderedDict
import gym
from gym import spaces
from gym_malware.envs.controls import action as manipulate
from gym_malware.envs.utils import interface, pefeatures, reward
from config import *

ACTION_LOOKUP = {i: act for i, act in enumerate(
    manipulate.ACTION_TABLE.keys())}

label_function = reward.label_function

class MalwareEnv(gym.Env):
    metadata = {'render.modes': ['human']}

    def __init__(self, sha256list, random_sample=True, maxturns=10, output_path='evaded/blackbox/', cache=True,
                 test=False, engine='fsecure'):
        self.total_turn = 0
        self.episode = -1  # 共训练了多少轮
        self.cache = cache
        self.available_sha256 = sha256list
        self.action_space = spaces.Discrete(len(ACTION_LOOKUP))
        self.maxturns = maxturns
        self.feature_extractor = pefeatures.PEFeatureExtractor()
        self.random_sample = random_sample
        self.sample_iteration_index = 0
        self.test = test
        self.output_path = os.path.join(
            os.path.dirname(
                os.path.dirname(
                    os.path.dirname(
                        os.path.abspath(__file__)))), output_path)
        if not os.path.exists(output_path):
            os.makedirs(output_path)

        self.history = OrderedDict()

        self.samples = {}
        self.set_engine(engine)
        if self.cache:
            for sha256 in self.available_sha256:
                try:
                    self.samples[sha256] = interface.fetch_file(sha256, self.test)
                except Exception as e:
                    print("failed fetching file {}".format(e))
                    continue  # try a new sha256...this one can't be retrieved from storage

        self.reset()

    def set_engine(self, engine):
        self.reward_engine = eval('reward.'+reward.ENGINE_TABLE[engine]+'()')

    def step(self, action_index):
        reward = 0
        self.total_turn += 1
        self.turns += 1
        # a_t
        self._take_action(action_index)  # update self.bytez
        # 调用杀毒软件 get reward R_(t+1)
        try:
            self.label = label_function(self.reward_engine, self.bytez)
        except interface.ClassificationFailure:
            print("Failed to classify file")
            episode_over = True
        self.observation_space = self.feature_extractor.extract(self.bytez)
        if self.label == 0:
            # reward = 10
            reward = 10.0+self.maxturns-self.turns
            print("success!")
            with open(os.path.join(LOG_PATH, "log.txt"), "a+") as f:
                f.write("successfully evaded after {} actions!\n".format(self.turns))
            episode_over = True
            self.history[self.sha256]['evaded'] = True

            # store sample to output directory
            if self.test:
                m = hashlib.sha256()
                m.update(self.bytez)
                sha256 = m.hexdigest()
                self.history[self.sha256]['evaded_sha256'] = sha256

                with open(os.path.join(self.output_path, sha256), 'wb') as outfile:
                    outfile.write(self.bytez)
        elif self.turns >= self.maxturns:
            print("label:", self.label)
            reward = 0.0
            episode_over = True
        else:
            reward = 0.0
            episode_over = False

        # S_(t+1), R_(t+1), done, info
        return self.observation_space, reward, episode_over, {}

    def _take_action(self, action_index):
        assert action_index < len(ACTION_LOOKUP)
        action = ACTION_LOOKUP[action_index]
        self.history[self.sha256]['actions'].append(action)
        self.bytez = bytes(manipulate.modify_without_breaking(self.bytez, action))
        print("turns {} : _take_action {}".format(self.turns, action))
        with open(os.path.join(LOG_PATH, "log.txt"), 'a+') as f:
            f.write("turns {} : {}, ".format(self.turns, action))

    def reset(self):
        self.turns = 0
        self.episode += 1
        while True:
            # get the new environment
            if self.random_sample:
                self.sha256 = random.choice(self.available_sha256)
            else:  # draw a sample at random
                self.sha256 = self.available_sha256[self.sample_iteration_index % len(self.available_sha256)]
                self.sample_iteration_index += 1

            self.history[self.sha256] = {'actions': [], 'evaded': False}
            if self.cache:
                self.bytez = self.samples[self.sha256]
            else:
                try:
                    self.bytez = interface.fetch_file(self.sha256, self.test)
                except interface.FileRetrievalFailure:
                    print("failed fetching file")
                    continue  # try a new sha256...this one can't be retrieved from storage

            self.tips = ' ' if not self.test else 'test '

            if self.episode > 0:
                with open(os.path.join(LOG_PATH, "log.txt"), "a+") as f:
                    f.write("---------------------------------------------------------------------------------------\n")
                    f.write("{}episode {} select training sample: {}\n".format(self.tips, self.episode, self.sha256))
                print("--------------------------------------------------------------------------------")
                print("{}episode {} select training sample: {}".format(self.tips, self.episode, self.sha256))
                print("--------------------------------------------------------------------------------")

            self.observation_space = self.feature_extractor.extract(self.bytez)
            break  # we're done here

        return self.observation_space


"""
                            - Generators -

PROGRAMMED BY: Jean Flaherty
DATE: 07/14/2017
DESCRIPTION:
    Utility functions for generators.
"""
from .ansi import ANSI

def print_generator(label, gen, period=1, end="\n"):
    """
    A generator that prints the value generated by a given generator
    as they are generated.

    ARGUMENTS:
        label  - Text that goes before the printed value.
        gen    - The generator to print.
        period - (Optional) How often the generated value should be printed.
                 Useful when printing slows run time.
        end    - (Optional) Defaults to "\n" and is used for print(args**, end)
    """
    try:
        i = 0
        while True:
            try:
                value = next(gen)
            except StopIteration:
                return
            if i % period == 0:
                print(label + "{0: <40}".format(str(value).rstrip("\n"))[:40], end=end)
            yield value
            i += 1
    finally:
        print(ANSI.CLEAR_LINE, end="\r")

def print_progress_generator(label, gen, total, period=1):
    """
    A generator that prints the value generated by a given generator
    as they are generated.

    ARGUMENTS:
        label  - Text that goes before the printed value.
        gen    - The generator to print.
        period - (Optional) How often the generated value should be printed.
                 Useful when printing slows run time.
        end    - (Optional) Defaults to "\n" and is used for print(args**, end)
    """
    try:
        i = 0
        while True:
            if (i % period == 0 or i+1 == total) and total > 0:
                print(label + "{:.2f}%".format(100.0*float(i+1)/float(total)), end="\r")
            try:
                yield next(gen)
            except StopIteration:
                return
            i += 1
    finally:
        print()


import json
from airflow import DAG
from datetime import datetime,timedelta
from airflow.providers.http.operators.http import SimpleHttpOperator
from airflow.providers.http.sensors.http import HttpSensor
from airflow.operators.python import PythonOperator
import pandas as pd
import os

def kelvin_to_farenheit(temp_in_kelvin):
    temp_in_farenheit = (temp_in_kelvin - 273.15) * (9/5) + 32
    return temp_in_farenheit

def transform_load_data(task_instance):
    data = task_instance.xcom_pull(task_ids ="extract_api_data")
    city = data["name"]
    weather_description = data["weather"][0]['description']
    temp_farenheit = kelvin_to_farenheit(data["main"]["temp"])
    feels_like_farenheit = kelvin_to_farenheit(data["main"]["feels_like"])
    min_temp_farenheit = kelvin_to_farenheit(data["main"]["temp_min"])
    max_temp_farenheit = kelvin_to_farenheit(data["main"]["temp_max"])
    pressure = data["main"]["pressure"]
    humidity = data["main"]["humidity"]
    wind_speed = data["wind"]["speed"]
    time_of_record = datetime.utcfromtimestamp(data['dt'] + data["timezone"])
    sunrise_time = datetime.utcfromtimestamp(data["sys"]["sunrise"] + data["timezone"])
    sunset_time = datetime.utcfromtimestamp(data["sys"]["sunset"] + data["timezone"])

    transformed_data = {
        "City" : city,
        "Description" : weather_description,
        "Temperature (F)" : temp_farenheit,
        "Feels Like (F)" : feels_like_farenheit,
        "Minimum Temp (F)" : min_temp_farenheit,
        "Maximum Temp (F)" : max_temp_farenheit,
        "Pressure" : pressure,
        "Humidity" : humidity,
        "Wind Speed" : wind_speed,
        "Time of Record" : time_of_record,
        "Sunrise (Local Time)" : sunrise_time,
        "Sunset (Local Time)" : sunset_time
    }

    transformed_data_list = [transformed_data]
    df_data = pd.DataFrame(transformed_data_list)

    now = datetime.now()
    dt_string = now.strftime("%d%m%Y%H%M%S")
    file_name = 'current_weather_data_Mumbai' + dt_string + '.csv'
    current_directory = os.path.dirname(__file__)
    file_path = os.path.join(current_directory, file_name)
    df_data.to_csv(file_path, index=False)

default_args = {
    'owner' : 'vishal',
    'depends_on_past' : False,
    'start_date' : datetime(2023,9,22),
    'retries' : 5,
    'retry_delay' : timedelta(minutes = 2)
}

with DAG(
    dag_id = 'weather_api',
    default_args = default_args,
    schedule_interval = '@daily',
    catchup = False
)as dag:
    task1 = HttpSensor(
        task_id = 'weather_api_ready',
        http_conn_id = 'weathermap_api',
        endpoint = '/data/2.5/weather?q=Mumbai&appid={api_key}'
    )

    task2 = SimpleHttpOperator(
        task_id = 'extract_api_data',
        http_conn_id = 'weathermap_api',
        endpoint = '/data/2.5/weather?q=Mumbai&appid={api_key}',
        method="GET",
        response_filter=lambda r : json.loads(r.text),
        log_response=True
    )

    task3 = PythonOperator(
        task_id = 'transform_load_weather_data',
        python_callable = transform_load_data
    )

    task1 >> task2 >> task3


from Modules import Commits, Log

import time
import hashlib
from flask import Flask, render_template, url_for, send_from_directory, request

app = Flask('Portfolio')
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

@app.route("/")
def home():
    Log.LogVisit(request)
    return render_template(
            "index.html",
            Events=Commits.GetCommits()
        )

@app.route('/favicon.ico')
@app.route('/robots.txt')
@app.route('/sitemap.xml')
def static_from_root():
    return send_from_directory(app.static_folder, request.path[1:])

if __name__ == "__main__":
    app.run(host='0.0.0.0',debug=True)


import os

from flask import Flask
from flask import render_template
from flask_bootstrap import Bootstrap5

from . import db

def create_app(test_config=None):
    app = Flask(__name__, instance_relative_config=True)
    Bootstrap5(app)

    app.config.from_mapping(
        SECRET_KEY='dev',
        DATABASE=os.path.join(app.instance_path, 'next.sqlite'),
    )

    if test_config is None:
        app.config.from_pyfile('config.py', silent=True)
    else:
        app.config.from_mapping(test_config)

    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    db.init_app(app)

    @app.route('/')
    def index():
        name = 'Library "3 Books"'
        return render_template('enter.html', name=name)

    return app


# -*- encoding=utf-8 -*-
__all__ = ['get_intention']
import json
import sys
import os
import traceback
import copy
pathDir = os.path.dirname(__file__)
curPath = os.path.abspath(pathDir)
rootPath = os.path.split(curPath)[0]
sys.path.append(os.path.split(rootPath)[0])
sys.path.append(rootPath)
from voiceAssistant.getWord import get_word_inverted_index
from voiceAssistant.intentGreet.get_intention_word import GetIntentByRe
from voiceAssistant.fieldWord.get_field_word1 import get_field_word
from voiceAssistant.text_error_correct.correct_txt_error import CorrectTextError
from voiceAssistant.setParameter import SetParameter
from voiceAssistant.rePattern.pattern_obj import GetPatternByRe
from voiceAssistant.rePattern.pattern_str import pattern_intent_combine, pattern_intent_divide
from voiceAssistant.Text_classification.txt_classification.classification_model import predict_model

def _get_pattern_obj(str_):
    gibr = GetPatternByRe(str_)
    return gibr.get_compile_ptn()

# 获得四个模式串
pattern_divide = pattern_intent_divide()

class GetIntention(object):
    def __init__(self):
        self._sp = SetParameter()  # 返回参数设置
        self._sr = CorrectTextError()  # 同义词替换等
        self._intent_code_dir = self._sp.intent_code_dir
        self._field_code_dir = self._sp.field_code_dir
        self._except_code_dir = self._sp.except_code_dir
        self._TipTxt_100 = self._sp.except_TipTxt_100
        self._TipTxt_greet_0 = self._sp.greet_tiptxt_0
        self._TipTxt_greet1_0 = self._sp.greet1_tiptxt_0
        self._TipTxt_101 = self._sp.except_TipTxt_101
        self._TipTxt_102 = self._sp.except_TipTxt_102
        self._intend_word_dir, self._field_word_dir, self._intend_word_div = get_word_inverted_index()
        self._get_intent_word = GetIntentByRe()

        # 初始化编译模式串
        self.pattern_great = _get_pattern_obj(pattern_divide['pattern_greet'])
        self.pattern_repair = _get_pattern_obj(pattern_divide['pattern_repair'])
        self.pattern_complaint = _get_pattern_obj(pattern_divide['pattern_complaint'])
        self.pattern_quary = _get_pattern_obj(pattern_divide['pattern_quary'])
        self.pattern_buy = _get_pattern_obj(pattern_divide['pattern_buy'])
        self.pattern_combine = _get_pattern_obj(pattern_divide['pattern_combine'])
        self.punc = self._sp.punc
        self.greet_list = self._sp.greet_time_list
        # self.special_word = self.sr.special_word()
        # self.add_word = self.sr.add_word()

        # sklearn 三种方法进行文本分类
        self.path_fearture_space = os.path.join(pathDir, 'Text_classification', 'data_models/')
        self.path_models = os.path.join(pathDir, 'Text_classification', 'data_models/')
        self.clf_model = self._sp.clf_models
        # 有以下三个模型可供选择
        # RandomForestClassifier   LogisticRegression   MultinomialNB SVM
        self.classifier = predict_model(self.clf_model['LogisticRegression'], self.path_fearture_space, self.path_models)
        self.alpha = self._sp.alpha

    def get_intent_result(self, input_txt, data):

        # data = {
        #     'intentionType': 100,
        #     'queryType': 0,
        #     'instParas': '',
        #     'tipTxt': '',
        #     'conTxt': ''
        #     }

        try:
            repair_pattern = self.pattern_repair.search(input_txt).group()
            if repair_pattern:
                repair_intent = repair_pattern
                contxt = input_txt.replace(repair_intent, '')
                contxt = self.remove_punc_start(contxt)
                data['intentionType'] = 1
                data['conTxt'] = contxt.replace(' ', '')
                return data, 1

            complaint_pattern = self.pattern_complaint.search(input_txt).group()
            if complaint_pattern:
                complaint_intent = complaint_pattern
                contxt = input_txt.replace(complaint_intent, '')
                contxt = self.remove_punc_start(contxt)
                data['intentionType'] = 2
                data['conTxt'] = contxt.replace(' ', '')
                return data, 1

            # 查询意图匹配
            quary_pattern = self.pattern_quary.search(input_txt).group()
            if quary_pattern:
                quary_intent = quary_pattern
                contxt = input_txt.replace(quary_intent, '')
                data, quary_succeed = self.get_querytype(contxt, data)
                return data, 1

            buy_pattern = self.pattern_buy.search(input_txt).group()
            if buy_pattern:
                buy_intent = buy_pattern
                contxt = input_txt.replace(buy_intent, '')
                contxt = self.remove_punc_start(contxt)
                data['intentionType'] = 4
                data['conTxt'] = contxt.replace(' ', '')
                return data, 1
            return data, 0
        except:
            print('traceback.print_exc():', traceback.print_exc())
            return data, 0

    def get_querytype(self, ConTxt, data):
        """
        '查询'意图清晰的情况下,获得查询类型，以及异常处理
        :param ConTxt:
        :return: 返回查询领域类型和提示
        """
        field_word = get_field_word(self._field_word_dir, ConTxt)

        # field_word = search_field_word(self.field_word_dir, ConTxt)
        if len(field_word) == 1:
            data['intentionType'] = 3
            data['queryType'] = self._field_code_dir[field_word[0]]
            return data, 1
        elif len(field_word) >= 1:
            data['intentionType'] = 3
            data['queryType'] = self._except_code_dir['102异常']
            TipTxt = self._TipTxt_102
            for txt in field_word:
                TipTxt = TipTxt + txt + '、'
            TipTxt = TipTxt[:-1]
            data['tipTxt'] = TipTxt
            return data, 1
        else:
            # 商品购买识别
            data, succeed = self.txt_forecast(self.classifier, ConTxt, data)
            if succeed == 1:
                return data, 1
            data['intentionType'] = self._except_code_dir['100异常']
            # data['queryType'] = self._except_code_dir['101异常']
            data['tipTxt'] = self._TipTxt_100
            return data, 1

    def get_no_intent_querytype(self, ConTxt):
        """
        # 意图不清晰的情况下,获得查询类型，以及异常处理
        :param ConTxt:
        :return: 返回查询领域类型和提示
        """
        queryType = 0
        TipTxt = ''
        field_word = get_field_word(self._field_word_dir, ConTxt)
        if len(field_word) == 1:
            queryType = self._field_code_dir[field_word[0]]
            return queryType, TipTxt, 1
        if len(field_word) > 1:
            queryType = self._except_code_dir['102异常']
            TipTxt = self._TipTxt_102
            for txt in field_word:
                TipTxt = TipTxt + txt + '、'
            TipTxt = TipTxt[:-1]  # 去掉最后的顿号
            return queryType, TipTxt, 1

        return queryType, TipTxt, 0

    def get_greet_result(self, greet_txt, data):
        """
        # 根据时间来智能回复
        # if greet_txt in self.greet_list:
        #     tipTxt = greet_txt + self._TipTxt_greet1_0
        #     data['tipTxt'] = tipTxt
        #     data['intentionType'] = self._intent_code_dir['问候语']
        #     return data
        """
        tipTxt = self._TipTxt_greet_0
        data['tipTxt'] = tipTxt
        data['intentionType'] = self._intent_code_dir['问候语']
        return data

    def remove_punc_start(self, input_txt):
        if not input_txt:
            return input_txt
        else:
            if input_txt[0] in self.punc:
                input_txt = input_txt[1:]
        return input_txt

    def remove_punc_end(self, input_txt):

        if not input_txt:
            return input_txt
        else:
            if input_txt[-1] in self.punc:
                input_txt = input_txt[:-1]
        return input_txt

    def remove_punc_all(self, inputtxt):
        txt = copy.deepcopy(inputtxt)
        for each_punc in self.punc:
            txt.replace(each_punc, '')
        return txt, inputtxt

    def txt_forecast(self, classifier, input_txt, data):
        if len(input_txt.strip()) == 0:
            return data, 0
        result, proba = classifier.txt_predict(input_txt)

        # print(result, max(proba))
        # type_list = ['不可识别', '商品搜索', '家具报修', '建议与投诉', '查询电话号码', '问候语']
        # print([{key: '{0:.7f}'.format(value)} for key, value in zip(type_list, proba)])

        # print(max(proba), self.alpha[result])
        if max(proba) > self.alpha[result] and result != '不可识别':
            if result in self._intent_code_dir.keys():  # 判断类别在意图词中是否存在
                data['intentionType'] = self._intent_code_dir[result]
                data['conTxt'] = self.remove_punc_end(input_txt.replace(' ', ''))

            elif result in self._field_code_dir.keys():  # 判断类别在领域词中是否存在
                data['intentionType'] = int(self._intent_code_dir['查询'])
                data['queryType'] = self._field_code_dir[result]
            return data, 1
        else:
            return data, 0

    def get_intention(self, areaCode, ownerCode, inputTxt):
        """

        :param ownerCode:
        :param areaCode:
        :param inputTxt:
        :return:
        """
        data = {
            'intentionType': 100,
            'queryType': 0,
            'instParas': '',
            'tipTxt': '',
            'conTxt': ''}
        # 如果输入为空
        if not inputTxt:
            tipTxt = self._TipTxt_100
            data['tipTxt'] = tipTxt
            return data
        # 输入文本的预处理
        inputTxt = self.remove_punc_end(inputTxt)
        inputTxt = self._sr.correct_homophonic_text(inputTxt)
        inputTxt = self._sr.replace_special_word(inputTxt)

        # 1、获取问候语----------------------------------------------
        great_intent, inputTxt = self._get_intent_word.get_greet_intent(inputTxt)
        # print(1, great_intent, "\t", 2, inputTxt)
        inputTxt = self.remove_punc_start(inputTxt)
        if not inputTxt:
            return self.get_greet_result(great_intent, data)

        # 2、处理特殊表达---------------------------------------------
        data, succeed = self._sr.process_special_expression(str_1=self.remove_punc_all(inputTxt),
                                                            inputtxt=inputTxt,
                                                            data=data)
        if succeed == 1:
            return data
        # 3、获取意图词通过正则表达式------------------------------------
        data, succeed = self.get_intent_result(inputTxt, data)
        # print(1, intend_word, "\t", 2, contxt)
        if succeed == 1:
            return data
        else:

            # 4、无意图的领域词分析---------------------------------------
            query_type, tip_txt, succeed = self.get_no_intent_querytype(inputTxt)
            if succeed == 1:
                data['intentionType'] = int(self._intent_code_dir['查询'])
                data['queryType'] = query_type
                data['tipTxt'] = tip_txt
                return data

            # 5、文本分类算法分析输入意图----------------------------------
            data, succeed = self.txt_forecast(self.classifier, inputTxt, data)
            # print('1、----------------------')
            # print(data)
            # print('-------------------------', succeed)
            if succeed == 1:
                return data

        # 不可识别类做默认引导回复------------------------------------------
        data['intentionType'] = int(self._except_code_dir['100异常'])
        data['queryType'] = 0
        data['tipTxt'] = self._TipTxt_100
        return data

if __name__ == '__main__':
    # f = open(r"E:\Document\python\hisense_test\Voice_Assistant_test\语音助手.txt", 'r', encoding='utf-8-sig')
    f = open(r"E:\Document\python\hisense_test\Voice_Assistant_test\测试用例1_0.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\2_.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\3_1.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\3_2.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\3_3.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\3_4.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\3_5.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\3_6.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\3_101.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\3_102.txt", 'r', encoding='utf-8-sig')
    # f = open(r"E:\Document\python\project\测试用例\voiceAssistant\3_102.txt", 'r', encoding='utf-8-sig')

    data_test = f.readlines()
    data_tmp = []
    for each_data in data_test:
        data_tmp.append(each_data.replace('\n', '').replace('，', ''))

    inputTxt = '报修我家的物业不好好干活'
    # inputTxt = ''
    ownerCode = 0
    areaCode = 0
    gi = GetIntention()
    # print(get_intention1(ownerCode, areaCode, inputTxt))
    n = 0
    f = open(r'E:\Document\python\hisense_test\Voice_Assistant_test\result2.json', 'w', encoding='utf-8')
    for each in data_tmp:
        # print(n, each)
        n += 1
        # result_ = get_intention1(ownerCode, areaCode, each)
        result_ = gi.get_intention(ownerCode, areaCode, each)
        print(result_)
        f.write(str(n) + '、' + each + '\n' + json.dumps(result_, indent=4, ensure_ascii=False) + '\n')
    f.close()


import argparse
import cv2
import json
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
import os
import random
import tkinter

NUM_IMAGES = 100
MAX_NUM_SHAPES = 20
TASKPATH = './eyespy/Data/Tasks/Shapes/'
GROUND_TRUTH = 'ground_truths'
META_DATA = 'meta_data.txt'
# SHAPES = ['line', 'rectangle', 'circle', 'ellipse', 'polygon']
SHAPES = ['line', 'rectangle', 'circle', 'ellipse']
COLORS = ['red', 'blue', 'green']
COLORMAP = {'red': (0, 0, 255), 'green': (0, 255, 0), 'blue': (255, 0, 0)} # BGR

def main(opt):
    metadata = {}
    if not os.path.exists(opt.task_path):
        os.makedirs(opt.task_path)
    for idx in range(opt.num_images):
        print('Creating image number: {}'.format(idx + 1))
        image_name = str(idx + 1) + '.png'
        height, width = get_screen_resolution()
        image, shapes = random_image(height, width, opt.max_num_shapes)
        # if np.random.uniform(0, 1) > 0.5:
        #     image = np.rot90(image, 2, (0, 1))
        metadata[idx + 1] = shapes
        # cv2.namedWindow("Image", cv2.WND_PROP_FULLSCREEN)
        # cv2.setWindowProperty("Image",cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
        # cv2.imshow('Image', image)
        # cv2.waitKey(0)
        # print(os.path.join(opt.task_path, image_name))
        cv2.imwrite(os.path.join(opt.task_path, image_name), image)
    with open(os.path.join(opt.task_path, META_DATA), 'w') as f:
        json.dump(metadata, f)

def get_screen_resolution():
    root = tkinter.Tk()
    width = root.winfo_screenwidth()
    height = root.winfo_screenheight()
    return height, width

def random_image(height, width, max_num_shapes):
    image = np.ones((height, width, 3), np.uint8)
    num_shapes = random.randint(1, max_num_shapes)
    shapes = {}
    for idx in range(num_shapes):
        shape = random.choice(SHAPES)
        # TODO: document width and height vs. x and y
        # image, shape_info = draw_shape(image, shape, height, width)
        image, shape_info = draw_shape(image, shape, width, height)
        shapes[idx] = shape_info
    shapes['num_shapes'] = num_shapes
    return image, shapes

def draw_shape(image, shape, height, width):
    """
    Draws shapes on to the image.
    Args:
        image:  (npy): Image to which shapes are to be added
        shape:  (str): Name of shape to be drawn
        height  (int): y-dimension of the image
        width   (int): x-dimension of the image
    Returns:
        image:  (npy): Image to which shapes have been added
    """
    color = random.choice(COLORS)
    if shape == 'line':
        start = (random.randint(0, height - 1), random.randint(0, width - 1))
        end = (random.randint(0, height - 1), random.randint(0, width - 1))
        image = cv2.line(image, start, end, COLORMAP[color], 4)
    elif shape == 'rectangle':
        leftTop = (random.randint(2, height - 2), random.randint(2, width - 2))
        rightBot = (random.randint(leftTop[0], min(height - 1, leftTop[0] + height//4)),
                    random.randint(leftTop[1], min(width - 1, leftTop[1] + width//4)))
        image = cv2.rectangle(image, leftTop, rightBot, COLORMAP[color], -1)
    elif shape == 'circle':
        radius = random.randint(2, int(min(height, width)//8))
        centre = (random.randint(radius, height - radius - 1), random.randint(radius, width - radius - 1))
        image = cv2.circle(image, centre, radius, COLORMAP[color], -1)
    elif shape == 'ellipse':
        minorAxis = random.randint(2, int(min(height, width)//12))
        majorAxis = random.randint(minorAxis, 2*minorAxis)
        axes = (minorAxis, majorAxis)
        centre = (random.randint(majorAxis, height - majorAxis - 1), random.randint(majorAxis, width - majorAxis - 1))
        image = cv2.ellipse(image, centre, axes, np.random.uniform(0, 360), 0.0, 360.0, COLORMAP[color], -1);
    elif shape == 'polygon':
        num_pts = random.randint(3, 6)
        pts = np.array([[random.randint(0, height - 1), random.randint(0, width -1)] for _ in range(num_pts)],
                np.int32)
        pts = pts.reshape((-1,1,2))
        image = cv2.polylines(image, [pts], True, COLORMAP[color])
    shape_info = {'shape': shape, 'color': color}
    return image, shape_info

def crop_resize(image, size: int=224):
    """
    Centre crops and resizes an image.
    Args:
        image           (npy): Image to be cropped and resized
        size            (int): Image to be resized to [size, size, 3]
    Returns:
        image_resized   (npy): Image resized to (size, size, channels)
    """
    H, W, C = image.shape
    assert min(H, W) >= size, 'Video/image resolution %ix%itoo low, size should be atleast %ix%i' % (H, W, size, size)
    if H > W:
        image_crop = image[H//2 - W//2 - 1:H//2 + W//2 - 2, ...]
    elif H < W:
        image_crop = image[:, W//2 - H//2 - 1:W//2 + H//2 - 2, ...]
    else:
        image_crop = image
    D, _, _ = image_crop.shape
    image_resized = cv2.resize(image_crop, (size, size), interpolation = cv2.INTER_AREA)
    return image_resized

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--task_path', type=str, default=TASKPATH, help='Path to output folder to save images(optional)')
    parser.add_argument('--num_images', default=NUM_IMAGES, type=int, help='Number of task images to be created')
    parser.add_argument('--max_num_shapes', default=MAX_NUM_SHAPES, type=int, help='Maximum number of shapes per image')
    args = parser.parse_args()
    # print(args)
    main(args)


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import numpy as np
import time
import sys
import paddle
import paddle.fluid as fluid
import reader as reader
import argparse
import functools
import models
from utils.learning_rate import cosine_decay
from utils.utility import add_arguments, print_arguments
import math

parser = argparse.ArgumentParser(description=__doc__)
add_arg = functools.partial(add_arguments, argparser=parser)
# yapf: disable
add_arg('batch_size',       int,  256,                 "Minibatch size.")
add_arg('use_gpu',          bool, True,                "Whether to use GPU or not.")
add_arg('class_dim',        int,  1000,                "Class number.")
add_arg('image_shape',      str,  "3,224,224",         "Input image size")
add_arg('with_mem_opt',     bool, True,                "Whether to use memory optimization or not.")
add_arg('pretrained_model', str,  None,                "Whether to use pretrained model.")
add_arg('model',            str,  "SE_ResNeXt50_32x4d", "Set the network to use.")

# yapf: enable

def eval(args):
    # parameters from arguments
    class_dim = args.class_dim
    model_name = args.model
    pretrained_model = args.pretrained_model
    with_memory_optimization = args.with_mem_opt
    image_shape = [int(m) for m in args.image_shape.split(",")]

    model_list = [m for m in dir(models) if "__" not in m]
    assert model_name in model_list, "{} is not in lists: {}".format(args.model,
                                                                     model_list)

    image = fluid.layers.data(name='image', shape=image_shape, dtype='float32')
    label = fluid.layers.data(name='label', shape=[1], dtype='int64')

    # model definition
    model = models.__dict__[model_name]()

    if model_name == "GoogleNet":
        out0, out1, out2 = model.net(input=image, class_dim=class_dim)
        cost0 = fluid.layers.cross_entropy(input=out0, label=label)
        cost1 = fluid.layers.cross_entropy(input=out1, label=label)
        cost2 = fluid.layers.cross_entropy(input=out2, label=label)
        avg_cost0 = fluid.layers.mean(x=cost0)
        avg_cost1 = fluid.layers.mean(x=cost1)
        avg_cost2 = fluid.layers.mean(x=cost2)

        avg_cost = avg_cost0 + 0.3 * avg_cost1 + 0.3 * avg_cost2
        acc_top1 = fluid.layers.accuracy(input=out0, label=label, k=1)
        acc_top5 = fluid.layers.accuracy(input=out0, label=label, k=5)
    else:
        out = model.net(input=image, class_dim=class_dim)
        cost, pred = fluid.layers.softmax_with_cross_entropy(
            out, label, return_softmax=True)
        avg_cost = fluid.layers.mean(x=cost)
        acc_top1 = fluid.layers.accuracy(input=pred, label=label, k=1)
        acc_top5 = fluid.layers.accuracy(input=pred, label=label, k=5)

    test_program = fluid.default_main_program().clone(for_test=True)

    fetch_list = [avg_cost.name, acc_top1.name, acc_top5.name]
    if with_memory_optimization:
        fluid.memory_optimize(
            fluid.default_main_program(), skip_opt_set=set(fetch_list))

    place = fluid.CUDAPlace(0) if args.use_gpu else fluid.CPUPlace()
    exe = fluid.Executor(place)
    exe.run(fluid.default_startup_program())

    if pretrained_model:

        def if_exist(var):
            return os.path.exists(os.path.join(pretrained_model, var.name))

        fluid.io.load_vars(exe, pretrained_model, predicate=if_exist)

    val_reader = paddle.batch(reader.val(), batch_size=args.batch_size)
    feeder = fluid.DataFeeder(place=place, feed_list=[image, label])

    test_info = [[], [], []]
    cnt = 0
    for batch_id, data in enumerate(val_reader()):
        t1 = time.time()
        loss, acc1, acc5 = exe.run(test_program,
                                   fetch_list=fetch_list,
                                   feed=feeder.feed(data))
        t2 = time.time()
        period = t2 - t1
        loss = np.mean(loss)
        acc1 = np.mean(acc1)
        acc5 = np.mean(acc5)
        test_info[0].append(loss * len(data))
        test_info[1].append(acc1 * len(data))
        test_info[2].append(acc5 * len(data))
        cnt += len(data)
        if batch_id % 10 == 0:
            print("Testbatch {0},loss {1}, "
                  "acc1 {2},acc5 {3},time {4}".format(batch_id, \
                  "%.5f"%loss,"%.5f"%acc1, "%.5f"%acc5, \
                  "%2.2f sec" % period))
            sys.stdout.flush()

    test_loss = np.sum(test_info[0]) / cnt
    test_acc1 = np.sum(test_info[1]) / cnt
    test_acc5 = np.sum(test_info[2]) / cnt

    print("Test_loss {0}, test_acc1 {1}, test_acc5 {2}".format(
        "%.5f"%test_loss, "%.5f"%test_acc1, "%.5f"%test_acc5))
    sys.stdout.flush()

def main():
    args = parser.parse_args()
    print_arguments(args)
    eval(args)

if __name__ == '__main__':
    main()


from collections import defaultdict

with open("day24.txt") as input_file:
    lines = input_file.readlines()

directions = {
    "e": -2 + 0j,
    "w": +2 + 0j,
    "sr": -1 - 1j,
    "nr": -1 + 1j,
    "sl": +1 - 1j,
    "nl": +1 + 1j,
}

replacements = {"se": "sr", "ne": "nr", "sw": "sl", "nw": "nl"}

def displacement(line: str) -> complex:
    for old, new in replacements.items():
        line = line.replace(old, new)
    return sum(d * line.count(k) for k, d in directions.items())

tiles = defaultdict(bool)
for line in lines:
    tiles[displacement(line)] = not tiles[displacement(line)]

print(sum(tiles.values()))

def expand(grid: defaultdict) -> None:
    for p, tile in list(grid.items()):
        if not tile:
            continue
        for d in directions.values():
            if p + d not in grid:
                grid[p + d] = False

def step(old_grid: defaultdict) -> defaultdict:
    new_grid = old_grid.copy()
    expand(new_grid)
    for p, tile in new_grid.items():
        neigh = sum(old_grid[p + d] for d in directions.values())
        if tile and (neigh == 0 or neigh > 2):
            new_grid[p] = False
        elif (not tile) and (neigh == 2):
            new_grid[p] = True
    return new_grid

for _ in range(100):
    tiles = step(tiles)

print(sum(tiles.values()))


from args import parse_config
from main import get_trainer
from utils import *
from sklearn.model_selection import KFold
import os

def cross_validation(**args):
    df_all = pd.read_csv(args.get('train_csv_path'))
    # Extract user, movie, rating vectors from the dataframe.
    users, movies, ratings = extract_user_movie_rating_arrays(df_all)
    cv_folder = args.get('cv_folder')
    base_model_name = args.get('model_name')
    if not os.path.exists(cv_folder):
        os.makedirs(cv_folder)

    kf = KFold(n_splits=args.get('k_fold'), shuffle=True, random_state=args.get('random_seed'))

    args['pred_folder'] = cv_folder
    args['ckpt_folder'] = cv_folder
    for idx, (train_index, test_index) in enumerate(kf.split(df_all)):
        users_train = users[train_index]
        movies_train = movies[train_index]
        ratings_train = ratings[train_index]

        users_test = users[test_index]
        movies_test = movies[test_index]
        ratings_test = ratings[test_index]

        print('Fold {}: Number of training sumples: {}, number of test samples: {}.'.format(idx+1, len(users_train), len(users_test)))

        args['model_name'] = base_model_name + '_fold_' + str(idx+1)
        trainer = get_trainer(**args)
        trainer.train(users_train, movies_train, ratings_train, users_test, movies_test, ratings_test, **args)

if __name__ == '__main__':
    args = parse_config()
    cross_validation(**args)


import profile
from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.views import View
from newsfeed.models import Post, Comment
from .models import UserProfile
from multiprocessing import context
from django.views.generic.edit import UpdateView, DeleteView
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin

# Create your views here.

class ProfileView(View):
    def get(self, request, pk, *args, **kwargs):
        profile = UserProfile.objects.get(pk=pk)
        user = profile.user
        posts = Post.objects.filter(author=user).order_by('-created_on')

        followers = profile.followers.all()

        if len(followers) == 0:
            is_following = False

        for follower in followers:
            if follower == request.user:
                is_following = True
                break
            else:
                is_following = False

        num_of_followers = len(followers)

        context = {
            'user': user,
            'profile': profile,
            'posts': posts,
            'num_of_followers': num_of_followers,
            'is_following': is_following,
        }

        return render(request, 'profile/profile.html', context)

class ProfileEditView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = UserProfile
    fields = ['name', 'bio', 'birth_date', 'location', 'picture']
    template_name = 'profile/profile_edit.html'

    def get_success_url(self):
        pk = self.kwargs['pk']
        return reverse_lazy('profile', kwargs={'pk': pk})

    def test_func(self):
        profile = self.get_object()
        return self.request.user == profile.user

class AddFollower(LoginRequiredMixin, View):
    def post(self, request, pk, *args, **kwargs):
        profile = UserProfile.objects.get(pk=pk)
        profile.followers.add(request.user)

        return redirect('profile', pk=profile.pk)

class RemoveFollower(LoginRequiredMixin, View):
    def post(self, request, pk, *args, **kwargs):
        profile = UserProfile.objects.get(pk=pk)
        profile.followers.remove(request.user)

        return redirect('profile', pk=profile.pk)

class ListFollowers(View):
    def get(self, request, pk, *args, **kwargs):
        profile = UserProfile.objects.get(pk=pk)
        followers = profile.followers.all()

        context = {
            'profile': profile,
            'followers': followers,
        }

        return render(request, 'profile/followers_list.html', context)


"""
PyTorch implementation of NVDM paper:
Neural Variational Inference for Text Processing. Miao et al. ICML 2016.

https://arxiv.org/pdf/1511.06038.pdf
"""
import torch
import torch.nn as nn

def kl_div(mu, log_sigma):
    """ KL divergence as defined in the paper, given the mu and log(sigma)
    parameters of the Gaussian variational distribution. """
    # In the paper they have an undefined "K" variable, but is set to one
    # in the author's code.
    K = 1
    # logdet(diag(s^2)) = log(prod_i s_i^2) = sum_i log s_i^2 = 2 sum_i log s_i
    return -0.5 * torch.sum(K - mu.pow(2) + 2 * log_sigma - torch.exp(2 * log_sigma), dim=1)

class NVDM(nn.Module):
    """ Neural Variational Document Model -- BOW VAE. """
    def __init__(self, vocab_size, n_hidden, n_topic, n_sample, device, learn_embeddings=False):
        super().__init__()
        self.vocab_size = vocab_size
        self.n_hidden = n_hidden
        self.n_topic = n_topic

        # Not used for now, just 1 sample on each call to self.decode()
        self.n_sample = n_sample

        # Inference network
        # See paper appendix B for details

        # Embedded Bag-of-Words
        # This converts variable-length sentences into BOW representations
        # Disable learning word embeddings for now.
        self.embed_bow = nn.EmbeddingBag(vocab_size, vocab_size, mode="sum")

        if not learn_embeddings:
            # Convert "embeddings" into non-trainable identity matrix
            # (i.e. word embeddings are always one-hot)
            # So this effectively becomes a CountVectorizer.
            self.embed_bow.requires_grad_(False)
            assert not self.embed_bow.weight.requires_grad
            assert self.embed_bow.weight.size() == (vocab_size, vocab_size)

            self.embed_bow.weight.zero_()
            self.embed_bow.weight.fill_diagonal_(1.0)

        # Encoder: takes the bag-of-words representation of a document
        # and generates an intermediate/hidden representation.
        # Original paper uses ReLU, but that results in values being too large
        # (many NaNs)
        self.encoder = nn.Sequential(
            nn.Linear(vocab_size, n_hidden),
            nn.Tanh(),
            nn.Linear(n_hidden, n_hidden),
            nn.Tanh()
        )

        # Transform the hidden representation to get the
        # Gaussian mu and log-standard deviation variational parameters.
        self.mu = nn.Linear(n_hidden, n_topic)
        self.log_sigma = nn.Linear(n_hidden, n_topic)
        # Author's code initializes weights and biases of log sigma to 0
        # torch.nn.init.zeros_(self.log_sigma.bias)
        # torch.nn.init.zeros_(self.log_sigma.weight)
        # h ~ N(mu, sigma^2)

        # Generative model
        # This linearly transforms the hidden representation
        # before computing softmax probabilities over vocabulary
        # This becomes the "learned embedding"
        self.decoder = nn.Sequential(
            nn.Linear(n_topic, vocab_size)
        )

        # Torch device (GPU/CPU)
        self.device = device

    def encode(self, text, offsets=None):
        """ If offsets is none, the we assume text is already a BoW representation. """
        # Convert text into BoW representation if required.
        if offsets is not None:
            X_bow = self.embed_bow(text, offsets)
        else:
            X_bow = text

        # Compute Gaussian parameters
        pi = self.encoder(X_bow)
        mu = self.mu(pi)
        log_sigma = self.log_sigma(pi)
        return X_bow, mu, log_sigma

    def decode(self, X_bow, mu, log_sigma):
        # Take samples from transformed standard Normal
        batch_size = X_bow.size(0)

        # Only 1 sample
        eps = torch.randn((batch_size, self.n_topic), device=self.device)
        doc_vec = torch.exp(log_sigma) * eps + mu

        # Logit probabilities over vocabulary
        logits = torch.log_softmax(self.decoder(doc_vec), dim=1)
        return logits

    def forward(self, text, offsets=None, kl_weight=1.0, n_sample=None):
        """ Here we compute both the logits and total loss. """

        if n_sample is None:
            n_sample = self.n_sample

        # Encoding step
        X_bow, mu, log_sigma = self.encode(text, offsets)

        # Reconstruction loss: estimate by sampling.
        loss_rec = 0.0
        for _ in range(n_sample):
            # decode() randomly samples from the Gaussian.
            logits = self.decode(X_bow, mu, log_sigma)

            # Log likelihood. Each logit p(x_i) is weighted by its
            # frequency in the document (retrieved from BoW)
            loss_rec_sample = (X_bow * logits).sum(dim=1)
            loss_rec += loss_rec_sample

        # Negate (important!) and sample mean (i.e. negative log likelihood)
        loss_rec = -loss_rec / n_sample

        # KL divergence loss
        # Computed once only unlike reconstruction loss.
        loss_kl = kl_div(mu, log_sigma)

        # Total loss = L_rec + L_kl
        # During training, we might want to weight the KL more as a form of
        # regularization, so multiply it by kl_weight.
        # But for the variational lower bound/estimating perplexity etc.,
        # kl_weight must be 1.
        loss_total = loss_rec + kl_weight * loss_kl
        return {"rec": loss_rec, "kl": loss_kl, "total": loss_total}