n = int(input())

trilhas = []
for e in range(n):
  trilha = list(map(int, input().split()))
  trilhas.append(trilha)

alturas = []
for trilha in trilhas:
  altura = 0
  alturaIda = 0
  alturaVolta = 0

  for num in range(1, len(trilha) - 1):
    valor = trilha[num]
    proximoValor = trilha[num + 1]
    if (valor < proximoValor):
      alturaIda += proximoValor - valor
    elif (valor > proximoValor):
      alturaVolta += valor - proximoValor

  if (alturaIda <= alturaVolta):
    altura = alturaIda
  elif (alturaIda > alturaVolta):
    altura = alturaVolta
  alturas.append(altura)

menor = 1001
indice = 0
for altura in range(len(alturas)):
  if (alturas[altura] < menor):
    menor = alturas[altura]
    indice = altura + 1

print(indice)


import time
import timeit
import Queue
import requests
#from flow_entry_mapper import *
from collections import defaultdict
from flow_entry_mapping import *
from user_site import *

U_table = [[0 for x in range(5)] for x in range(100000)] #uid/scid/gid/bw/L
loc=[[0 for x in range(5)] for x in range(100000)]

edge_num = 3
edge_set = []
site_set = []
max_entry_num = 16000
flows = []

def Management1(user):
	c_entry = 0
	edge_id = int(user[3])
	SC = user[4]
	pSC = split_SC(SC)
	if pSC[0] == '*':
		return Management2(SC)
	else:
		if avg_server_num[len(pSC[0])] <= edge_set[edge_id-1]:
			edge_set[edge_id-1] -= avg_server_num[len(pSC[0])]
			return Management2(pSC[1])
		else:
			return Management2(SC)

def Management2(SC):
	if SC == '*':
		return 4
	return avg_entry_num[len(SC)]

def over_flow():
	for f in flows:
		ip = f[0]
		edge_id = f[3]
		if site_set[edge_id].user_exist(ip, edge_id) and site_set[0].user_exist(ip, edge_id):
			site_set[edge_id].update(ip)
			site_set[0].update(ip)
		else:
			SC = f[4]
			pSC = split_SC(SC)
			if pSC[0] == '*':
				core_manager(ip, edge_id, SC)
				site_set[edge_id].add_user(ip, edge_id, SC)
			else:
				site_set[edge_id].add_user(ip, edge_id, pSC[0])
				core_manager(ip, edge_id, pSC[1])

def core_manager(ip, edge_id, SC):
	of = site_set[0].add_user(ip, edge_id, SC)
	for d in of:
		site_set[d[1]].delete(d[0])

def Serve(user_num):
	c_entry = 0
	for i in range(user_num):
		c_entry += Management1(U_table[i])
	return c_entry

if __name__ == '__main__':

	"""
	U_table_init(100000)

	for i in range(10000,110000,10000):
		site_set = []
		site_set.append(Site_manager(0, max_entry_num))
		for j in range(edge_num):
			site_set.append(Site_manager(j+1, max_entry_num))
		flows = gen_flows(i,100000)
		over_flow()
		print site_set[0].entry_num, site_set[0].of_num
	"""

	"""

	for i in range(edge_num):
		edge_set.append(edge_res)

	while(1):
		edge_id = raw_input(">>> id:")
		print Management1(['1','1','1',str(edge_id),'AB'])

	"""


import tkinter as tk
from tkinter import ttk
from random import randint

class TicTacToe(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.master = master
        self.master.title('TicTacToe Start Screen')

        self._player_sym = ttk.Combobox(self.master, values=('X','O'), state='readonly', width=2)
        self._player_type = ttk.Combobox(self.master, values=('System','Friend'), state='readonly', width=10)
        self._first_move = ttk.Combobox(self.master, values=('Player 1','Player 2'), state='readonly', width=10)

        self._init_widgets()

    def _init_widgets(self):
        ttk.Label(self.master,text='Select your symbol:',pad=5).grid(row=0,column=0,sticky='w')
        ttk.Label(self.master,text='Select your opponent type:',pad=5).grid(row=1,column=0,sticky='w')
        ttk.Label(self.master,text='Select who will get the first move:',pad=5).grid(row=2,column=0,sticky='w')

        self._player_sym.grid(row=0,column=1,sticky='w')
        self._player_sym.current(0)
        self._player_type.grid(row=1,column=1,sticky='w')
        self._player_type.current(0)
        self._first_move.grid(row=2,column=1,sticky='w')
        self._first_move.current(0)

        ttk.Button(self.master,text='start',command=self._start_action).grid(row=3,column=1,columnspan=2,pady=5,sticky='ew')
        ttk.Button(self.master,text='exit',command=self.master.destroy).grid(row=4,column=1,columnspan=2,pady=5,sticky='ew')

    def _start_action(self):
        self.master.withdraw()
        TicTacToeBoard(self.master, self._player_sym.get(), self._player_type.get(), self._first_move.get())

class TicTacToeBoard(tk.Toplevel):
    def __init__(self, master, player_sym='X', player_type='System', first_move='Player 1'):
        tk.Toplevel.__init__(self)
        self._master = master
        self._player1_sym = player_sym
        self._player2_sym = 'O' if self._player1_sym == 'X' else 'X'
        self._player_type = player_type
        self._first_move = first_move
        self._sym_fields = [[ttk.Combobox(self,values=(self._player1_sym,self._player2_sym),state='readonly') for _ in range(3)] for _ in range(3)]

        self._init_widgets()

    def _init_widgets(self):
        ttk.Label(self,text='After making your move hit the "confirm" button to proceed.',justify='left').grid(row=0,column=0,pady=2)
        self._init_board()
        self._init_controls()
        self.title('TicTacToe')

    def _init_board(self):
        for i in range(3):
            for j in range(3):
                self._sym_fields[i][j].grid(row=i+1,column=j+1,padx=2,pady=2,sticky='ew')

    def _init_controls(self):
        ttk.Button(self,text='confirm',command=self._player_move).grid(row=4,column=1,pady=2,sticky='ew')
        ttk.Button(self,text='back',command=self._back_action).grid(row=4,column=2,pady=2,sticky='ew')
        ttk.Button(self,text='exit',command=self._exit_action).grid(row=4,column=3,pady=2,sticky='ew')

    def _back_action(self):
        self.destroy()
        self._master.update()
        self._master.deiconify()

    def _exit_action(self):
        self.destroy()
        self._master.destroy()

    def _player_move(self):
        self._game_ai()
        player1_win = self._has_winner(self._player1_sym)
        player2_win = self._has_winner(self._player2_sym)

        if player1_win:
            self._disp_winner('Player 1')
        elif player2_win:
            self._disp_winner('Player 2')

    def _game_ai(self):
        while True:
            randx = randint(0,2)
            randy = randint(0,2)
            rand_cb = self._sym_fields[randx][randy]
            if rand_cb.get() == '':
                rand_cb.set(self._player2_sym)
                break

    def _disp_winner(self, player_sym):
        ttk.Label(self,text='Player '+player_sym+' has won!').grid(row=7,column=0)

    def _has_winner(self, player_sym):
        results = []

        for i in range(3):
            result = all(sym.get() == player_sym for sym in self._sym_fields[i][:])
            results.append(result)

        for i in range(3):
            result = all(sym.get() == player_sym for sym in self._sym_fields[:][i])
            results.append(result)

        diag1 = [self._sym_fields[i][i] for i in range(3)]
        diag2 = [self._sym_fields[-1-i][i] for i in range(3)]
        results.append(all(sym.get() == player_sym for sym in diag1))
        results.append(all(sym.get() == player_sym for sym in diag2))

        print(True in results)
        return (True in results)

root = tk.Tk()
app = TicTacToe(root)
root.mainloop()


# -*- coding: utf-8 -*-
"""
Created on Fri May 11 10:14:13 2018

@author: George
"""

import numpy as np
import numpy.random as npr
import matplotlib.pyplot as plt
from scipy.optimize import leastsq

#raw data
x = [3454, 3433, 3559, 3903, 3970, 4282, 4649, 4901]
y = [12546611, 9481327, 7132256, 3900473, 3287550, 2418038, 2235571, 2105149]

def logistic4(x, A, B, C, D):
    """4PL lgoistic equation."""
    return ((A-D)/(1.0+((x/C)**B))) + D

def residuals(p, y, x):
    """Deviations of data from fitted 4PL curve"""
    A,B,C,D = p
    err = y-logistic4(x, A, B, C, D)
    return err

def peval(x, p):
    """Evaluated value at x with current parameters."""
    A,B,C,D = p
    return logistic4(x, A, B, C, D)

# Initial guess for parameters [min, slope, inflection, max]
p0 = [0.1, 1, 0.2, 1.2]

# Fit equation using least squares optimization
plsq = leastsq(residuals, p0, args=(y, x))

# Plot results
plt.plot(x,peval(x,plsq[0]),x,y,'o',x,y)
plt.title('Least-squares 4PL fit to noisy data')

plt.plot(x,y, '+')


# -*- coding: utf-8 -*-
import gi
gi.require_version('Gedit', '3.0')
from gi.repository import GObject, Gio, Gdk, Gedit
import re
try:
    import gettext
    gettext.bindtextdomain('gedit-plugins')
    gettext.textdomain('gedit-plugins')
    _ = gettext.gettext
except:
    _ = lambda s: s

#Code based on https://github.com/theawless/Clear-Doc
class IndentConverterPluginAppActivatable(GObject.Object, Gedit.AppActivatable):
    app = GObject.property(type=Gedit.App)
    __gtype_name__ = "IndentConverterPluginAppActivatable"

    def __init__(self):
        GObject.Object.__init__(self)
        self.menu_ext = None
        self.menu_item = None

    def do_activate(self):
        self._build_menu()

    def _build_menu(self):
        # Get the extension from tools menu
        self.menu_ext = self.extend_menu("tools-section")

        # This is the submenu which is added to a menu item and then inserted in tools menu.
        sub_menu = Gio.Menu()
        sub_menu_item_spaces = Gio.MenuItem.new(_("_Spaces to tabs"), 'win.spaces_to_tabs')
        sub_menu.append_item(sub_menu_item_spaces)
        sub_menu_item_tabs = Gio.MenuItem.new(_("_Tabs to Spaces"), 'win.tabs_to_spaces')
        sub_menu.append_item(sub_menu_item_tabs)
        self.menu_item = Gio.MenuItem.new_submenu(_("_Indent Converter"), sub_menu)
        self.menu_ext.append_menu_item(self.menu_item)

        # Setting accelerators, first action is called when Ctrl+Alt+e is pressed. (PS: for some reason, using S and T do not work)
        self.app.set_accels_for_action("win.spaces_to_tabs", ("<Primary><Alt>E", None))
        self.app.set_accels_for_action("win.tabs_to_spaces", ("<Primary><Alt>A", None))

    def do_deactivate(self):
        self._remove_menu()

    def _remove_menu(self):
        # removing accelerators and destroying menu items
        self.app.set_accels_for_action("win.spaces_to_tabs", ())
        self.app.set_accels_for_action("win.tabs_to_spaces", ())
        self.menu_ext = None
        self.menu_item = None

class IndentConverterPluginWindowActivatable(GObject.Object, Gedit.WindowActivatable):

    __gtype_name__ = "IndentConverterPluginWindowActivatable"

    window = GObject.property(type=Gedit.Window)

    def __init__(self):
        GObject.Object.__init__(self)

    def do_activate(self):
        self._connect_menu()

    def do_deactivate(self):
        pass

    def do_update_state(self):
        view = self.window.get_active_view()

        #Enable if view exists and document is editable
        enabled = False
        enabled = view and view.get_editable()
        self.window.lookup_action('spaces_to_tabs').set_enabled(enabled)
        self.window.lookup_action('tabs_to_spaces').set_enabled(enabled)

    def _connect_menu(self):
        action_spaces = Gio.SimpleAction(name='spaces_to_tabs')
        action_spaces.connect('activate', self.do_spaces_to_tabs)
        self.window.add_action(action_spaces)
        action_tabs = Gio.SimpleAction(name='tabs_to_spaces')
        action_tabs.connect('activate', self.do_tabs_to_spaces)
        self.window.add_action(action_tabs)

    def remove_menu(self):
        pass

    def tab_size(self):
        settings = Gio.Settings.new('org.gnome.gedit.preferences.editor')
        tab_size = settings.get_uint('tabs-size')
        return tab_size

    def guess_tab_size(self, text):
        def gcd(a, b):
            return a if b == 0 else gcd(b, a % b);

        r = re.compile('^ +', re.MULTILINE)
        matches = r.findall(text)
        freq = {}

        # `key` - length of leading spaces, `value` - it's frequency
        for spaces in matches:
            spaces = len(spaces)
            if spaces in freq:
                freq[spaces] += 1
            else:
                freq[spaces] = 1

        # sort frequencies by value:
        items = [ [i[1], i[0]] for i in list(freq.items()) ]
        items.sort()
        items.reverse()
        items = [i[1] for i in items]

        if len(items) == 0:
            return 0
        elif len(items) == 1:
            return items[0]
        else:
            return gcd(items[0], items[1])

    def do_spaces_to_tabs(self, action, data):

        #TODO Code using view works?
        #view = self.window.get_active_view()
        #doc = view.get_buffer()

        #Return if document is empty
        doc = self.window.get_active_document()
        if doc is None:
            return

        #TODO Use selection if any, otherwise the whole document
        #try:
        #    start, end = doc.get_selection_bounds()
        #except ValueError:

        start, end = doc.get_bounds()
        text = doc.get_text(start, end, True)

        tab_size = self.guess_tab_size(text)
        if (tab_size < 2):
            tab_size = self.tab_size()
        r = re.compile('^(?:' +  (' ' * tab_size) + ')+', re.MULTILINE)

        def replacer(match):
            return '\t' * int(len(match.group(0)) / tab_size)

        text = r.sub(replacer, text)

        doc.begin_user_action()
        doc.set_text(text)
        doc.end_user_action()

    def do_tabs_to_spaces(self, action, data):
        doc = self.window.get_active_document()
        if doc is None:
            return

        start, end = doc.get_bounds()
        text = doc.get_text(start, end, True)
        text = text.expandtabs(self.tab_size())

        doc.begin_user_action()
        doc.set_text(text)
        doc.end_user_action()


from django.conf.urls import url

from services.user_management.views import student_list, parent_list, student_registration, staff_registration
from .auth_token_manager import CustomAuthToken

urlpatterns = [
    url(r'^students/$', student_list),
    url(r'^parents/$', parent_list),
    url(r'^register/student$', student_registration),
    url(r'^register/staff$', staff_registration),
    url(r'^auth/$', CustomAuthToken.as_view())
]


# coding=utf-8
from string import ascii_uppercase, digits
from tempfile import gettempdir

__author__ = 'etcher3rd'
import sys
from main import __version__
from random import choice, randint
# noinspection PyProtectedMember
from os import listdir, _exit, mkdir, startfile, environ
from os.path import join, dirname, abspath, exists
from json import dumps, loads
from PyQt5.QtCore import pyqtSlot, QObject, QTimer
from PyQt5.QtGui import QIcon, QKeySequence
from PyQt5.QtWidgets import QMainWindow, QApplication, QShortcut, QMessageBox, QPushButton, QDialog
from ui import ui_main as qt_main_ui, ui_update as qt_update_ui
from custom_logging import mkLogger, logged
from csv import excel, writer, reader, QUOTE_ALL
from pickle import load, dump
from requests import get as requests_get, head as requests_head
from urllib import request
from zipfile import ZipFile, BadZipfile, ZIP_LZMA
from shutil import rmtree, copy

cert = './cacert.pem'
environ['REQUESTS_CA_BUNDLE'] = cert

class Config():
    """
    Set it all up

    This holds everything that is accessible to the user, plus some more. It also writes/reads to the config file,
    so nothing's lost between runs.
    """
    defaults = {
        'qty': 7,
        'difficulty': 0,
        'csv': 0,
    }

    def __init__(self):
        self.__dict__['config'] = {}
        self.__dict__['path'] = None
        if hasattr(sys, 'frozen'):
            self.path = join(dirname(abspath(sys.executable)), 'epps.config')
        else:
            self.path = join(dirname(abspath(__file__)), 'epps.config')
        self.read()

    def read(self):
        if exists(self.path):
            with open(self.path) as f:
                self.__dict__['config'] = loads(f.read())

    def write(self):
        with open(self.path, mode='w') as f:
            f.write(dumps(self.__dict__['config'], indent=True, sort_keys=True))

    def __getattr__(self, key):
        for d in [self.__dict__, self.__dict__['config'], self.defaults]:
            try:
                return d[key]
            except KeyError:
                pass
        return ''

    def __setattr__(self, key, value):
        if key in self.__dict__.keys():
            self.__dict__[key] = value
        else:
            self.__dict__['config'][key] = value
            self.write()

    def __getitem__(self, key):
        return getattr(self, key)

    def __setitem__(self, key, value):
        self.__setattr__(key, value)

class DataSet():
    def __init__(self, init_list=None):
        if init_list:
            self.l = list(init_list)
        else:
            self.l = []

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

    # __iter__ is not strictly required, it's only needed to implement
    # efficient iteration.
    def __iter__(self):
        return self.l.__iter__()

    # __contains__ isn't strictly required either, it's only needed to
    # implement the `in` operator efficiently.
    def __contains__(self, item):
        return self.l.__contains__(item)

    def __getitem__(self, item):
        return self.l.__getitem__(item)

    # Mutable sequences only, provide the Python list methods.
    def append(self, item):
        self.l.append(item)

    def count(self, item):
        return self.l.count(item)

    def index(self, item):
        return self.l.index(item)

    def extend(self, other):
        return self.l.extend(other)

    def insert(self, index, item):
        return self.l.insert(index, item)

    def pop(self):
        return self.l.pop()

    def remove(self, item):
        return self.l.remove(item)

    def reverse(self):
        return self.l.reverse()

    def __eq__(self, other):
        return self.l == other.l

    def __str__(self):
        return self.l.__str__()

    def sort(self):
        self.l.sort()
        return self

class CSV(DataSet):
    csv_dialect = excel
    csv_dialect.lineterminator = '\n'
    csv_dialect.delimiter = ';'
    csv_dialect.quoting = QUOTE_ALL

    def __init__(self, target_file):
        """
        Superseeds data_set.DataSet with methods for reading / writing from / to CSV files

        :param target_file: CSV file to read or write
        """
        DataSet.__init__(self)
        self.target_file = target_file

    # def get_target_file(self):
    # return self.__target_file

    # def set_target_file(self, value):
    # self.__target_file = value
    #
    # def del_target_file(self):
    # del self.__target_file

    def read(self):
        with open(self.target_file) as f:
            data = reader(f, self.csv_dialect)
            for row in data:
                self.l.append(row)
        return self

    def write(self):
        with open(self.target_file, 'w') as csvFile:
            data = writer(csvFile, dialect=self.csv_dialect)
            for row in self.l:
                data.writerow(row)
        return self

        # target_file = property(get_target_file, set_target_file, del_target_file, "CSV file to read or write")

class Stats(object):
    """
    classdocs
    """
    d = {}

    def __init__(self):
        """
        Constructor
        """
        self.file_name = 'epps.stats'

    def read(self):
        if not exists(self.file_name):
            self.d = {'total': {'wrong': 0, 'correct': 0}}
            self.write()
        with open(self.file_name, 'rb') as f:
            # noinspection PyArgumentList
            self.d = load(f)

    def write(self):
        with open(self.file_name, 'wb') as f:
            # noinspection PyArgumentList
            dump(self.d, f)

    def correct(self, question):
        if question in self.d.keys():
            self.d[question]['correct'] += 1
        else:
            self.d[question] = {'correct': 1, 'wrong': 0}
        self.d['total']['correct'] += 1
        self.write()

    def wrong(self, question):
        if question in self.d.keys():
            self.d[question]['wrong'] += 1
        else:
            self.d[question] = {'correct': 0, 'wrong': 1}
        self.d['total']['wrong'] += 1
        self.write()

    def get_wrongs(self, percentile=25):
        qty = len(self.d) * (float(percentile) / 100)
        rtn = []
        for k in sorted([(x, self.d[x]['wrong']) for x in self.d.keys() if x != 'total'], key=lambda y: y[1],
                        reverse=True):
            rtn.append(k[0])
            if len(rtn) >= qty:
                return rtn

    def get_corrects(self, percentile=25):
        qty = len(self.d) * (float(percentile) / 100)
        rtn = []
        for k in sorted([(x, self.d[x]['correct']) for x in self.d.keys() if x != 'total'], key=lambda y: y[1],
                        reverse=True):
            rtn.append(k[0])
            if len(rtn) >= qty:
                return rtn

    def get_total_correct(self):
        return self.d['total']['correct']

    def get_total_wrong(self):
        return self.d['total']['wrong']

    def __str__(self):
        return 'Bon: {}\tMauvais: {}'.format(self.get_total_correct(), self.get_total_wrong())

def humansize(nbytes):
    suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
    if nbytes == 0:
        return '0 B'
    i = 0
    while nbytes >= 1024 and i < len(suffixes) - 1:
        nbytes /= 1024.
        i += 1
    f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
    return '%s %s' % (f, suffixes[i])

class Gui():
    def __init__(self):
        pass

    class UpdateEPPS(QDialog, qt_update_ui.Ui_Dialog):
        class UpdateProgressBar():
            def __init__(self, parent):
                self.progress_bar = parent.progress_bar

            def update_title(self, title):
                pass

            def update(self, i):
                self.progress_bar.setValue(round(int(i)))

        def __init__(self):
            logger.debug("UpdateGui - init")
            QDialog.__init__(self)
            self.setupUi(self)
            self.setWindowTitle('Mise à jour d\'EPPS')
            self.setModal(True)
            self.setWindowIcon(icon)
            self.download_progress_bar = Gui.UpdateEPPS.UpdateProgressBar(self)

    class Main(QMainWindow, QObject, qt_main_ui.Ui_MainWindow):

        logger, csv, qa_pair = None, None, None

        @logged
        def __init__(self):
            QObject.__init__(self)
            self.config = Config()
            self.setupUi(self)
            self.setWindowTitle('EPPS {}'.format(__version__))
            self.ensurePolished()
            self.timer = QTimer()
            self.style_timer = QTimer()
            self.update_gui = Gui.UpdateEPPS()
            # noinspection PyUnresolvedReferences
            self.style_timer.timeout.connect(self.on_style_timer_timeout)
            self.csv_combo.addItems([x[:-4] for x in listdir('.') if x[-4:] == '.csv'])
            # noinspection PyUnresolvedReferences
            self.csv_combo.currentIndexChanged.connect(self.on_csv_combo_index_changed)
            self.buttons = {
                0: self.toolButton_1,
                1: self.toolButton_2,
                2: self.toolButton_3,
                3: self.toolButton_4,
                4: self.toolButton_5,
                6: self.toolButton_6,
                5: self.toolButton_7,
                7: self.toolButton_8,
                8: self.toolButton_9,
                9: self.toolButton_10,
            }
            self.shortcuts = []
            for i in self.buttons.items():
                i[1].setFixedHeight(40)
                i[1].setFixedWidth(700)
                s = QShortcut(QKeySequence(str(i[0])), self)
                # noinspection PyUnresolvedReferences
                s.activated.connect(self.buttons[i[0]].click)
                self.shortcuts.append(s)
            self.stats = Stats()
            self.stats.read()
            self.refresh_stats()
            self.config_values = [
                (self.difficulty_combo, 'difficulty'),
                (self.csv_combo, 'csv'),
                (self.choices_qty_combo, 'qty')
            ]
            for x in self.config_values:
                x[0].setCurrentIndex(self.config[x[1]])
                # noinspection PyUnresolvedReferences
                x[0].currentIndexChanged.connect(lambda iii=x[0], ii=x[1]: self.on_config_value_update(iii, ii))
            # noinspection PyUnresolvedReferences
            self.start_button.clicked.connect(self.start)
            # noinspection PyUnresolvedReferences
            self.timer.timeout.connect(self.on_timer_update)
            self.time_max, self.time_left = None, None
            self.default_style = self.styleSheet()
            self.check_for_new_version()
            self.show()

        @pyqtSlot()
        def on_timer_update(self):
            self.time_left -= 100
            if self.time_left <= 0:
                self.on_wrong_answer()
            else:
                self.progress_bar.setValue(self.time_left / self.time_max * 100)

        @pyqtSlot()
        def on_config_value_update(self, idx, value):
            self.config[value] = idx

        @pyqtSlot()
        def on_csv_combo_index_changed(self):
            self.load_csv()

        def load_csv(self):
            self.logger.debug(self.csv_combo.currentText())
            self.csv = CSV('{}.csv'.format(self.csv_combo.currentText()))
            self.csv.read()

        def start(self):
            self.load_csv()
            self.make_question()

        def make_question(self):
            qi, ai = 0, 1
            if self.inversed:
                qi, ai = 1, 0
            self.qa_pair = tuple(choice(self.csv))
            if self.prio_wrong:
                self.qa_pair = tuple(choice(self.stats.get_wrongs()))
            q, a = self.qa_pair[qi], self.qa_pair[ai]
            self.question_label.setText(q)
            ca = randint(0, self.choices_qty - 1)
            wa = [choice(self.csv)[ai] for _ in range(self.choices_qty)]
            while a in wa:
                wa.remove(a)
                wa.append(choice(self.csv)[ai])
            for k in self.buttons:
                try:
                    # noinspection PyUnresolvedReferences
                    self.buttons[k].clicked.disconnect()
                    self.buttons[k].setText('')
                except TypeError:
                    pass
            for i in range(0, self.choices_qty):
                if i == ca:
                    self.buttons[i].setText('{}: {}'.format(i, a))
                    # noinspection PyUnresolvedReferences
                    self.buttons[i].clicked.connect(self.on_correct_answer)
                else:
                    self.buttons[i].setText('{}: {}'.format(i, wa.pop()))
                    # noinspection PyUnresolvedReferences
                    self.buttons[i].clicked.connect(self.on_wrong_answer)
            if self.difficulty_combo.currentIndex() > 0:
                self.time_max = (10000 + self.choices_qty * 1000) / self.difficulty
                self.time_left = self.time_max
                self.timer.start(100)
            elif self.timer.isActive():
                self.timer.stop()
                self.progress_bar.setValue(0)

        @pyqtSlot()
        def on_style_timer_timeout(self):
            self.setStyleSheet(self.default_style)

        @pyqtSlot()
        def on_wrong_answer(self):
            self.stats.wrong(self.qa_pair)
            self.next_question('red')

        @pyqtSlot()
        def on_correct_answer(self):
            self.stats.correct(self.qa_pair)
            self.next_question('green')

        def next_question(self, color=None):
            if color is not None:
                self.setStyleSheet('background-color: {}'.format(color))
                self.style_timer.start(100)
            self.make_question()
            self.refresh_stats()

        def refresh_stats(self):
            self.stats_label.setText(str(self.stats))

        @property
        def inversed(self):
            return self.inversed_checkbox.isChecked()

        @property
        def prio_wrong(self):
            return self.priowrong_checkbox.isChecked()

        @property
        def choices_qty(self):
            return int(self.choices_qty_combo.currentText())

        @property
        def difficulty(self):
            return self.difficulty_combo.currentIndex()

        def check_for_new_version(self):
            # if not hasattr(sys, 'frozen'):
            #     return
            self.logger.debug("vérification de l'existence d'une nouvelle version d'EPPS")
            r = requests_get('https://api.github.com/repos/etcher3rd/EPPS/releases')
            if not r:
                self.logger.error("erreur lors de la requete HTTP")
                return
            # noinspection PyBroadException
            try:
                for x in r.json():
                    tag = x['tag_name']
                    url = x['assets'][0]['browser_download_url']
                    size = x['assets'][0]['size']
                    notes = x['body']
                    draft = x['draft']
                    prerelease = x['prerelease']
                    logger.debug(notes)
                    logger.debug(draft)
                    logger.debug(prerelease)
                    # skip all alpha & beta versions if we're not already on it
                    if 'alpha' in tag and not 'alpha' in __version__ \
                            or 'beta' in tag and not 'beta' in __version__:
                        continue
                    # we're already up to date
                    elif tag == __version__:
                        return
                    # return latest version
                    # return url, size, notes, tag
                    if self.confirm("
Une nouvelle version d'EKPI est disponible: {}
"
                                    "
Voulez-vous mettre à jour maintenant ?
"
                                    "(EKPI sera automatiquement redemarré)
"
                                    "
Notes de version: {}
".format(tag, notes)):
                        # self.hide()
                        self.update_gui.show()
                        tmp_file = abspath(join(gettempdir(), ''.join(choice("{0}{1}".format(
                            ascii_uppercase, digits)) for _ in range(15))))
                        if not download(url, tmp_file, size=size, download_nice_name='EPPS',
                                        callback=self.update_gui.download_progress_bar):
                            self.logger.error('erreur lors du téléchargement')
                            return
                        if exists('./update'):
                            rmtree('./update')
                        mkdir('./update')
                        if not unzip(tmp_file, './update'):
                            self.logger.error('erreur lors de la décompression')
                        self.logger.debug("fermeture du programme")
                        for f in listdir('./update'):
                            if f == "epps.exe":
                                continue
                            try:
                                copy('./update/{}'.format(f), f)
                            except:
                                continue
                        rmtree('./update')
                        self.update_gui.hide()
                        startfile('epps.exe')
                        _exit(0)
                    else:
                        return

            except IndexError:
                self.logger.error('erreur lors de la recherche de mise à jour; la dernière release n\'a pas encore de '
                                  'fichier disponible au téléchargement, probablement qu\'etcher est en train d\''
                                  'uploader, ou qu\'il a retiré la release à cause d\'un bug découvert à la dernière '
                                  'minute. Vous pourrez réessayer d\'ici quelques minutes.')
            except:
                self.logger.exception("erreur lors de la recherche d'une nouvelle version")
                return
            self.logger.debug("pas de nouvelle version")
            return

        @staticmethod
        def __build_msg_box():
            _msgbox = QMessageBox()
            _msgbox.setWindowTitle("EPPS {}".format(__version__))
            _msgbox.setWindowIcon(icon)
            _msgbox.setTextFormat(1)
            return _msgbox

        @pyqtSlot(str)
        def msgbox(self, text):
            _msgbox = self.__build_msg_box()
            _msgbox.setText(text)
            _msgbox.addButton(QPushButton('Ok ...'), QMessageBox.YesRole)
            _msgbox.exec_()

        @pyqtSlot(str)
        def confirm(self, text):
            _msgbox = self.__build_msg_box()
            _msgbox.setText(text)
            _msgbox.addButton(QMessageBox.Yes)
            _msgbox.addButton(QMessageBox.No)
            if _msgbox.exec_() == QMessageBox.Yes:
                return True
            return

def download(url, target, count=1, size=None, download_nice_name='', callback=None, redirect=False):
    logger.debug("Defer - download - début du téléchargement")
    logger.debug("Defer - download - url: {}".format(url))
    logger.debug("Defer - download - fichier local: {}".format(target))
    try:
        logger.debug("Defer - download - récupération des headers")
        resp = requests_head(url)
    except:
        logger.exception("Defer - download - erreur lors de la récupération des headers")
        return
    if not resp:
        logger.exception("Defer - download - erreur lors de la récupération des headers")
        return
    logger.debug('Defer - download - lecture des headers')
    try:
        h = resp.headers
        if size is None:
            logger.debug('Defer - download - recherche de la taille du fichier à télécharger dans les headers')
            if 'Content-Length' in h.keys():
                size = h['Content-Length']
                logger.debug('Defer - download - taille trouvée: {}'.format(size))
    except:
        logger.error('defer-download - erreur lors de la lecture des headers')
        return
    if redirect and 'location' in h.keys() and not h['location'] == url:
        logger.debug('Defer - download - redirection vers la nouvelle url: {}'.format(h['location']))
        if count > 10:
            logger.error("Defer - download - trop de redirections, je laisse tomber")
            return
        return download(h['location'], target, count + 1, size=size,
                        download_nice_name=download_nice_name, redirect=redirect)
    if size is None:
        if count > 10:
            logger.error('Defer - download - je ne suis pas parvenu à obtenir la taille du fichier distant')
            logger.error('Defer - download - headers: {}'.format(h))
            return
        return download(url, target, count=count + 1, size=size,
                        download_nice_name=download_nice_name, callback=callback, redirect=redirect)
    else:
        size = int(size)
    logger.debug("Defer - download - début du transfert des données")
    try:
        callback.update(0)
        callback.update_title("Téléchargement de : {} ({})".format(download_nice_name, humansize(size)))
        with request.urlopen(url) as resp, open(target, mode='wb') as f:
            size_dl = 0
            while True:
                buffer = resp.read(512)
                if not buffer:
                    break
                size_dl += len(buffer)
                f.write(buffer)
                callback.update(size_dl * 100 / size)
    except:
        logger.exception("Defer - download - erreur lors du transfert des données")
        return
    callback.update_title("Téléchargement de : {} ({}) - succès".format(download_nice_name, humansize(size)))
    callback.update(100)
    return True

def unzip(zip_file_path, target_dir):
    logger.debug("Defer - unzip - ouverture du fichier ZIP")
    try:
        with ZipFile(zip_file_path, mode='r', compression=ZIP_LZMA) as zip_file:
            logger.debug(
                "Defer - unzip - extraction des données vers {}".format(target_dir))
            zip_file.extractall(target_dir)
    except BadZipfile:
        logger.exception(
            "il semble que le fichier ZIP suivant soit corrompu: {}".format(zip_file_path))
        return
    except:
        logger.exception("Defer - unzip- erreur lors de l'extraction du fichier ZIP")
        logger.error("Est-ce que le dossier suivant est protégé par l'UAC Windows ? \n\"{}\""
                     "\n\nSi oui, il faudrait peut-être redémarrer EKPI en mode administrateur"
                     .format(zip_file_path))
        return
    return True

logger = mkLogger('__main__')
qt_app = QApplication(sys.argv)
icon = QIcon(':/ico/epps.ico')
ui_main = Gui.Main()
ui_main.setWindowIcon(icon)
_exit(qt_app.exec())


import sys
from setuptools import setup
main = 'ezrp.py'

if (sys.platform == 'darwin'):
	extra_options = dict(
		setup_requires=["py2app"],
		options=dict(py2app=dict(argv_emulation=True))
	)
elif (sys.platform == 'win32'):
	from cx_Freeze import setup, Executable

	extra_options = dict(
		setup_requires=["cx_Freeze"],
		executables = [Executable(main, base="Win32GUI", shortcutName="ezrp", shortcutDir="ProgramMenuFolder")]
	)
else:
	extra_options = dict(
		scripts=[main]
	)
setup(
	name = "ezrp",
	version = "1.0.0a2",
    app=[main],
	**extra_options
)


import numpy as np
import subprocess
import sys
from collections import defaultdict
from tqdm import tqdm
import os
import pickle

np.random.seed(42)

class RNN:
    def __init__(self, H, epoch=1):
        self.H = H
        self.epoch = epoch
        self.x_ids = defaultdict(lambda: len(self.x_ids))
        self.y_ids = defaultdict(lambda: len(self.y_ids))
        self.x_len = 0
        self.y_len = 0

    def init_net(self):
        # w_rx = np.random.rand(self.x_len, self.H) / 5 - 0.1
        w_rx = np.random.rand(self.H, self.x_len) / 5 - 0.1
        w_rh = np.random.rand(self.H, self.H) / 5 - 0.1
        b_r = np.random.rand(self.H, 1) / 5 - 0.1
        # w_oh = np.random.rand(self.H, self.y_len) / 5 - 0.1
        w_oh = np.random.rand(self.y_len, self.H) / 5 - 0.1
        b_o = np.random.rand(self.y_len, 1) / 5 - 0.1
        self.net = [w_rx, w_rh, b_r, w_oh, b_o]

    def softmax(self, x):
        """ #08 p9 """
        r = np.exp(x)
        return r / r.sum()

    def find_best(self, p):
        """ #8 10 """
        return np.argmax(p)
        y = 0
        for i in range(1, len(p)):
            if p[i] > p[y]:
                y = i
        return y

    def create_one_hot(self, id_, size):
        """ #8 p12 """
        vec = np.zeros((size, 1))
        if id_ is not None:
            vec[id_] = 1
        return vec

    def forward(self, x):
        """ #8 p16 """
        w_rx, w_rh, b_r, w_oh, b_o = self.net
        x_len = len(x)
        h = [None for _ in range(x_len)]  # 隠れ層の値 (各時間tにおいて)
        p = [None for _ in range(x_len)]  # 出力の確率分布の値 (各時間tにおいて)
        y = [None for _ in range(x_len)]  # 出力の確率分布の値 (各時間tにおいて)
        for t in range(x_len):
            if t > 0:
                h[t] = np.tanh(np.dot(w_rx, x[t]) + np.dot(w_rh, h[t - 1]) + b_r)   # w_rx → w_rx.T
            else:
                h[t] = np.tanh(np.dot(w_rx, x[t]) + b_r)    # w_rx → w_rx.T
            p[t] = self.softmax(np.dot(w_oh, h[t]) + b_o)        # w_oh → w_oh.T
            y[t] = self.find_best(p[t])
        return h, p, y

    def gradient(self, x, h, p, y_):
        """ #8 p30 """
        w_rx, w_rh, b_r, w_oh, b_o = self.net
        Δw_rx, Δw_rh, Δb_r, Δw_oh, Δb_o = [np.zeros_like(x) for x in self.net]

        δ_r_ = np.zeros((len(b_r), 1))   # 次の時間から伝搬するエラー
        for t in range(len(x) - 1, -1, -1):
            δ_o_ = y_[t] - p[t]                                # 出力層エラー              # 出力層重み勾配
            Δw_oh += np.outer(δ_o_, h[t])                  # 出力層重み勾配
            Δb_o += δ_o_                                   # 出力層重み勾配
            # δ_r = np.dot(δ_r_, w_rh) + np.dot(w_oh, δ_o_)   # 逆伝搬    np.dot(δ_o_, w_oh) → np.dot(w_oh, δ_o_)
            δ_r = np.dot(w_rh, δ_r_) + np.dot(w_oh.T, δ_o_)   # 逆伝搬    np.dot(δ_o_, w_oh) → np.dot(w_oh, δ_o_)
            δ_r_ = δ_r * (1 - h[t] ** 2)                    # tanh の勾配
            # Δw_rx += np.outer(x[t], δ_r_)                   # 隠れ層重み勾配
            Δw_rx += np.outer(δ_r_, x[t])                   # 隠れ層重み勾配
            Δb_r += δ_r_                                    # 隠れ層重み勾配
            if t != 0:
                Δw_rh += np.outer(δ_r_, h[t - 1])
                # Δw_rh += np.outer(h[t - 1], δ_r_)
        Δ = [Δw_rx, Δw_rh, Δb_r, Δw_oh, Δb_o]
        return Δ

    def update_weights(self, Δ, λ=0.01):
        w_rx, w_rh, b_r, w_oh, b_o = self.net
        Δw_rx, Δw_rh, Δb_r, Δw_oh, Δb_o = Δ
        w_rx += λ * Δw_rx
        w_rh += λ * Δw_rh
        b_r += λ * Δb_r
        w_oh += λ * Δw_oh
        b_o += λ * Δb_o
        self.net = w_rx, w_rh, b_r, w_oh, b_o

    def dump(self, data, file_name):
        os.makedirs('pickles_naoto', exist_ok=True)
        with open(f"pickles_naoto/{file_name}.pkl", 'wb') as f_out:
            pickle.dump(data, f_out)

    def train(self, train_path):
        """ #8 p32 """
        X, Y_corrrect = [], []
        for line in map(lambda x: x.rstrip(), open(train_path)):
            words, tags = map(list, zip(*map(lambda x: x.split('_'), line.split())))
            X.append([])
            Y_corrrect.append([])
            for word, tag in zip(words, tags):
                X[-1].append(self.x_ids[word])
                Y_corrrect[-1].append(self.y_ids[tag])
        self.x_ids = dict(self.x_ids)
        self.y_ids = dict(self.y_ids)
        self.x_len = len(self.x_ids)
        self.y_len = len(self.y_ids)
        self.init_net()

        x_onehot_list = []
        y_onehot_list = []
        for x, y_correct in zip(X, Y_corrrect):
            x_onehot_list.append([])
            y_onehot_list.append([])
            for i in range(len(x)):
                x_onehot_list[-1].append(self.create_one_hot(x[i], self.x_len))
            for i in range(len(y_correct)):
                y_onehot_list[-1].append(
                    self.create_one_hot(y_correct[i], self.y_len))
        for _ in tqdm(range(self.epoch)):
            for x_onehot, y_onehot in zip(x_onehot_list, y_onehot_list):
                h, p, y_predict = self.forward(x_onehot)
                Δ = self.gradient(x_onehot, h, p, y_onehot)
                self.update_weights(Δ)
        self.dump(self.net, 'rnn_net')
        self.dump(self.x_ids, 'x_ids')
        self.dump(self.y_ids, 'y_ids')

    def test(self, test_path, out_path):
        self.y_ids_recover = {value: key for key, value in self.y_ids.items()}
        with open(out_path, 'w') as f:
            x_onehot_list = []
            for line in map(lambda x: x.rstrip(), open(test_path)):
                words = line.split(' ')
                x_onehot_list.append([])
                for word in words:
                    if word in self.x_ids:
                        x_onehot_list[-1].append(self.create_one_hot(
                            self.x_ids[word], self.x_len))
                    else:
                        x_onehot_list[-1].append(self.create_one_hot(
                            None, self.x_len))
            for x_onehot in x_onehot_list:
                h, p, y = self.forward(x_onehot)
                predict_list = []
                for predict_num in y:
                    predict = self.y_ids_recover[predict_num]
                    predict_list.append(predict)
                print(' '.join(predict_list), file=f)

if __name__ == '__main__':
    if sys.argv[1:] == ['test']:
        train_path = '../../../nlptutorial/test/05-train-input.txt'
        test_path = '../../../nlptutorial/test/05-test-input.txt'
        ans_path = '../../../nlptutorial/test/05-test-answer.txt'
    else:
        train_path = '../../../nlptutorial/data/wiki-en-train.norm_pos'
        test_path = '../../../nlptutorial/data/wiki-en-test.norm'
        ans_path = '../../../nlptutorial/data/wiki-en-test.pos'
    out_path = 'out.txt'
    script_path = '../../../nlptutorial/script/gradepos.pl'

    rnn = RNN(5, 20)
    rnn.train(train_path)
    rnn.test(test_path, out_path)
    subprocess.run(f'perl {script_path} {ans_path} {out_path}'.split())


#!/usr/bin/env python

import numpy
import scipy
from scipy import signal
from scipy.spatial.distance import squareform
from scipy.cluster.hierarchy import linkage
from scipy.cluster.hierarchy import fcluster
from scm.plams import Molecule, DCDTrajectoryFile, dihedral

"""
The goal is to find out for each bond if all three torsion angles are represented
"""

def define_rotatable_torsions (mol) :
        """
        Return the atoms of the torsion angles for the rotatable bonds
        """
        torsions = []
        for bond in mol.bonds :
                indices = [ind-1 for ind in mol.index(bond)]
                terminal = False
                identical = False
                for i,at in enumerate(bond) :
                        neighbors = at.neighbors()
                        if len(neighbors)<4 :
                                terminal = True
                                continue
                        labels = set([at.IDname for at in neighbors if not at in bond])
                        if len(labels) == 1 :
                                identical = True
                if terminal or identical :
                        continue
                # Define the torsion
                one_four = []
                for at in bond :
                        one_four += [mol.index(n)-1 for n in at.neighbors() if n.symbol=='C' and not n in bond]
                torsion = [one_four[0]] + indices + [one_four[1]]
                torsions.append(torsion)

        return torsions

def get_diffvec (phi,psi) :
        """
        Compute the shift
        """
        diff = phi-psi
        diff = diff - (numpy.round(diff/360)*360)
        return diff

def get_distance (phi,psi) :
        """
        Computes the difference between two dihedral angles
        """
        return abs(get_diffvec (phi,psi))

def get_average_torsion (phis) :
        """
        Get the average torsion angle, taking periodicity into account
        """
        shift = phis[0]
        phis_shifted = get_diffvec(phis,shift)
        avg_shifted = phis_shifted.sum()/len(phis)
        average = avg_shifted + shift
        return average

def check_clusters (centers, threshold=30.) :
        """
        Check that the clusters are approximately 120 degrees apart
        """
        ones = numpy.ones(nclusters)
        distances = get_distance(ones*centers.reshape((nclusters,1)), ones*centers.reshape((1,nclusters)))
        distances = distances[numpy.triu(distances)!=0]
        return (abs(distances-120)).max() <= threshold

mol = Molecule('mol.xyz')
mol.guess_bonds()
mol.label(keep_labels=True)
nats = len(mol)

dcd = DCDTrajectoryFile('RDKit.dcd')

# Define the torsion angles
torsions = define_rotatable_torsions(mol)
for tor in torsions: print(tor)

# Get all the values for the torsion angles
coords = mol.as_array()
torsion_angles = {}
for iconf,(crd,cell) in enumerate(dcd) :
        if iconf%100==0 : print (iconf)
        coords[:] = crd
        for itors,atoms in enumerate(torsions) :
                phi = dihedral(*coords[atoms],unit='degree')
                if not itors in torsion_angles :
                        torsion_angles[itors] = []
                torsion_angles[itors].append(phi)
for itors,atoms in enumerate(torsion_angles) :
        torsion_angles[itors] = numpy.array(torsion_angles[itors])

# Now we need to cluster them somehow (for a function over the histogram and find maxima?
confnum = 6 # The conformation I want to compare
ntorsions = len(torsions)
size_list = []
dists_to_conf = []
for itors in range(ntorsions) :
        phis = torsion_angles[itors]
        #print ('phis: ',phis)

        # Compute a distance matrix
        nconfs = len(phis)
        ones = numpy.ones((nconfs,nconfs))
        matrix = get_distance(ones * phis.reshape((nconfs,1)), ones*phis.reshape((1,nconfs)) )

        # Get the minimum distance conformer for each conformer
        print ('Matrix ',itors)
        print (matrix[confnum,:10])
        matrix[range(nconfs),range(nconfs)] = 1000.
        dists_to_conf.append(matrix[confnum])

dists_to_conf = numpy.array(dists_to_conf)

# Now find the conformers that is overall the most similar
dist_to_conf = dists_to_conf.sum(axis=0) / ntorsions
indices = dist_to_conf.argsort()
mindist = dist_to_conf.min()
print ()
print ('The nearest conformer: ',indices[:5], mindist)


import coax
import jax
import jax.numpy as jnp
import gym
import haiku as hk
import optax

# the MDP
env = gym.make('FrozenLakeNonSlippery-v0')
env = coax.wrappers.TrainMonitor(env)

def func_v(S, is_training):
    value = hk.Sequential((hk.Linear(1, w_init=jnp.zeros), jnp.ravel))
    return value(S)

def func_pi(S, is_training):
    logits = hk.Linear(env.action_space.n, w_init=jnp.zeros)
    return {'logits': logits(S)}

# function approximators
pi = coax.Policy(func_pi, env)
v = coax.V(func_v, env)

# create copies
pi_old = pi.copy()  # behavior policy
v_targ = v.copy()   # target network

# experience tracer
tracer = coax.reward_tracing.NStep(n=1, gamma=0.9)

# updaters
simple_td = coax.td_learning.SimpleTD(v, v_targ, optimizer=optax.adam(0.02))
ppo_clip = coax.policy_objectives.PPOClip(pi, optimizer=optax.adam(0.01))

# train
for ep in range(500):
    s = env.reset()

    for t in range(env.spec.max_episode_steps):
        a, logp = pi_old(s, return_logp=True)
        s_next, r, done, info = env.step(a)

        # small incentive to keep moving
        if jnp.array_equal(s_next, s):
            r = -0.01

        # update
        tracer.add(s, a, r, done, logp)
        while tracer:
            transition_batch = tracer.pop()
            _, td_error = simple_td.update(transition_batch, return_td_error=True)
            ppo_clip.update(transition_batch, td_error)

            # sync target networks
            v_targ.soft_update(v, tau=0.01)
            pi_old.soft_update(pi, tau=0.01)

        if done:
            break

        s = s_next

    # early stopping
    if env.avg_G > env.spec.reward_threshold:
        break

# run env one more time to render
s = env.reset()
env.render()

for t in range(env.spec.max_episode_steps):

    # estimated state value
    print("  v(s) = {:.3f}".format(v(s)))

    # print individual action probabilities
    params = pi.dist_params(s)
    propensities = jax.nn.softmax(params['logits'])
    for i, p in enumerate(propensities):
        print("  π({:s}|s) = {:.3f}".format('LDRU'[i], p))

    a = pi.mode(s)
    s, r, done, info = env.step(a)

    env.render()

    if done:
        break

if env.avg_G < env.spec.reward_threshold:
    name = globals().get('__file__', 'this script')
    raise RuntimeError(f"{name} failed to reach env.spec.reward_threshold")


# -*- coding: utf-8 -*-
"""
Created on Tue Apr 20 17:06:40 2021

@author: ANIL
"""

'''
The problem of finding summation of digit of number is quite common. This can sometimes come in form of list and we need to perform that. This has application in many domains such as school programming and web development. Let’s discuss certain ways in which this problem can be solved.
'''

def sumOfDigit(x):
    sumdigit = 0
    while(x>0):
        sumdigit += (x%10)
        x = x//10

    return sumdigit

test_list = [12, 67, 98, 34]
sum_list = []

for item in test_list:
    sum_list.append(sumOfDigit(item))

print(sum_list)


import json
import time
from datetime import datetime
from sensors import sensor

unknown_config_topic = "homeassistant/binary_sensor/tydom/{id}/config"
unknown_values_topic = "unknown/tydom/{id}/state_topic"

#temperature = current_temperature_topic
#setpoint= temperature_command_topic
#temperature_unit=C
#"modes": ["STOP", "ANTI-FROST","ECO", "COMFORT"],
#####################################
#setpoint (seulement si thermostat)
#temperature (intérieure, seulement si thermostat)
#anticipCoeff 30 (seulement si thermostat)

#thermicLevel STOP ECO ...
#auhorisation HEATING
#hvacMode NORMAL None (si off)
#timeDelay : 0
#tempoOn : False
#antifrost True False
#openingdetected False
#presenceDetected False
#absence False
#LoadSheddingOn False

#outTemperature float
##################################

# climate_json_attributes_topic = "climate/tydom/{id}/state"
# State topic can be the same as the original device attributes topic !
class Unknown:

    def __init__(self, tydom_attributes, tydom_client=None, mqtt=None):

        self.attributes = tydom_attributes
        self.device_id = self.attributes['device_id']
        self.endpoint_id = self.attributes['endpoint_id']
        self.id = self.attributes['id']
        self.name = self.attributes['name']
        self.mqtt = mqtt
        self.tydom_client = tydom_client

    async def setup(self):
        self.device = {}
        self.config = {}
        self.device['manufacturer'] = 'Delta Dore'
        self.device['name'] = self.name
        self.device['identifiers'] = self.id

        self.config['name'] = self.name
        #self.device['model'] = 'sensor'

        self.config_topic = unknown_config_topic.format(id=self.id)

        self.config['state_topic'] = unknown_values_topic.format(id=self.id)
        self.config['payload_on'] = True
        self.config['payload_off'] = False
        self.config['device_class'] = 'hvac'

        self.config['value_template'] =  "{{ value_json.intrusionDetect }}"
        self.config['unique_id'] = self.id

        if (self.mqtt != None):
            self.mqtt.mqtt_client.publish(self.config_topic, json.dumps(self.config), qos=0)

    async def update(self):
        await self.setup()

        # Chic Debug

        if (self.mqtt != None):
            self.mqtt.mqtt_client.publish(self.config['state_topic'],json.dumps(self.attributes), qos=0)


import random
import numpy as np
import tkinter as tk
from tkinter import ttk
import time  # Time is needed to slow down the agent and to see how he runs
from PIL import Image, ImageTk  # For adding images into the canvas widget
from path import Environment
from agent import QLearningTable
from configure import episodeAmount,env_height,env_width,randomPixelRatio,startPageTitle,startPageResolation,XCBOptions,YCBOptions

class HomePage(tk.Tk, object):
    def __init__(self):
        super(HomePage, self).__init__()
        #self.configure(bg="white")
        self.startPosition = [tk.StringVar(value=0),tk.StringVar(value=0)]
        self.endPosition = [tk.StringVar(value=0),tk.StringVar(value=0)]
        self.title(startPageTitle)
        self.geometry(startPageResolation)
        self.create_widgets()

    def create_widgets(self):
        self.startButton =  tk.Button(self,text="baslat",command=self.startQLearning)
        self.startButton.place(x = 190,y = 130)
        self.startPositionLabel= tk.Label(self,text = "Başlangıç konumu :").place(x = 40,y = 60)
        self.endPositionLabel = tk.Label(self,text="Bitiş Konumu          :").place(x=40,y=100)
        self.startPositionComboBoxX = ttk.Combobox(self,values=XCBOptions,textvariable=self.startPosition[0],width=5)
        self.startPositionComboBoxX.place(x=150,y=60)
        self.startPositionComboBoxX.current(0)
        self.startPositionComboBoxY = ttk.Combobox(self,values=YCBOptions,textvariable=self.startPosition[1],width=5)
        self.startPositionComboBoxY.place(x=210,y=60)
        self.startPositionComboBoxY.current(0)
        # hedef konum labirentin sonuna yaikin olmasi acisindan degerler ters donduruluyor.
        self.endPositionComboBoxX = ttk.Combobox(self,values=XCBOptions[::-1],textvariable=self.endPosition[0],width=5)
        self.endPositionComboBoxX.place(x=150,y=100)
        self.endPositionComboBoxX.current(0)
        self.endPositionComboBoxY = ttk.Combobox(self,values=YCBOptions[::-1],textvariable=self.endPosition[1],width=5)
        self.endPositionComboBoxY.place(x=210,y=100)
        self.endPositionComboBoxY.current(0)
    def startQLearning(self):
        self.destroy()
        startPixel = [int(self.startPosition[0].get()),int(self.startPosition[1].get())]
        finishPixel = [int(self.endPosition[0].get()),int(self.endPosition[1].get())]
        print(finishPixel)
        # random Obstacle coordinat list ex:5x5 [0,3]
        obstacleCoordinats = self.generateRandomObstacleCoordinats(finishPixel,startPixel)
        self.env = Environment(startPixel ,finishPixel,obstacleCoordinats)
        # Calling for the main algorithm
        self.RL = QLearningTable(actions=list(range(self.env.n_actions)))
        # Running the main loop with Episodes by calling the function update()
        self.env.after(100, self.update)  # Or just update()
        self.env.mainloop()

    def update(self):
        # Resulted list for the plotting Episodes via Steps
        steps = []

    # Summed costs for all episodes in resulted list
        all_costs = []

        for episode in range(episodeAmount):
        # Initial Observation
            print(episode)
            observation = self.env.reset()
        # Updating number of Steps for each Episode
            i = 0

        # Updating the cost for each episode
            cost = 0

            while True:
            # Refreshing environment
                # self.env.render()

            # RL chooses action based on observation
                action = self.RL.choose_action(str(observation))

            # RL takes an action and get the next observation and reward
                observation_, reward, done = self.env.step(action)

            # RL learns from this transition and calculating the cost
                cost += self.RL.learn(str(observation), action, reward, str(observation_))

            # Swapping the observations - current and next
                observation = observation_

            # Calculating number of Steps in the current Episode
                i += 1

            # Break while loop when it is the end of current Episode
            # When agent reached the goal or obstacle
                if done:
                    steps += [i]
                    all_costs += [cost]
                    break

    # Showing the final route
        self.env.final()

    # Showing the Q-table with values for each action
        self.RL.print_q_table()

    # Plotting the results
        self.RL.plot_results(steps, all_costs)

    def generateRandomObstacleCoordinats(self,finishPixel,startPixel):

        obstacleAmount = int(env_height*env_width*randomPixelRatio)
        xList = np.random.randint(env_width,size=obstacleAmount)
        yList =  np.random.randint(env_height,size=obstacleAmount)
        obstacleCoordinats = []
        f = open("./entities/engel.txt", "w")
        try:
            for i in range(obstacleAmount):
                if not(xList[i]==finishPixel[0] and yList[i]==finishPixel[1]) and not(xList[i]==startPixel[0] and yList[i]==startPixel[1]):
                    newObstacle = [xList[i] ,yList[i]]
                    obstacleCoordinats.append(newObstacle)
                    f.write("({}, {}, K)\n".format(xList[i], yList[i]))
            #print(obstacleCoordinats)
            #test icin
            for i in range(obstacleAmount):
                if(xList[i]==finishPixel[0] and yList[i]==finishPixel[1]) or (xList[i]==startPixel[0] and yList[i]==startPixel[1]):
                    print("cakisiyor......")
        except(e):
            print("Dosyaya yazarken veyahut random atama yapilirken bir hata olustu!")
        finally:
            f.close();
            return obstacleCoordinats

# sadece bu dosya calistirilmak
if __name__ == '__main__':
    env = HomePage()
    env.mainloop()


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

from glance.common import exception
import glance.store
from glance.tests.unit import utils as unit_test_utils
from glance.tests import utils

BASE_URI = 'swift+http://storeurl.com/container'
UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d'
UUID2 = '971ec09a-8067-4bc8-a91f-ae3557f1c4c7'
USER1 = '54492ba0-f4df-4e4e-be62-27f4d76b29cf'

class ImageRepoStub(object):
    def get(self, *args, **kwargs):
        return 'image_from_get'

    def list(self, *args, **kwargs):
        return ['image_from_list_0', 'image_from_list_1']

class ImageStub(object):
    def __init__(self, image_id, status, location):
        self.image_id = image_id
        self.status = status
        self.location = location

    def delete(self):
        self.status = 'deleted'

class TestStoreImage(utils.BaseTestCase):
    def setUp(self):
        location = '%s/%s' % (BASE_URI, UUID1)
        self.image_stub = ImageStub(UUID1, 'active', location)
        self.image_repo_stub = ImageRepoStub()
        self.store_api = unit_test_utils.FakeStoreAPI()
        super(TestStoreImage, self).setUp()

    def test_image_delete(self):
        image = glance.store.ImageProxy(self.image_stub, {}, self.store_api)
        self.assertEquals(image.status, 'active')
        self.store_api.get_from_backend({}, image.location)  # no exception
        image.delete()
        self.assertEquals(image.status, 'deleted')
        self.assertRaises(exception.NotFound,
                          self.store_api.get_from_backend, {}, image.location)

    def test_image_delayed_delete(self):
        self.config(delayed_delete=True)
        image = glance.store.ImageProxy(self.image_stub, {}, self.store_api)
        self.assertEquals(image.status, 'active')
        image.delete()
        self.assertEquals(image.status, 'pending_delete')
        self.store_api.get_from_backend({}, image.location)  # no exception

    def test_image_get_data(self):
        image = glance.store.ImageProxy(self.image_stub, {}, self.store_api)
        self.assertEquals(image.get_data(), 'XXX')

    def test_image_set_data(self):
        context = glance.context.RequestContext(user=USER1)
        image_stub = ImageStub(UUID2, status='queued', location=None)
        image = glance.store.ImageProxy(image_stub, context, self.store_api)
        image.set_data('YYYY', 4)
        self.assertEquals(image.size, 4)
        #NOTE(markwash): FakeStore returns image_id for location
        self.assertEquals(image.location, UUID2)
        self.assertEquals(image.checksum, 'Z')

    def test_image_repo_get(self):
        image_repo = glance.store.ImageRepoProxy({}, self.store_api,
                                                 self.image_repo_stub)
        image = image_repo.get(UUID1)
        self.assertTrue(isinstance(image, glance.store.ImageProxy))
        self.assertEqual(image.image, 'image_from_get')

    def test_image_repo_list(self):
        image_repo = glance.store.ImageRepoProxy({}, self.store_api,
                                                 self.image_repo_stub)
        images = image_repo.list()
        for i, image in enumerate(images):
            self.assertTrue(isinstance(image, glance.store.ImageProxy))
            self.assertEqual(image.image, 'image_from_list_%d' % i)


def printColor(msg, color=None, style=0):
	colorDci = {
		'orange': 31,
		'green': 32,
		'red': 33,
		'white': 34,
		'fense': 35,
		'blue': 36,
		'gray': 37,
	}
	if color:
		color = colorDci.get(color)
		if not color:
			color = 30
	print(f'\033[{style};{color}m {msg} \033[m')


#导入程序运行必须模块
from win32com.client import Dispatch
import sys
import os
import time
import shutil
import openpyxl as xl
import xlrd
from xlutils.copy import copy

from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import QEventLoop, QTimer
from PyQt5.QtGui import QPainter, QColor
#PyQt5中使用的基本控件都在PyQt5.QtWidgets模块中
from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow,QGroupBox, QPushButton, QLabel, QHBoxLayout, QVBoxLayout, QGridLayout, QFormLayout, QLineEdit, QTextEdit, QInputDialog, QFileDialog, QMessageBox, QDesktopWidget

#导入UI文件类
from pyqt5_office_keywords_replace_ui import Ui_MainWindow

class MyMainForm(QMainWindow, Ui_MainWindow):

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

        # 添加选择替换目录 按钮信号和槽
        self.ori_dir_btn.clicked.connect(self.replacePath)

        # 添加添加选择存储目录 按钮信号和槽
        self.replace_dir_btn.clicked.connect(self.savePath)

        #添加开始转换按钮信号和槽
        self.start_transfer.clicked.connect(self.transfer)

        self.word = Dispatch('kwps.Application')

    #需要替换的目录
    def replacePath(self):
        path = QFileDialog.getExistingDirectory(self, "请选择您要替换的目录")
        # 判断选择的文件是否存在
        if os.path.exists(path):
            # 将保存url放入路径文本框中
            self.ori_dir_input.setText(path)
        else:
            self.showMsg('错误', '您选择的目录不存在，请重新选择！')
            return False

    def savePath(self):
        path = QFileDialog.getExistingDirectory(self, "请选择您要保存的位置")
        if os.path.exists(path):
            # 将保存url放入路径文本框中
            self.replace_dir_input.setText(path)
        else:
            self.showMsg('错误', '您选择的目录不存在，请重新选择！')
            return False

    # 显示消息
    def showMsg(self, title, content, icon=3):
        box = QMessageBox(QMessageBox.Warning, title, content)
        # 设置左上角消息框图标
        # box.setWindowIcon(QIcon(r'E:\site\python\cutimg\favicon.ico'))
        # 添加按钮，可用中文
        yes = box.addButton('确定', QMessageBox.YesRole)
        # 设置消息框中内容前面的图标
        box.setIcon(icon)
        # 显示该问答框
        box.exec()
        return False

    #开始转换
    def transfer(self):

        #需要替换的目录
        self.replace_dir = self.ori_dir_input.text()
        #保存的目录
        self.save_dir = self.replace_dir_input.text()
        #关键词，并且去除收尾空格
        self.keywords = self.replace_words.toPlainText().strip()

        if not os.path.isdir(self.replace_dir) or not os.path.isdir(self.save_dir):
            self.showMsg('错误', '您选择的目录不存在，请重新选择！')
            return False

        #存储目录必须为空目录
        if os.listdir(self.save_dir):
            self.showMsg('错误', '存储目录必须为空目录！')
            return False

        #文件目录和子目录不能相同
        if self.replace_dir == self.save_dir:
            self.showMsg('错误', '替换目录和存储目录不能相同！')
            return False

        # 替换目录和文件目录不能互为子目录
        if self.replace_dir.startswith(self.save_dir) or self.save_dir.startswith(self.replace_dir):
            self.showMsg('错误', '替换目录和存储目录不能相互包含！')
            return False

        if self.keywords == "":
            self.showMsg('错误', '关键词不能为空')
            return False

        #存储目录不存在就直接创建
        if not os.path.exists(self.save_dir):
            os.makedirs(self.save_dir)

        #开始替换
        self.replace_tool()
        #将转换结果输出到界面上
        # self.result_display.setPlainText(self.keywords)

    #删除目录及目录下的所有文件
    def del_dir(self, filepath):
        del_list = os.listdir(filepath)
        for f in del_list:
            file_path = os.path.join(filepath, f)
            if os.path.isfile(file_path):
                os.remove(file_path)
            elif os.path.isdir(file_path):
                shutil.rmtree(file_path)

    #将doc替换成docx
    def doc2docx(self, file):
        #获取文件目录，文件名带后缀，文件名，后缀
        file_dir, tmpfilename = os.path.split(file)
        file_name, extension = os.path.splitext(tmpfilename)
        doc = self.word.Documents.Open(file)

        new_file = file_dir + "/" +file_name + '.docx'
        doc.SaveAs(new_file, 12)  #12表示docx格式
        doc.Close()
        #删除doc文件
        os.remove(file)

        #docx文件转换
        self.docx_keywords_replace(new_file)

    #将目录及子目录下的文件copy到另一个目录
    def deep_copy_dir(self, origin_dir, target_dir):
        for files in os.listdir(origin_dir):
            name = os.path.join(origin_dir, files)
            back_name = os.path.join(target_dir, files)
            if os.path.isfile(name):
                if os.path.isfile(back_name):
                    shutil.copy(name, back_name)
                else:
                    shutil.copy(name, back_name)
            else:
                if not os.path.isdir(back_name):
                    os.makedirs(back_name)
                self.deep_copy_dir(name, back_name)

    #获取目录及子目录下的文件，并转换成可以处理的格式
    def recurse_transfer_file(self, path):
        for root, dirs, files in os.walk(path):
            for file in files:
                file = file.replace('\\', '/')
                src_file = os.path.join(root, file)

                #doc文件，先进行转换
                if src_file.endswith(".doc") and not src_file.startswith('~$'):
                    self.display_result("{src_file}格式转换".format(src_file=src_file))
                    self.doc2docx(src_file)
                elif src_file.endswith(".docx") and not src_file.startswith('~$'):
                    self.docx_keywords_replace(src_file)
                elif src_file.endswith(".xls") and not src_file.startswith('~$'):
                    # self.xls_keywords_replace(src_file)
                    pass
                elif src_file.endswith(".xlsx") and not src_file.startswith('~$'):
                    # self.xlsx_keywords_replace(src_file)
                    pass
                elif src_file.endswith(".pdf") and not src_file.startswith('~$'):
                    pass

    #word文件关键字替换
    def docx_keywords_replace(self, file):

        # 获取文件目录，文件名带后缀，文件名，后缀
        file_dir, tmpfilename = os.path.split(file)
        file_name, extension = os.path.splitext(tmpfilename)
        origin_file_name = file_name
        doc = self.word.Documents.Open(file)
        a = self.word.ActiveDocument.Sections

        # 每行
        every_line = self.keywords.split('\n')

        for i in range(len(a)):

            for line in every_line:
                split_list = line.split('|')
                old_word = split_list[0].strip().replace('\r', '').replace('\n', '').replace('\t', '')
                new_word = split_list[1].strip().replace('\r', '').replace('\n', '').replace('\t', '')

                #对页眉进行替换
                self.word.ActiveDocument.Sections[i].Headers[0].Range.Find.Execute(old_word, False, False, False, False, False, True, 1, True, new_word, 2)

                #对页脚进行替换
                self.word.ActiveDocument.Sections[i].Footers[0].Range.Find.Execute(old_word, False, False, False, False, False, True, 1, True, new_word, 2)

                #替换正文
                self.word.Selection.Find.Execute(old_word, False, False, False, False, False, True, 1, True, new_word, 2)

                file_name = file_name.replace(old_word, new_word)
                display_content = "{file}进行{old_word}->{new_word}替换".format(file=file, old_word = old_word, new_word = new_word)
                self.display_result(display_content)

        #存储替换文件
        doc.SaveAs(r"{0}/{1}.docx".format(file_dir, file_name))
        if origin_file_name != file_name:
            os.remove(file)
        doc.Close()
        # self.word.Quit()

    #替换xlsx关键词
    def xlsx_keywords_replace(self, file):
        wb = xl.load_workbook(file)
        ws = wb.worksheets[0]

        every_line = self.keywords.split('\n')
        file_dir, tmpfilename = os.path.split(file)
        file_name, extension = os.path.splitext(tmpfilename)

        # 每个关键词替换
        for line in every_line:

            split_list = line.split('|')
            old_word = split_list[0].strip().replace('\r', '').replace('\n', '').replace('\t', '')
            new_word = split_list[1].strip().replace('\r', '').replace('\n', '').replace('\t', '')

            for row in range(1, ws.max_row + 1):
                for col in range(1, ws.max_column + 1):
                    content = ws.cell(row=row, column=col).value
                    ws.cell(row=row, column=col).value = content.replace(old_word, new_word, 1)

            file_name = file_name.replace(old_word, new_word)

        #存储
        wb.save(r"{0}/{1}{2}".format(file_dir, file_name,extension))
        #删除源文件
        os.remove(file)
        wb.close()
        display_content = file + "关键词转换成功"
        self.display_result(display_content)

    #替换xls文件关键词
    def xls_keywords_replace(self, file):

        wb = xlrd.open_workbook(file, formatting_info=True)  # 获取xls，保留原格式
        ws = wb.sheet_by_index(0)  # 根据index获取sheet
        rows = ws.nrows
        cols = ws.ncols
        newbook = copy(wb)  # 复制xls
        newsheet = newbook.get_sheet(0)

        every_line = self.keywords.split('\n')
        file_dir, tmpfilename = os.path.split(file)
        file_name, extension = os.path.splitext(tmpfilename)
        # 每个关键词替换
        for line in every_line:
            split_list = line.split('|')
            old_word = split_list[0].strip().replace('\r', '').replace('\n', '').replace('\t', '')
            new_word = split_list[1].strip().replace('\r', '').replace('\n', '').replace('\t', '')

            # 遍历每个单元格，进行替换操作
            for row in range(1, rows):
                for col in range(1, cols):
                    content = ws.cell(row, col).value
                    if (content != None and isinstance(content, str)):  # 判断不为空且为字符
                        if (content.find(old_word) != -1):  # 找到需要替换的字符
                            newsheet.write(row, col, content.replace(old_word, new_word))

            file_name = file_name.replace(old_word, new_word)

        # 保存新的xls以替换原有的xls
        newbook.save(r"{0}/{1}{2}".format(file_dir, file_name, extension))
        # 删除源文件
        os.remove(file)
        display_content = file + "关键词转换成功"
        self.display_result(display_content)

    #将处理结果实时显示到控制台
    def display_result(self,msg):
        self.result_display.append("{msg}\n".format(msg=msg))
        # self.cursor = self.result_display.textCursor()
        # self.result_display.moveCursor(self.cursor.End)
        QApplication.processEvents()

    #核心替换功能
    def replace_tool(self):
        try:
            self.result_display.clear()
            self.display_result("正进行目录清理")
            # 转换前先清空目录下文件
            self.del_dir(self.save_dir)
            self.display_result("正进行目录文件拷贝")
            #将原始目录及子目录文件全部拷贝至新目录
            self.deep_copy_dir(self.replace_dir, self.save_dir)

            self.display_result("正进行文件关键词替换")
            #递归处理存储目录下的文件
            self.recurse_transfer_file(self.save_dir)
            self.display_result("全部操作完毕")
        except Exception as e:
            self.display_result("==================出现异常，请钉钉联系管理员==================")
            self.display_result(str(e))
            self.display_result("=============================================================")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    # 初始化
    myWin = MyMainForm()
    # 将窗口控件显示在屏幕上
    myWin.show()
    # 程序运行，sys.exit方法确保程序完整退出。
    sys.exit(app.exec_())


# Put the code here that you need to run the application/start the application
from src.reader import Manager, Process, db, users, sendSummary, updates

def main():
    manager = Manager()
    messageDict = manager.dict()
    similarityDict = manager.dict()
    parentTimes = manager.dict()
    updatesProcess = Process(target=updates, args=(messageDict,similarityDict,parentTimes,))
    sendSummaryProcess = Process(target=sendSummary, args=(messageDict,similarityDict,parentTimes,))
    updatesProcess.start()
    sendSummaryProcess.start()
    updatesProcess.join()
    sendSummaryProcess.join()

if __name__ == '__main__':
    db.setup()
    users.setup()
    users.delete_all()
    users.add_user('729427424')
    main()


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

from __future__ import print_function

import inspect
import sys
import contextlib

import game
from game import (
    shuffle_field,
    is_game_finished,
    handle_user_input,
    perform_move,
    EMPTY_MARK,
)

__author__ = 'sobolevn'

class AssertionTestException(AssertionError):
    pass

class BaseTestClass(object):
    fails = 0
    passed = 0

    def run_tests(self):
        print('Starting tests for: {}'.format(self.__class__.__name__))

        for method in dir(self):
            candidate = getattr(self, method)
            if callable(candidate) and method.startswith('test_'):
                try:
                    candidate()
                    self.__class__.passed += 1
                except AssertionTestException as ex:
                    print('{} failed: '.format(method), ex)
                    self.__class__.fails += 1

        fails = self.__class__.fails
        all_tests = fails + self.__class__.passed
        print("Finished class' tests: {}/{}".format(
                (all_tests - fails), all_tests))
        print()

    def _assert_compare(self, first, second, equality=True):
        if (first == second) != equality:
            message = 'does not equal' if equality else 'equals'
            raise AssertionTestException('{}.{}: {} {} {}'.format(
                    self.__class__.__name__,
                    inspect.stack()[1][3],
                    first,
                    message,
                    second,
            ))

    def assert_equal(self, first, second):
        self._assert_compare(first, second, equality=True)

    def assert_not_equal(self, first, second):
        self._assert_compare(first, second, equality=False)

    @contextlib.contextmanager
    def assert_raises(self, exception):
        try:
            yield
            raise AssertionTestException('{}.{}: does not rise {}'.format(
                    self.__class__.__name__,
                    inspect.stack()[1][3],
                    exception,
            ))
        except exception:
            pass

class TestShuffleField(BaseTestClass):
    def test_length(self):
        result = shuffle_field()
        self.assert_equal(len(result), 16)

    def test_randomness(self):
        result1 = shuffle_field()
        result2 = shuffle_field()
        self.assert_not_equal(result1, result2)

    def test_type(self):
        result = shuffle_field()
        self.assert_equal(isinstance(result, list), True)

class TestIsGameFinished(BaseTestClass):
    def test_finished_state(self):
        finished_state = list(range(1, 16))
        finished_state.append(EMPTY_MARK)

        result = is_game_finished(finished_state)
        self.assert_equal(result, True)

    def test_unfinished_states(self):
        unfinished_state = list(range(1, 16))
        unfinished_state.append(EMPTY_MARK)
        unfinished_state[0], unfinished_state[-1] = \
            unfinished_state[-1], unfinished_state[0]

        result = is_game_finished(unfinished_state)
        self.assert_equal(result, False)

class TestUserInput(BaseTestClass):
    @contextlib.contextmanager
    def _patch_user_input(self, obj, value):
        if sys.version_info[0] == 3:
            obj.input = lambda _: value
        else:
            obj.raw_input = lambda _: value

        yield

        # setting values back just in case:
        if sys.version_info[0] == 3:
            obj.input = input
        else:
            obj.raw_input = raw_input

    def test_right_input(self):
        with self._patch_user_input(game, 'w'):
            move = handle_user_input()
        self.assert_equal(move, 'w')

class TestPerformMove(BaseTestClass):
    left_down_corner_index = 12
    right_up_corner_index = 3

    @classmethod
    def _left_down_corner(cls):
        state = list(range(15))
        state[0], state[1] = state[1], state[0]
        state.insert(cls.left_down_corner_index, EMPTY_MARK)
        return state

    @classmethod
    def _right_up_corner(cls):
        state = cls._left_down_corner()
        state[cls.left_down_corner_index], state[cls.right_up_corner_index] = \
            state[cls.right_up_corner_index], state[cls.left_down_corner_index]
        return state

    def test_up_move(self):
        state = self._left_down_corner()
        result = perform_move(state, 'w')

        result_index = result.index(EMPTY_MARK)
        self.assert_equal(result_index, self.left_down_corner_index - 4)

    def test_right_move(self):
        state = self._left_down_corner()
        result = perform_move(state, 'd')

        result_index = result.index(EMPTY_MARK)
        self.assert_equal(result_index, self.left_down_corner_index + 1)

    def test_left_move(self):
        state = self._right_up_corner()
        result = perform_move(state, 'a')

        result_index = result.index(EMPTY_MARK)
        self.assert_equal(result_index, self.right_up_corner_index - 1)

    def test_down_move(self):
        state = self._right_up_corner()
        result = perform_move(state, 's')

        result_index = result.index(EMPTY_MARK)
        self.assert_equal(result_index, self.right_up_corner_index + 4)

    def test_bad_moves(self):
        state = self._right_up_corner()
        with self.assert_raises(IndexError):
            perform_move(state, 'w')

        with self.assert_raises(IndexError):
            perform_move(state, 'd')

        state = self._left_down_corner()
        with self.assert_raises(IndexError):
            perform_move(state, 'a')

        with self.assert_raises(IndexError):
            perform_move(state, 's')

if __name__ == '__main__':
    all_passed = 0
    all_fails = 0

    # Detect tests:
    for name, klass in inspect.getmembers(sys.modules[__name__]):
        if inspect.isclass(klass) and issubclass(klass, BaseTestClass) \
                and klass is not BaseTestClass:
            klass().run_tests()
            all_passed += klass.passed
            all_fails += klass.fails

    print('Total fails: {}'.format(all_fails))


# -*- coding: utf-8 -*-
"""
Created on Thu Sep  7 16:26:21 2017
爬取信息
@author: lovephysics
"""

from bs4 import BeautifulSoup
import urllib.request as request
import pandas as pd

url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-recent30-0-0-1-'

shuming = []
value = []

for num in range(1,26):

    urlopen = request.urlopen(url+str(num))
    content = urlopen.read()
    content=content.decode('gbk')
    soup = BeautifulSoup(content,'lxml')

    tem1 = soup.select('body div div div.bang_list_box ul li div.name a')
    #title
    tem2 = soup.select('body div.bang_wrapper div.bang_content div ul li div.price p span.price_n')
    #now price
    tem3 = soup.select('body div.bang_wrapper div.bang_content div ul li div.price p span.price_r')
    #before price
    tem9 = soup.select('body div.bang_wrapper div.bang_content div ul li div.price p span.price_s')
    #zekou
    tem = soup.select('body div.bang_wrapper div.bang_content div.bang_list_box ul li div.publisher_info a')
    tem4 = []  #author
    tem5 = []  #public
    for i,each in enumerate(tem):
        if(i%2==0):
            tem4.append(each)
        else:tem5.append(each)

    tem6 = soup.select('body div.bang_wrapper div.bang_content div.bang_list_box ul li div.star span.tuijian')
    #tuijian
    tem7 = soup.select('body div.bang_wrapper div.bang_content div.bang_list_box ul li div.star a')
    #pinglunshu
    tem8 = soup.select('body div.bang_wrapper div.bang_content div.bang_list_box ul li div.publisher_info span')
    #shijian

    for t1,t2,t3,t4,t5,t6,t7,t8,t9 in zip(tem1,tem2,tem3,tem4,tem5,tem6,tem7,tem8,tem9):
        v1 = t1.get_text()
        v2 = t2.get_text()
        v3 = t3.get_text()
        v4 = t4.get_text()
        v5 = t5.get_text()
        v6 = t6.get_text()
        v7 = t7.get_text()
        v8 = t8.get_text()
        v9 = t9.get_text()

        shuming.append(v1)
        value.append([v2,v3,v6,v7,v8,v9])

columns =  ['现价','原价','推荐','评论','时间','折扣']
df = pd.DataFrame(value,index = shuming,columns=columns)
df.to_csv('dangdang_xiaoshuo.csv')


import requests
from time import sleep

def config_params(params, param, payload):

    """
    takes as input a list of params, a param under consideration and payload to be inserted,
    creates a dict in which param under consideration is set to payload
    and sets all other params to "example".
    return dict request_params
    """

    request_params = {}

    for parameter in params:

            if parameter == param:

                request_params[parameter] = payload

            else:

                request_params[parameter] = "test"

    return request_params

def make_fuzz_request(url, params, param, payload):
    """
    takes target url, list of params, present param and payload as inputs,
    configures parameters and makes request,
    returns response and, if WAF and dropping suspicious requests, returns break_loop as True
    """
    break_loop = False

    request_params = config_params(params, param, payload)

    # tries to make request
    try:

        response = requests.post(url, data=request_params)

    # if request is dropped, tries again in 60 seconds
    except:

        print("WAF is dropping suspiscious requests")
        print("Payload: " + payload)
        sleep(60)

        try:

            response = requests.post(url, data=request_params)

        # if dropped again sets break_loop to True
        except:

            print("WAF is blocking this IP address")

            break_loop = True

    return response, break_loop


import random
import sys

board = [['-', '-', '-'], ['-', '-', '-'], ['-', '-', '-']]
inputs = 'XO'

def printBoard():
	for x in range(3):
		print(" ".join(board[x]))
	print()

def selectInput():
	pi = input('Do you wish to play as X or O?: ').upper()
	return inputs[inputs.index(pi)]

player_input = selectInput()

if player_input == 'X':
	computer_input = 'O'
else:
	computer_input = 'X'

def playerMove(board, player_input):
	position = input('Enter the row(1-3) and col(1-3) : ').strip().split()
	row = int(position[0]) - 1
	col = int(position[1]) -1

	if board[row][col] == '-':
		board[row][col] = player_input

	else:
		print("Invalid")

def offence(board, computer_input, player_input):
	#row check
	for x in range(3):
		if not player_input in board[x]:
			if board[x].count('O') == 2:

				board[x] = computer_input * 3
				return True

	#col check
	for y in range(3):
		array = []

		for x in range(3):
			array.append(board[x][y])

		if not player_input in array:
			if array.count(computer_input) == 2:
				pos = array.index('-')
				board[pos][y] = computer_input
				return True

	#right diagonal check
	array = []
	for x in range(3):
		array.append(board[x][x])

	if not player_input in array:
		if array.count(computer_input) == 2:
			pos = array.index('-')
			board[pos][pos] = computer_input
			return True

	#left diagonal check
	array = []
	for y in range(2, -1, -1):
		array.append(board[2 - y][y])

	if not player_input in array:
		if array.count(computer_input) == 2:
			pos = array.index('-')
			board[pos][2 - pos] = computer_input
			return True

def defence(board, computer_input, player_input):

	#row check
	for x in range(3):
		if not computer_input in board[x]:
			if board[x].count(player_input) == 2:
				pos = board[x].index('-')
				board[x][pos] = computer_input
				return True

	#col check
	for y in range(3):
		array = []

		for x in range(3):
			array.append(board[x][y])

		if not computer_input in  array:
			if array.count(player_input) == 2:
				pos = array.index('-')
				board[pos][y] = computer_input
				return True

	#R diagonal check
	array = []
	for x in range(3):
		array.append(board[x][x])

	if not computer_input in array:
		if array.count(player_input) == 2:
			pos = array.index('-')
			board[pos][pos] = computer_input
			return True

	#L diagonal check

	array = []
	for y in range(2, -1, -1):
		array.append(board[2 - y][y])

	if not computer_input in array:
		if array.count(player_input) == 2:
			pos = array.index('-')
			board[pos][2 - pos] = computer_input
			return True

def computerMove(board, computer_input, player_input):

	flag = offence(board, computer_input, player_input)
	if flag == True:
		return

	flag = defence(board, computer_input, player_input)
	if flag == True:
		return

	if board[0][0] == '-':
		board[0][0] = computer_input

	elif board[2][0] == '-':
		board[2][0] = computer_input

	elif board[0][2] == '-':
		board[0][2] = computer_input

	elif board[2][2] == '-':
		board[2][2] = computer_input

	else:

		while 1:
			row = random.randint(0, 2)
			col = random.randint(0, 2)

			if board[row][col] == '-':
				board[row][col] = computer_input
				break

def checkBoard(board, move_input):

	for x in range(3):
		if board[x].count(move_input) == 3:
			print("{} wins!".format(move_input))
			sys.exit()

	for y in range(3):
		array = []
		for x in range(3):
			array.append(board[x][y])

		if array.count(move_input) == 3:
			print("{} wins!".format(move_input))
			sys.exit()

	array = []
	for x in range(3):
		array.append(board[x][x])

	if array.count(move_input) == 3:
		print("{} wins!".format(move_input))
		sys.exit()

	array = []
	for y in range(2, -1, -1):
		array.append(board[2 - y][y])

	if array.count(move_input) == 3:
		print("{} wins!".format(move_input))
		sys.exit()

	count = 0
	for x in range(3):
		for y in range(3):
			if board[x][y] != '-':
				count +=1

	if count == 9:
		print("It's a draw.")
		sys.exit(0)

while True:
	print("Player's turn")
	playerMove(board, player_input)
	printBoard()
	checkBoard(board, player_input)

	print("Computer's turn")
	computerMove(board, computer_input, player_input)
	printBoard()
	checkBoard(board, computer_input)


# Python 3
#invite cool guys to the party
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# boundaries
xlim=[0, 30]
ylim=[0, 20]

# set up initial configuration of plot
fig = plt.figure()
ax = fig.add_subplot(111, autoscale_on=False, xlim=xlim, ylim=ylim)
plt.xticks([])
plt.yticks([])
ln, = plt.plot([], [], 'ro', animated=True)

# global parameters
g = 9.8 # gravity
ag = np.array([0.0, -g]) # gravity vector
delta_t = 0.05
cor = 0.95 # damping factor at each accident with walls or other balls
friction_coeff = 0.97 # coefficient of friction at bottom edge along x direction
balls = []

class Ball():
    def __init__(self, radius, center, velocity):
        self.radius = 0.5 # it is different than that the argument "radius"
        self.position = center
        self.velocity = velocity
        self.scatter, = ax.plot([], [], 'o', markersize=radius)
        balls.append(self)
        self.ball_number = len(balls)

    def update(self):
        self.velocity += ag*delta_t
        self.position += self.velocity*delta_t

        if self.position[1] < ylim[0]: # hit bottom edge
            self.velocity[1] = - cor * self.velocity[1]
        if self.position[1] > ylim[1]: # hit top edge
            self.velocity[1] = - cor * self.velocity[1]
        if self.position[0] > xlim[1]: # hit right edge
            self.velocity[0] = - cor * self.velocity[0]
        if self.position[0] < xlim[0]: # hit left edge
            self.velocity[0] = - cor * self.velocity[0]

        # if ball is stuck at bottom edge apply friction
        if (self.position[1] < 0.2) and (self.velocity[1] < 1):
            self.velocity[0] = friction_coeff * self.velocity[0]

        # check if balls hit each other
        for ball in balls:
            if (ball.ball_number != self.ball_number)and (np.sqrt((ball.position[0]-self.position[0])**2 + (ball.position[1]-self.position[1])**2) < (ball.radius + self.radius)):
                self.velocity[0] = - cor * self.velocity[0]

        # clip position to make sure ball is within the boundaries
        self.position[0] = np.clip(self.position[0], xlim[0], xlim[1])
        self.position[1] = np.clip(self.position[1], ylim[0], ylim[1])

        self.scatter.set_data(self.position)

b1 = Ball(15.0, np.array([3., 18.]), np.array([1., 0.]))
b2 = Ball(9., np.array([28., 15.]), np.array([1.5, -20.]))
b3 = Ball(12., [5., 5.], [5., 5.])
b4 = Ball(14., [5., 15.], [5., -5.])

def init():
    return []

def animate(t):
    for ball in balls:
        ball.update()
    return [ball.scatter for ball in balls]

ani = animation.FuncAnimation(fig, animate, np.arange(0,100,delta_t), init_func=init, interval=10, blit=True)

plt.show()