# -*- coding: utf-8 -*-
"""
@Time    : 2018/8/15 下午5:07
@Author  : libing
@Email   : icearl@qq.com
@File    : 57_二叉树的下一个节点.py
@Software: PyCharm
"""

"""书：8
题：
给定一个二叉树和其中的一个结点，请找出中序遍历顺序的下一个结点并且返回。
注意，树中的结点不仅包含左右子结点，同时包含指向父结点的指针。
"""

"""
1、 先找右节点，有的话，找到右节点最左边的那个
2、 找父节点
    1、 如果是父节点的左儿子，直接返回父亲节点
    2、 若为右儿子，一直往上找，知道找到是父亲的左儿子的那个节点，返回之
"""

# -*- coding:utf-8 -*-
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None #.next属性代表当前节点的父节点
class Solution:
    def GetNext(self, pNode):
        # write code here
        if not pNode:
            return pNode
        if pNode.right is not None:
            left1 = pNode.right
            while left1.left is not None:
                left1 = left1.left
            return left1
        while pNode.next is not None:  # pNode节点的父节点
            tmp = pNode.next
            if tmp.left == pNode:
                return tmp
            pNode = tmp

57_二叉树的下一个节点.py


#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you 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.

import os
import random
from collections import namedtuple
from typing import Tuple, List, Dict

import numpy as np
from spacy.gold import GoldParse
from spacy.lang.fr import French
from spacy.scorer import Scorer
from spacy.util import minibatch, compounding
from tqdm import tqdm

from ner.model_factory import get_empty_model, entity_types
from resources.config_provider import get_config_default

Offset = namedtuple('Offset', ['start', 'end', 'type'])

def parse_offsets(text: str) -> Offset:
    """
    Convert to the right offset format
    :param text: original line
    :return: a tuple containing the offset
    """
    item = text.split(' ')
    return Offset(int(item[0]), int(item[1]), item[2])

def extract_offsets(text: str, offsets: List[Offset]) -> List[str]:
    """
    Extract a span from a line according to provided offsets
    :param text: original text
    :param offsets: list of tuples containing the positional information and a class of entity
    :return: a list of tokens
    """
    return [text[offset.start:offset.end] for offset in offsets]

def convert_offset_to_words(line: str, offsets: List[Offset], selected_type: str) -> List[str]:
    """
    Convert offsets to word tokens
    :param line: original string
    :param offsets: list of offsets
    :param selected_type: the offset type to keep for this extraction
    :return: a list of words
    """
    offset = [item for item in offsets if item.type == selected_type]
    tokens = extract_offsets(text=line, offsets=offset)
    words = [token.split(" ") for token in tokens]
    words = [word for sublist in words for word in sublist]
    return words

def spacy_evaluate(model, samples: List[Tuple[str, List[Offset]]]) -> Dict[str, float]:
    """
    Compute entity global scores according to Spacy
    :param model: Spacy NER model
    :param samples: list of tuples containgin the filename, the text, and the offsets
    :return: a dict of scores
    """
    scorer = Scorer()
    for input_, annot in samples:
        doc_gold_text = model.make_doc(input_)
        gold = GoldParse(doc_gold_text, entities=annot)
        pred_value = model(input_)
        scorer.score(pred_value, gold)
    return scorer.scores

def eval(model: French, classes: List[str], content: List[Tuple[str, List[Offset]]]):
    scores = {}
    with tqdm(total=len(content), unit=" samples", desc="compute score") as progress_bar:
        for current_line, gold_offsets in content:
            spacy_offsets: List[Offset] = [Offset(ent.start_char, ent.end_char, ent.label_) for ent in
                                           model(current_line).ents]
            for entity_type in classes:
                # predictions from Spacy
                pred_words = convert_offset_to_words(line=current_line,
                                                     offsets=spacy_offsets,
                                                     selected_type=entity_type)
                # manual annotations
                gold_words = convert_offset_to_words(line=current_line,
                                                     offsets=gold_offsets,
                                                     selected_type=entity_type)
                if len(gold_words) > 0:
                    score = len(set(gold_words).intersection(set(pred_words))) / len(set(gold_words))
                    current_scores: List[float] = scores.get(entity_type, [])
                    current_scores.append(score)
                    scores[entity_type] = current_scores
                    # if score != 1:
                    #     print(token_type, ":", pred_tokens, "VS", gold_tokens)
            progress_bar.update()

    for entity_type in classes:
        if (entity_type in scores) and (len(scores[entity_type]) > 0):
            print(entity_type, np.round(100 * np.mean(scores[entity_type]), 2), "%\tnb samples",
                  len(scores[entity_type]))

def load_content(paths) -> List[Tuple[str, List[Offset]]]:
    results: List[Tuple[str, List[Offset]]] = []
    for file_path in paths:
        file_path = os.path.join(eval_dataset_path, file_path)
        if file_path.endswith('.txt'):
            with open(file_path, 'r') as f:
                content_case = [item.strip() for item in f.readlines()]
            path_annotations = file_path.replace('.txt', '.ent')
            with open(path_annotations, 'r') as f:
                annotations = [item.strip() for item in f.readlines()]

            assert len(content_case) > 0
            assert len(content_case) == len(annotations)

            for line_case, line_annotations in zip(content_case, annotations):
                gold_offsets = [parse_offsets(item) for item in line_annotations.split(',') if item != ""]
                if len(gold_offsets) > 0:
                    results.append((line_case, gold_offsets))
    return results

config_training = get_config_default()
eval_dataset_path = config_training["eval_path"]
ner_model = get_empty_model(load_labels_for_training=False)
ner_model = ner_model.from_disk(config_training["model_dir_path"])

file_paths = os.listdir(eval_dataset_path)
content_to_rate: List[Tuple[str, List[Offset]]] = load_content(file_paths[:-20])
content_to_rate_test = load_content(file_paths[-20:])

eval(model=ner_model, classes=entity_types, content=content_to_rate_test)

# results = spacy_evaluate(ner_model, content_to_rate)
# print(results)

print("nb entities", sum([len(item) for item in content_to_rate]))

train_data = [(current_line, GoldParse(ner_model.make_doc(current_line), entities=gold_offsets)) for current_line, gold_offsets in content_to_rate]

with tqdm(total=30, unit=" epoch", desc="update model") as progress_bar:
    for itn in range(30):
        random.shuffle(train_data)
        losses = dict()
        batches = minibatch(train_data, size=compounding(4.0, 32.0, 1.001))
        for batch in batches:
            texts, annotations = zip(*batch)
            ner_model.update(
                texts,
                annotations,
                drop=0.5,
                losses=losses
            )
        progress_bar.update()

eval(model=ner_model, classes=entity_types, content=content_to_rate_test)


import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib import rc
rc('text', usetex=True)
import pickle

label_map = {"naive" : "naive", \
			"glasso" : "glasso", \
			"scio" : "scio", \
			"clime" : "clime", \
			"OR" : "FMPL", \
			"random": "random"}

color_map = {"naive" : "b", \
			"glasso" : "r", \
			"scio" : "m", \
			"clime" : "k", \
			"OR" : "c", \
			"random" : "g"}

def get_data(method, dir_name):
	f = open(dir_name + '/' + method, 'r')
	data = pickle.load(f)
	f.close()
	return data

def get_data_param(method, dir_name):
	return get_data(method, dir_name)[1]

def save_data(data, method, dir_name):
	f = open(dir_name + '/' + method, 'w')
	pickle.dump(data, f)
	f.close()

def save_figure(fig, name):
	figure_name = "../figures/" + name + ".pdf"
	pd = PdfPages(figure_name)
	pd.savefig(fig)
	pd.close()

def make_figuree(data_set, xs, ys, x_variable_name = None, y_variable_name = None, figure_title = "test_figure", dim = 144):
	if (x_variable_name == None):
		x_variable_name = xs
	if (y_variable_name == None):
		y_variable_name = ys
	fig = plt.figure()
	plt.title(figure_title)
	fontsize = 20
	plt.xlabel(x_variable_name, fontsize = fontsize)
	plt.ylabel(y_variable_name, fontsize = fontsize)
	outdims = []
	indims = []
	if (y_variable_name == "hamming distance"):
		ax = plt.subplot(111)
		if (xs == "outdim"):
			plt.ylabel("hamming distance $/ d_2$")
			for method in data_set:
				outdims = data_set[method][xs]
		if (xs == "indim"):
			plt.ylabel("hamming distance")
			for method in data_set:
				indims = data_set[method][xs]
	for method in data_set:
		yy = data_set[method][ys]
		if (xs == "outdim"):
			yy = [1.0*yyy/dim for yyy, dim in zip(yy, outdims)]
		m = len(data_set[method][xs])
		x = range(m)
		curve_label = label_map[method]
		curve_color = color_map[method]
		plt.plot(x, yy, label = curve_label, color=curve_color)
		plt.xticks(x, data_set[method][xs])
	plt.legend()
	if ((y_variable_name == "hamming distance") and (xs == "noise_stds")):
		plt.gca().set_ylim([0, 35])
	return fig


import json
from datetime import datetime
import requests
import pytz
#test for merging branch

class ApiError(Exception):

    def __init__(self, url, status):
        self.url = url
        self.status = status

    def __str__(self):
        return "<{}> {}".format(self.status, self.url)

class Api:

    BASE_URL = 'https://api.genability.com/rest'
    HEADER = {
        'Content-Type': 'application/json'
    }

    DURATIONS = {
        'HOUR': 60*60*1000,
        'QTR_HOUR': 15*60*1000
    }

    UNITS = {
        'consumption': 'kWh',
        'demand': 'kW'
    }

    def __init__(self, app_id, app_key):
        self.app_id = app_id
        self.app_key = app_key
        self.now = datetime.utcnow().replace(tzinfo=pytz.utc)

    def get_calc_request_template_for(self, mtid, property_data, profile, profile_duration, profile_type, from_datetime, to_datetime):
        """
        mtid: Master Tariff Id to use for the calc
        property_data: An array of additional properties to set for the calc with each element
                       being at 2-item tuple or array of [key, value].
        profile: Annual profile. Currently `duration` set to 15m interval data. To use hourly (8760)
                 instead, change `duration` to 60*60*1000.
        profile_duration: HOUR or QTR_HOUR. The interval between points in the profile.
        profile_type: 'consumption' or 'demand'.
        from_datetime: Start datetime of the calc. Should align with the start of the profile.
        to_datetime: End datetime of the calc.
        """

        request_template = {
            'masterTariffId': mtid,
            'detailLevel': 'CHARGE_TYPE',
            'groupBy': 'MONTH',
            'fromDateTime': from_datetime,
            'toDateTime': to_datetime,
            'propertyInputs': [
                {
                    'keyName': profile_type,
                    'unit': Api.UNITS[profile_type],
                    'dataSeries': profile,
                    'duration': Api.DURATIONS[profile_duration],
                    'fromDateTime': from_datetime
                }
            ]
        }

        for pd in property_data:
            request_template['propertyInputs'].append(
                {
                    'keyName': pd[0],
                    'dataValue': pd[1]
                }
            )

        return request_template

    def calc(self, request):
        resp = requests.post(
            '{}/v1/ondemand/calculate'.format(Api.BASE_URL),
            headers=Api.HEADER,
            json=request,
            auth=(self.app_id, self.app_key)
        )

        if resp.status_code != 200:
            with open('bad_request.json', 'w') as fp:
                json.dump(request, fp)
            with open('bad_response.json', 'w') as fp:
                json.dump(resp.json(), fp)
            # raise ApiError(resp.request.url, resp.status_code)

        return resp.json(), resp

    def tariff(self, mtid, **kwargs):
        resp = requests.get(
            '{}/public/tariffs/{}'.format(Api.BASE_URL, mtid),
            headers=Api.HEADER,
            params=kwargs,
            auth=(self.app_id, self.app_key)
        )

        # if resp.status_code != 200:
            # raise ApiError(resp.request.url, resp.status_code)

        return resp.json()['results'][0], resp


import cv2
import os
import numpy as np
from PIL import Image
import pickle
import argparse

# handle command-line arguments
ap = argparse.ArgumentParser()
ap.add_argument('-f', '--folder', help='path to folder dataset')
args = ap.parse_args()
name_folder = args.folder

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
image_dir = os.path.join(BASE_DIR, name_folder)

face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_alt2.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()

current_id = 0
label_ids = {}
y_labels = []
x_train = []

for root, dirs, files in os.walk(image_dir):
    for file in files:
        if file.endswith("png") or file.endswith("jpg"):
            path = os.path.join(root, file)
            label = os.path.basename(root).replace(" ", "-").lower()
            if not label in label_ids:
                label_ids[label] = current_id
                current_id += 1
            id_ = label_ids[label]
            pil_image = Image.open(path).convert("L")
            image_array = np.array(pil_image, "uint8")
            faces = face_cascade.detectMultiScale(image_array, scaleFactor=1.5, minNeighbors=5)
            for (x,y,w,h) in faces:
                roi = image_array[y:y+h, x:x+w]
                x_train.append(roi)
                y_labels.append(id_)
with open("pickles/face-labels.pickle", 'wb') as f: # Đánh chỉ mục dữ liệu đặc trưng
    pickle.dump(label_ids, f)

recognizer.train(x_train, np.array(y_labels))
recognizer.write("trainner-face/trainner_frontalface_alt2.yml")
print("__Finish__")


import sys
from PyQt5.QtWidgets import *
import win32com.client
import ctypes

import pandas as pd
import os

################################################
# PLUS 공통 OBJECT
g_objCodeMgr = win32com.client.Dispatch('CpUtil.CpCodeMgr')
g_objCpStatus = win32com.client.Dispatch('CpUtil.CpCybos')
g_objCpTrade = win32com.client.Dispatch('CpTrade.CpTdUtil')

################################################
# PLUS 실행 기본 체크 함수
def InitPlusCheck():
    # 프로세스가 관리자 권한으로 실행 여부
    if ctypes.windll.shell32.IsUserAnAdmin():
        print('정상: 관리자권한으로 실행된 프로세스입니다.')
    else:
        print('오류: 일반권한으로 실행됨. 관리자 권한으로 실행해 주세요')
        return False

    # 연결 여부 체크
    if (g_objCpStatus.IsConnect == 0):
        print("PLUS가 정상적으로 연결되지 않음. ")
        return False

    # # 주문 관련 초기화 - 계좌 관련 코드가 있을 때만 사용
    # if (g_objCpTrade.TradeInit(0) != 0):
    #     print("주문 초기화 실패")
    #     return False

    return True

class CpMarketEye:
    def __init__(self):
        self.objRq = win32com.client.Dispatch("CpSysDib.MarketEye")
        self.RpFiledIndex = 0

    def Request(self, codes, dataInfo):
        # 0: 종목코드 4: 현재가 20: 상장주식수
        # 21: 외국인 보유 비율 10: 거래량 67:per 92:매출액영업이익률
        rqField = [0, 4, 20, 21, 10, 67, 92]  # 요청 필드

        self.objRq.SetInputValue(0, rqField)  # 요청 필드
        self.objRq.SetInputValue(1, codes)  # 종목코드 or 종목코드 리스트
        self.objRq.BlockRequest()

        # 현재가 통신 및 통신 에러 처리
        rqStatus = self.objRq.GetDibStatus()
        print("통신상태", rqStatus, self.objRq.GetDibMsg1())
        if rqStatus != 0:
            return False

        cnt = self.objRq.GetHeaderValue(2)

        for i in range(cnt):
            code = self.objRq.GetDataValue(0, i)  # 코드
            cur = self.objRq.GetDataValue(1, i)  # 현재가
            listedStock = self.objRq.GetDataValue(2, i)  # 상장주식수
            foreign_rate = self.objRq.GetDataValue(3,i) #외국인 보유 비율
            trading_volume = self.objRq.GetDataValue(4,i) # 거래량
            per = self.objRq.GetDataValue(5,i) # per
            ratio_gain = self.objRq.GetDataValue(6,i) #영업이익률

            maketAmt = listedStock * cur
            if g_objCodeMgr.IsBigListingStock(code):
                maketAmt *= 1000
            #            print(code, maketAmt)

            # key(종목코드) = tuple(상장주식수, 시가총액,외국인 보유비율, 거래량,per,영업이익률)
            dataInfo[code] = (cur,listedStock, maketAmt,foreign_rate,trading_volume,per,ratio_gain)

        return True

class top_10_calculate():
    def __init__(self):
        self.dataInfo = {}

    def GetAllMarketTotal(self):
        codeList = g_objCodeMgr.GetStockListByMarket(1)  # 거래소
        codeList2 = g_objCodeMgr.GetStockListByMarket(2)  # 코스닥
        allcodelist = codeList + codeList2
        print('전 종목 코드 %d, 거래소 %d, 코스닥 %d' % (len(allcodelist), len(codeList), len(codeList2)))

        objMarket = CpMarketEye()
        rqCodeList = []
        for i, code in enumerate(allcodelist):
            rqCodeList.append(code)
            if len(rqCodeList) == 200:
                objMarket.Request(rqCodeList, self.dataInfo)
                rqCodeList = []
                continue
        # end of for

        if len(rqCodeList) > 0:
            objMarket.Request(rqCodeList, self.dataInfo)

    #시가총액 상위 10
    def Market_TOP10(self):

        #시가총액 순으로 sorting
        data2 = sorted(self.dataInfo.items(), key=lambda x: x[1][2], reverse=True)

        top_10_data = []
        count = 0

        for item in data2:

            if (count == 10) : break
            name = g_objCodeMgr.CodeToName(item[0])
            cur = item[1][0]
            listed = item[1][1]
            markettot = item[1][2]

            dic = {}
            dic['이름'] = name
            dic['현재가'] = cur
            dic['상장주식수'] = listed
            dic['시가총액'] = markettot

            top_10_data.append(dic)
            count += 1
        return top_10_data

    #외국인 보유비율 top 10
    def Foreign_TOP10(self):

        data2 = sorted(self.dataInfo.items(), key=lambda x: x[1][4], reverse=True)

        top_10_data = []
        count = 0

        for item in data2:

            if (count == 10): break
            name = g_objCodeMgr.CodeToName(item[0])
            cur = item[1][0]
            foreign = item[1][4]

            dic = {}
            dic['이름'] = name
            dic['현재가'] = cur
            dic['외국인보유비율'] = foreign

            top_10_data.append(dic)
            count += 1
        return top_10_data

    #영업이익률 top 10

    def Gain_TOP10(self):

        data2 = sorted(self.dataInfo.items(), key=lambda x: x[1][6], reverse=True)

        top_10_data = []
        count = 0

        for item in data2:

            if (count == 10): break
            name = g_objCodeMgr.CodeToName(item[0])
            cur = item[1][0]
            gain = item[1][6]

            dic = {}
            dic['이름'] = name
            dic['현재가'] = cur
            dic['영업이익률'] = gain

            top_10_data.append(dic)
            count += 1
        return top_10_data

    # def expectation(self):
    #     data2 = self.dataInfo.items()
    #
    #
    #
    #     expectation_data= []
    #
    #     for item in data2:
    #
    #         instStockChart = win32com.client.Dispatch("CpSysDib.StockChart")
    #         instStockChart.SetInputValue(0, item[0])
    #         instStockChart.SetInputValue(1, ord('2'))
    #         instStockChart.SetInputValue(4, 60) #최근 60일
    #         instStockChart.SetInputValue(5, 8)
    #         instStockChart.SetInputValue(6, ord('D'))
    #         instStockChart.SetInputValue(9, ord('1'))
    #
    #         instStockChart.BlockRequest()
    #
    #         volumes = []
    #         numData = instStockChart.GetHeaderValue(3)
    #         for i in range(numData):
    #             volume = instStockChart.GetDataValue(0, i)
    #             volumes.append(volume)
    #
    #         averageVolume = (sum(volumes) - volumes[0]) / (len(volumes) - 1)
    #
    #         if(averageVolume != 0):
    #             temp = {}
    #             temp['이름'] = g_objCodeMgr.CodeToName(item[0])
    #             check = volumes[0] / averageVolume
    #             temp['유망종목 수치'] = check
    #
    #             expectation_data.append(temp)
    #         else: continue
    #
    #     return expectation_data

if __name__ == "__main__":

    # 시가총액 top 10
    objMarketTotal = top_10_calculate()
    objMarketTotal.GetAllMarketTotal()
    top_10 = objMarketTotal.Market_TOP10() #시가총액 상위 10개의 기업 리스트 출력 (각 리스트에는 이름, 상장주식수, 시가총액)

    print(top_10)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from catalog_database_setup import Base, Category, Item, User
from random import randint

engine = create_engine('sqlite:///catalog.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()

user = User(email = "chris22931@gmail.com")
session.add(user)
category = Category(name="Apps & Games")
session.add(category)
item = Item(
    name="Tetris",
    description="Description of Tetris",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Minecraft",
    description="Description of Minecraft",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Hungry Shark Evolution",
    description="Description of Hungry Shark Evolution",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Portal",
    description="Description of Portal",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Dota 2",
    description="Description of Dota 2",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="BioShock",
    description="Description of BioShock",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Starcraft",
    description="Description of Starcraft",
    category=category,
    owner=user)
session.add(item)

category = Category(name="Beauty")
session.add(category)
item = Item(
    name="Peel Gel",
    description="Description of Peel Gel",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Sunscreen",
    description="Description of Sunscreen",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Lip Stick",
    description="Description of Lip stick",
    category=category,
    owner=user)
session.add(item)

category = Category(name="Books")
session.add(category)
item = Item(
    name="Chains of Command",
    description="The assault on Earth was thwarted by the destruction of the "
    "aliens seed ship, but with Mars still under Lanky control, survivors work "
    "frantically to rebuild fighting capacity and shore up planetary defenses. "
    "Platoon sergeant Andrew Grayson must crash-course train new volunteers "
    "all while dulling his searing memories of battle with alcohol and meds.",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Wayward",
    description="Welcome to Wayward Pines, population 461. Nestled amid "
    "picture-perfect mountains, the idyllic town is a modern-day Eden... "
    "except for the electrified fence and razor wire, snipers scoping "
    "everything, and the relentless surveillance tracking each word "
    "and gesture.",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="The Hidden Relic",
    description="With the fate of their homeland still in jeopardy, siblings "
    "Ella and Miro must face the Primates evil as he discovers a new "
    "technique: a method to extract essence from human blood.",
    category=category,
    owner=user)
session.add(item)

category = Category(name="Sports & Outdoors")
session.add(category)
item = Item(
    name="Ball",
    description="Not just a normal ball!",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Snowboard",
    description="Really cool Snowboard.",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Skateboard",
    description="Skateboard from the Tony Hawk Edition.",
    category=category,
    owner=user)
session.add(item)

category = Category(name="DVD & Blu-ray")
session.add(category)
item = Item(
    name="The Shawshank Redemption",
    description="Two imprisoned men bond over a number of years, "
    "finding solace and eventual redemption through acts of common decency.",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="The Godfather",
    description="The aging patriarch of an organized crime dynasty transfers "
    "control of his clandestine empire to his reluctant son.",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="The Dark Knight",
    description="When the menace known as the Joker emerges from his "
    "mysterious past, he wreaks havoc and chaos on the people of Gotham, "
    "the Dark Knight must accept one of the greatest psychological "
    "and physical tests of his ability to fight injustice..",
    category=category,
    owner=user)
session.add(item)

category = Category(name="Watches")
session.add(category)
item = Item(
    name="Ice Watch",
    description="Description of Ice Watch",
    category=category,
    owner=user)
session.add(item)
item = Item(
    name="Casio Digital Watch",
    description="Description of Casio Digital Watch",
    category=category,
    owner=user)
session.add(item)

session.commit()


'''
684: Redundant Connection
'''
from collections import defaultdict
# Graph question , detect a cycle in the graph first
class Solution(object):
    """docstring for Solution."""
    def __init__(self):
        super(Solution, self).__init__()

    def findRedundantConnection(self,edges):
        #(u,v) , u<v
        self.indices={}
        self.g = defaultdict(set)
        for i,x in enumerate(edges):
            self.g[x[0]].add(x[1])
            self.g[x[1]].add(x[0])
            self.indices[(x[0],x[1])] = self.indices[(x[1],x[0])] = i # where the edges occur in edges
        self.path = {x:0 for x in self.g}
        return self.dfs(list(self.g.keys())[0])

        # for x in edges[::-1]:
        #     if x in l2:
        #         return x

    def dfs(self, node):
        for w in self.g[node]:
            if self.path[node]==w:
                continue
            if self.path[w]!=0: #cycle is found
                self.path[w]=node #complete the cycle
                return self.result(w)

            self.path[w]=node
            temp=self.dfs(w)
            if temp:
                return temp
            self.path[w]=0

    def result(self, w):
        prev, curr = w, self.path[w]
        M = self.indices[(curr, prev)] # Find all the cycle edges and get max M
        while curr!=w:
            prev, curr = curr, self.path[curr]
            M=max(M,self.indices[(curr, prev)])
        return edges[M]

obj = Solution()
edges = [[1,2],[1,3],[2,3]]
print(obj.findRedundantConnection(edges))


#! python3

"""this is 8comic module for comiccrawler.

"""

import re
import comiccrawler
from safeprint import safeprint

header = {}
domain = ["www.8comic.com", "www.comicvip.com"]
name = "無限"

def gettitle(html, **kw):
	return re.search("(.+?)",html).group(1)

def getepisodelist(html, **kw):
	html = html.replace("\n","")
	ms = re.findall("(.+?)", html, re.M)
	# safeprint(ms)
	s = []
	for m in ms:
		url, catid, title = m

		# tag cleanup
		title = title.strip()
		title = re.sub("","",title)
		title = re.sub("<.+?>","",title)

		catid = int(catid)

		if catid in (3,8,10,11,13,14,15,16,18,20):
			base = "http://new.comicvip.com/show/best-manga-"
		else:
			base = "http://new.comicvip.com/show/cool-"

		# I really don't know what is this
		# base = "/view/"

		url = url.replace(".html", "").replace("-", ".html?ch=")

		e = comiccrawler.Episode()
		e.title = title
		e.firstpageurl = base + url
		s.append(e)
	return s

def getimgurls(html, url="", page=0):
	m = re.search("ch=(\d+)", url)
	if m is None:
		ch = "1"
	else:
		ch = m.group(1)

	try:
		# before 2014/4/6
		chs = re.search("chs=(.+?);", html).group(1)
		itemid = re.search("itemid=(.+?);", html).group(1)
		allcodes = re.search("allcodes=\"(.+?)\"", html).group(1)

		cs = allcodes.split("|")
		code = ""

		for c in cs:
			if c.split(" ")[0] == ch:
				code = c
				break
		else:
			raise Exception("can't retrieve imgurl")

		num, sid, did, pages, code = code.split(" ")
		s = []
		for p in range(1, int(pages)+1):
			hash = (((p - 1) // 10) % 10) + (((p - 1) % 10) * 3)
			s.append("http://img" + sid + ".8comic.com/" + did + "/" + itemid + "/"
					+ num + "/" + "{:03}_{}".format(p, code[hash:hash+3]) + ".jpg")
		return s
	except Exception:
		pass

	# after 2014/4/6
	def ss(str):
		return re.sub("[a-z]+", "", str)

	cs = re.search("cs='(.+)'", html).group(1)
	ti = re.search("ti=(\d+);", html).group(1)

	i = 0
	while i < len(cs):
		if ch == ss(cs[i:i+4]):
			code = cs[i:i+50]
			break
		i += 50
	else:
		code = cs[-50:]

	pages = int(ss(code[7:10]))

	s = []
	for p in range(1, pages + 1):
		hash = (((p - 1) // 10) % 10) + (((p - 1) % 10) * 3)
		src = "http://img{}.8comic.com/{}/{}/{}/{:03}_{}.jpg".format(
				ss(code[4:6]), code[6:7], ti, ch, p, code[hash + 10:hash + 13])
		s.append(src)
	return s

def errorhandler(er, ep):
	pass

def getnextpageurl(pagenumber, html):
	pass


# import glob
import os
import re
import rarfile
import shutil
import glob
from javcore import common
from javcore import data
from javcore import db
from javcore import site
from send2trash import send2trash

class ImportRegisterBj:

    def __init__(self):

        # rarfile.DEFAULT_CHARSET = "windows-1252"
        # rarfile.UNRAR_TOOL = 'unrar'
        rarfile.UNRAR_TOOL = r'C:\\Program Files (x86)\\UnrarDLL\\Examples\\MASM\\unrar'
        # rarfile.UNRAR_TOOL = r'C:\\SHARE\\unrar.exe'
        self.movie_extension = '.*\.avi$|.*\.wmv$|.*\.mpg$|.*ts$|.*divx$|.*mp4$' \
                               '|.*asf$|.*mkv$|.*rm$|.*rmvb$|.*m4v$|.*3gp$|.*flv'

        self.register_path = "D:\DATA\Downloads\TEMP"
        if not os.path.exists(self.register_path):
            print('not exist path store_path [' + self.register_path + ']')
            exit(-1)

        self.store_path = "C:\mydata\\bj-jpeg"
        if not os.path.exists(self.store_path):
            print('not exist path store_path [' + self.store_path + ']')
            exit(-1)

        self.import_dao = db.import_dao.ImportDao()
        self.bj_dao = db.bj.BjDao()
        self.wiki = site.wiki.SougouWiki()

        self.is_check = True
        # self.is_check = False
        # self.target_max = 200
        # self.__set_files()

    def arrange_execute(self):

        bjs = self.bj_dao.get_all()

        # print('count bjs [{}]'.format(len(bjs)))
        err_list = []
        target_idx = 1
        bj_parser = common.BjParser()
        idx2 = 0
        for idx, bj in enumerate(bjs):

            is_err = False
            if not bj.isSelection == 1:
                continue

            bj.parse(bj_parser)
            bj.print()

            for thumbnail_info in bj.thumbnailInfoList:
                pathname = os.path.join(self.store_path, thumbnail_info.filename)
                if not os.path.isfile(pathname):
                    err_list.append('[' + str(bj.id) + '] JPEGが存在しない [' + pathname + ']')

            rar_pathname = os.path.join(self.register_path, bj.rar_filename)
            size = 0
            if not os.path.isfile(rar_pathname):
                err_list.append('[' + str(bj.id) + '] RARが存在しない [' + rar_pathname + ']')
                is_err = True
            else:
                size = os.path.getsize(rar_pathname)
                print('  OK ' + rar_pathname)

            base_pathname = os.path.join(self.register_path, bj.basename)

            if not os.path.exists(base_pathname):
                file_list = glob.glob(os.path.join(self.register_path, bj.basename + '*'))
                is_exist = False
                for file in file_list:
                    if re.search(self.movie_extension, file, re.IGNORECASE):
                        # err_list.append('[{}] DIRなしで動画が存在する [{}] {}'.format(bj.id, base_pathname, file_list))
                        is_exist = True
                        break

                if is_exist is False:
                    err_list.append('[' + str(bj.id) + '] DIRが存在しない [' + base_pathname + ']')
                    is_err = True
            else:
                print('  OK ' + base_pathname)

            if is_err:
                continue

            for thumbnail_info in bj.thumbnailInfoList:
                src_pathname = os.path.join(self.store_path, thumbnail_info.filename)
                dest_pathname = os.path.join(self.register_path, thumbnail_info.dest_filename)
                if not self.is_check:
                    shutil.copy2(src_pathname, dest_pathname)
                else:
                    print('  {} -> {}'.format(src_pathname, dest_pathname))

            import_data = data.ImportData()
            import_data.title = bj.title
            import_data.postDate = bj.postDate
            import_data.copy_text = bj.base_filename
            import_data.productNumber = bj.basename
            import_data.kind = 5
            import_data.actress = bj.actress
            import_data.isNameOnly = True
            import_data.url = bj.url
            import_data.rating = bj.rating
            import_data.tag = bj.tag
            import_data.maker = bj.postedIn
            import_data.size = size

            if not self.is_check:
                self.import_dao.export_import(import_data)
                self.bj_dao.update_is_selection(bj.id, 9)

            if target_idx > self.target_max:
                break

            target_idx = target_idx + 1

        for err in err_list:
            print(err)

    def __get_actress(self, title, posted_in):
        actress = ''
        if '201' in title and "KOREAN BJ" in title:
            match = re.search('[A-Z ]* 201', title)
            if match:
                replace_str = match.group().replace(' 201', '')
                actress = posted_in.replace(replace_str, '').strip()
                print('    ' + replace_str + '  ' + actress)
            else:
                print('    not match')

        return actress

if __name__ == '__main__':
    importRegister = ImportRegisterBj()
    importRegister.arrange_execute()


class Age():

    def __init__(self,age):
        self.age     = age
        self.days    = 365
        self.hours   = 24
        self.minutes = 60
        self.seconds = 60

    def age_to_seconds(self):
        seconds = int(self.age) * self.days * self.hours * self.minutes * self.seconds
        return seconds


def get_products_of_all_ints_except_at_index(int_list):

    product = 1
    product_list = []

    if len(int_list) < 2:
        raise ValueError("Size Less than specified")

    for i in range(0, len(int_list)):
        product_list.append(product)
        product = product * int_list[i]

    product = 1
    for i in range(len(int_list)-1, -1, -1):
        product_list[i] = product_list[i] * product
        product = product * int_list[i]

    return product_list


from json import dumps, loads

class Product:
	def __init__(self, name, price):
		self.name = name
		self.price = price
	def to_dict(self):
		return {"name": self.name, "price": self.price}

def add_Product(name, price):
	new_product = Product(name, price)
	products.append(new_product)

def save_products(products):
	product_save_list = []
	for product in products:
		product_save_list.append(product.to_dict())
	products_file = open("products.json", "w+")
	products_file.write(dumps(product_save_list))
	products_file.close()

def load_products():
	try :
		products_file = open("products.json", "r")
	except IOError:
		return []
	products_json = products_file.read()
	product_data = loads(products_json)
	products_file.close()

	products = []
	for product in product_data:
		products.append(Product(product['name'], product['price']))
	return products

def list_products(products):
	for product in products:
		print(product.name, " Rs.", product.price)

def total_products(products):
	total = 0
	for product in products:
		total += product.price
	print("Your total cost of all the products is: "+str(total))

products = load_products()

while True:
	print("Type add to add a product.")
	print("Type quit to quit the program.")
	print("Type list to see list of all Products")
	print("Type total to see total cost of all the Products")
	command = input("Type a command: ")

	if command == 'quit':
		save_products(products)
		break

	if command == 'add':
		product_name = input("Enter a name for your Product: ")
		try :
			product_price = float(input("Enter a price for your new Product in Rs: "))
		except ValueError:
			print("Enter a valid price")
			continue
		add_Product(product_name, product_price)

	if command == 'list':
		list_products(products)

	if command == 'total':
		total_products(products)


from baseentity import BaseEntity

from svrConfig import DB_G,RedisPool_G
from datetime import datetime,timedelta

import redis,json

class HourReport(BaseEntity):
    def __init__(self,hour):
        self.hour=hour
        BaseEntity.expire_time=3600*48
        BaseEntity.__init__(self,"daily_report:%s" % hour)

    def read_from_db(self):

        if datetime.today().hour>=self.hour:
            curtime=datetime.today().replace(hour=self.hour)
        else:
            timespan=timedelta(days=1)
            curtime=(datetime.today()-timespan).replace(hour=self.hour)

        today=curtime.strftime("%Y-%m-%d %H:00:00")

        timespan=timedelta(hours=1)
        today_pre=(curtime-timespan).strftime("%Y-%m-%d %H:00:00")

        #print "Today:%s,Today_END:%s" % (today,today_pre)

        hour_report={}
        hour_report["new_user"]=0
        hour_report["active_user"]=0
        hour_report["total_impression"]=0
        hour_report["total_impression_unique"]=0
        hour_report["total_click"]=0
        hour_report["total_click_unique"]=0

        sqlres=DB_G.query("select status,count(client_id) as num,count(distinct(client_id)) as unum from ad_action_log force index(ix_AL_CAS) where create_time>='%s' and create_time<'%s' group by status" %  (today_pre,today))

        for qres in sqlres:
            if qres['status']=="19":
                hour_report["total_impression"]=qres['num']
                hour_report["total_impression_unique"]=qres['unum']
            elif qres['status']=="20":
                hour_report["total_click"]=qres['num']
                hour_report["total_click_unique"]=qres['unum']

        sqlres=DB_G.query("select count(client_id) as num from sdk2.sdk_clients where create_time>='%s' and create_time<'%s'" %  (today_pre,today))
        qres=sqlres[0]
        hour_report["new_user"]=qres['num']

        sqlres=DB_G.query("select count(distinct(client_id)) as num from ad_pull_log where cur_day='%s'" % today_pre)
        qres=sqlres[0]
        hour_report["active_user"]=qres['num']

        return hour_report

class DailyReport:
    def get(self):
        r=redis.Redis(connection_pool=RedisPool_G)
        daily_report={}
        daily_report["new_user"]=0
        daily_report["active_user"]=0
        daily_report["total_impression"]=0
        daily_report["total_impression_unique"]=0
        daily_report["total_click"]=0
        daily_report["total_click_unique"]=0

        for hour_index in xrange(datetime.today().hour):
            hour_report=HourReport(hour_index)
            daily_report["new_user"]+=hour_report.get()["new_user"]
            daily_report["active_user"]+=hour_report.get()["active_user"]
            daily_report["total_impression"]+=hour_report.get()["total_impression"]
            daily_report["total_impression_unique"]+=hour_report.get()["total_impression_unique"]
            daily_report["total_click"]+=hour_report.get()["total_click"]
            daily_report["total_click_unique"]+=hour_report.get()["total_click_unique"]

        return daily_report

class DailyReportHist:
    def get(self):
        daily_report_hist_list=[]
        r=redis.Redis(connection_pool=RedisPool_G)
        hour=datetime.today().hour

        for hour_index in reversed(xrange(12)):
            if hour-hour_index>=0:
                xhour=hour-hour_index
            else:
                xhour=hour-hour_index+24

            hour_report=HourReport(xhour).get()
            if hour_report is not None:
                daily_report_hist_list.append(hour_report)
            else:
                break

        daily_report_hist={}

        new_user_list=[]
        active_user_list=[]
        impressions_list=[]
        clicks_list=[]
        for report in daily_report_hist_list:
            new_user_list.append(report["new_user"])
            active_user_list.append(report["active_user"])
            impressions_list.append(report["total_impression"])
            clicks_list.append(report["total_click"])

        daily_report_hist["new_user"]=self.calc_hist_string(new_user_list)
        daily_report_hist["active_user"]=self.calc_hist_string(active_user_list)
        daily_report_hist["total_impression"]=self.calc_hist_string(impressions_list)
        daily_report_hist["total_click"]=self.calc_hist_string(clicks_list)

        return daily_report_hist

    def calc_hist_string(self,hist_list):
        max_val=max(hist_list)

        result_str=""

        for val in hist_list:
            if max_val==0:
                result_str="0,"
            else:
                result_str+=str(int(round(val*10/max_val)))+","

        return result_str[:-1]


'''
In this problem, a tree is an undirected graph that is connected and has no cycles.

You are given a graph that started as a tree with n nodes labeled from 1 to n, with one additional edge added. The added edge has two different vertices chosen from 1 to n, and was not an edge that already existed. The graph is represented as an array edges of length n where edges[i] = [a_i, b_i] indicates that there is an edge between nodes a_i and b_i in the graph.

Return an edge that can be removed so that the resulting graph is a tree of n nodes. If there are multiple answers, return the answer that occurs last in the input.
'''
from time import time
from typing import List

class Solution:
    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
        parent = {v: -1 for v in range(1, len(edges) + 1)}

        def find(u):
            if parent[u] != -1:
                # Find root with path compression
                parent[u] = find(parent[u])
                return parent[u]
            else:
                return u

        def union(u, v):
            parent_of_u = find(u)
            parent_of_v = find(v)

            if parent_of_u != parent_of_v:
                # After adding edge, graph is still a tree without cycle
                parent[parent_of_u] = parent_of_v
                return True
            else:
                # U and V has same parent node
                return False

        for u, v in edges:
            if not union(u, v):
                return [u, v]

    def reference(self, edges: List[List[int]]) -> List[int]:
        par = [i for i in range(len(edges) + 1)]
        rank = [1] * (len(edges) + 1)

        def find(n):
            p = par[n]
            while p != par[p]:
                par[p] = par[par[p]]
                p = par[p]
            return p

        # Return False if already unioned
        def union(n1, n2):
            p1, p2 = find(n1), find(n2)

            if p1 == p2:
                return False
            if rank[p1] > rank[p2]:
                par[p2] = p1
                rank[p1] += rank[p2]
            else:
                par[p1] = p2
                rank[p2] += rank[p1]
            return True

        for n1, n2 in edges:
            if not union(n1, n2):
                return [n1, n2]

    def quantify(self, test_cases, runs=50000):
        sol_start = time()
        for i in range(runs):
            for case in test_cases:
                if i == 0:
                    print(self.findRedundantConnection(case))
                else:
                    self.findRedundantConnection(case)
        print(f'Runtime for our solution: {time() - sol_start}\n')

        ref_start = time()
        for i in range(0, runs):
            for case in test_cases:
                if i == 0:
                    print(self.reference(case))
                else:
                    self.reference(case)
        print(f'Runtime for reference: {time() - ref_start}')

if __name__ == '__main__':
    test = Solution()
    test_cases = [
        [[1, 2], [1, 3], [2, 3]],
        [[1, 2], [2, 3], [3, 4], [1, 4], [1, 5]],
        # Additional
        [[1, 4], [3, 4], [1, 3], [1, 2], [4, 5]],  # [1, 3]
    ]
    test.quantify(test_cases)

NeetCode +75/11 - Graphs/684-redundant-connection.py


import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import pandas as pd
from sklearn.tree import DecisionTreeRegressor
from sklearn.preprocessing import StandardScaler

# importing the dataset
dataset = pd.read_csv('data\Position_Salaries.csv')
X = dataset.iloc[:, 1:2].values
y = dataset.iloc[:, 2:3].values

# feature scaling
# sc_X = StandardScaler()
# X = sc_X.fit_transform(X)
# sc_y = StandardScaler()
# y = sc_y.fit_transform(y)

# fitting SVR to the dataset
regressor = DecisionTreeRegressor(random_state=0)
regressor.fit(X, y)

# predicting the slaray for positon 6.5
# inverse transform due to feature scaling
y_pred = regressor.predict(6.5)

# visualizing the Decision Tree result
# this is a non-linear as well as non-continuos regression model
# therefore this visualization will not work
plt.scatter(X, y, color='red')
plt.plot(X, regressor.predict(X), color='blue')
plt.title('Truth or Bluff: Decision Tree')
plt.xlabel('Position')
plt.ylabel('Salary')
plt.show()

# non-continuos regression model needs to be plotted in higher
# resolution
X_grid = np.arange(min(X), max(X), 0.01)
X_grid = X_grid.reshape((len(X_grid), 1))
plt.scatter(X, y, color='red')
plt.plot(X_grid, regressor.predict(X_grid), color='blue')
plt.title('Truth or Bluff: Decision Tree')
plt.xlabel('Position')
plt.ylabel('Salary')
plt.show()


#! /usr/bin/env python
# -*- coding: utf8 -*-
"""
@author: ralf
Instalar:
pip install python-wordpress-xmlrpc
"""
# Librerias de python para wordpress
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.posts import GetPosts, NewPost
from wordpress_xmlrpc.methods.users import GetUserInfo
from wordpress_xmlrpc.methods import media, posts
# LIbrerias para hacer webscraping
import requests
import bs4 as bs
import sys
try:
    # URL sistema y credenciales de acceso
    wp = Client('http://localhost/wordpress/xmlrpc.php', 'mercadodent', 'OhL#APNmpguQb22C)E')
    # URLs a obtener data
    url_txt = ['https://www.baradent.cl/categorias/endodoncia',
    'https://www.baradent.cl/categorias/endodoncia?p=2',
    'https://www.baradent.cl/categorias/endodoncia?p=3',]
    for ss in url_txt:
        #Comenzamos a obtener los datos
        categorias = ss.split("https://www.baradent.cl/categorias/")
        r = requests.get(ss)
        soup = bs.BeautifulSoup(r.content, 'html.parser')
        divs = soup.find_all("li", class_="item")
        for item in divs:
            imagen = item.div.a.img["src"]
            nombre = item.h2.a.text
            urlorigen = item.h2.a["href"]
            url_producto = [item.h2.a["href"]]
            for link in url_producto:
                rq = requests.get(link)
                lsoup = bs.BeautifulSoup(rq.content, 'html.parser')
                detallesku = lsoup.find_all("div", class_="sku")
                descripcion = lsoup.find_all("div", class_="panel")
                for psku in detallesku:
                    sku = getattr(psku.find('span', attrs={'class': 'value'}), "text")
                    break
                for pdetalle in descripcion:
                    desc = pdetalle.div.text
                    break
            precio = getattr(item.contents[9].find('span', attrs={'class': 'price'}), "text", 0).strip()
            precio = precio.replace(".","").strip().lstrip("$")
            #Insert en el sistema wordpress
            post = WordPressPost()
            post.title = nombre.strip()
            post.content = desc.strip()
            #post.thumbnail = attachment_id
            post.post_status = 'publish'
            post.terms_names = {
                'post_tag': ['Baradent'],
                'category': ['Endodoncia']
                }
            post.custom_fields = []
            post.custom_fields.append({
                '_regular_price':precio,
                '_sku': sku.strip(),
                '_product_url':url_producto,
                '_button_text':'Baradent',
                '_price':precio
            })
            wp.call(NewPost(post))

except Exception as e:
    sys.exit(e)


import os
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

blk = mpl.patches.Rectangle((-70,-120), 140, 80, color='0.5')
blk.set_lw(0)

x = np.r_[-300:300:20]
y = np.zeros_like(x)+30.

fig = plt.figure(figsize=(6,4))
ax = fig.add_axes([0.14, 0.14, 0.8, 0.8])
ax.plot([-400, 400], [0, 0], color='k', ls='-')

ax.add_patch(blk)

ax.set_xlabel("Easting (m)")
ax.set_ylabel("Depth (m)")
ax.plot(x, y, marker='.', color='black', markersize=2, linestyle='None')
plt.xlim(-300, 300)
plt.ylim(-300, 100)
ax.set_aspect('equal')

ytick = [-300, -200, -100, 0, 100]
ax.set_yticks(ytick)

fig.canvas.draw()
fname = '../figs/ATEMlayout.eps'
plt.savefig(fname, format='eps')
os.system("open " + fname)


'''
因子：
    整数  12
         1 2 3 4 6 12
         从1开始，逐一判断
         起始值：1
         结束值：数字本身
         逐一： 累加1 拿到每个整数数字 遍历
         判断： 每个整数  因子？  12 % 每个数字
'''
# def isYinZi(num):
# #     for i in range(1,num+1):
# #         if not num % i:
# #             print(i)
# # isYinZi(12)

#  打印 n遍 helloworld
def print_fn(num):
    # print('hello world\n' * num)
    for i in range(num):
        print('hello world')
# print_fn(10)

# 输入一个整数 位数
# 判断 一个整数 是个几位数字？
# 123   3位数
#    123//10   12
#    12//10    1
#    1//10    0
#  不除 了   判断出来 3位数
def num_count(num):
    count1 = 0
    while num != 0:
        num //= 10 # 12 1 0
        count1 += 1 # 1  2  3

# num_count(123)

# 统计个数
#  字符：英文 数字 空格 其他字符
# 遍历字符串，拿到每个字符 判断类型 进行分类计数
def count_fn(s):
    al_num = 0
    num_num = 0
    space_num = 0
    other_num = 0
    for i in s:
        if i.isalpha():
            al_num += 1
        elif i.isdigit():
            num_num += 1
        elif i.isspace():
            space_num += 1
        else:
            other_num += 1
    print('该字符串为%s,其中 字母个数为%s,数字个数为%s,空格个数为%d,其他字符个数为%d' % (s,al_num,num_num,space_num,other_num))
# count_fn('123abc,.; -=+ABC')

'''
判断质数 模拟 判断数字是否为偶数
'''
# def isPrime(num):
#     ....
#     flag = True False
#     return True


def leap():
	b=int(1900)
	c=int(10**5)
	print('Please Enter a Year In Between 1900 to 10**5')
	a=int(input())
	if a<b or a>c:
		print('Year is not in list, Please Enter the year in range')
		print('To check For More Years Please Enter the year in range\n')
	elif a%4==0 or a%100==0 or a%400==0:
		print('This year is leap year')
		leap()
	else:
		print('This year is not leap year')
		leap()
leap()


from colander import null, Invalid
from deform.i18n import _
from deform.widget import AutocompleteInputWidget, SelectWidget, Widget
from deform.widget import DateTimeInputWidget as DateTimeInputWidgetBase
import json
import sys

PY3 = sys.version_info[0] == 3

if PY3:
    string_types = str
else:
    string_types = basestring  # noqa

class TypeaheadInputWidget(AutocompleteInputWidget):
    """
    Renders an ``<input type="text"/>`` widget which provides
    autocompletion via a list of values using bootstrap's typeahead plugin
    http://twitter.github.com/bootstrap/javascript.html#typeahead.

    When this option is used, the :term:`bootstrap-typeahead`
    library must be loaded into the page serving the form for
    autocompletion to have any effect.

    **Attributes/Arguments**

    size
        The size, in columns, of the text input field.  Defaults to
        ``None``, meaning that the ``size`` is not included in the
        widget output (uses browser default size).

    template
        The template name used to render the widget.  Default:
        ``typeahead_textinput``.

    readonly_template
        The template name used to render the widget in read-only mode.
        Default: ``readonly/typeahead_textinput``.

    strip
        If true, during deserialization, strip the value of leading
        and trailing whitespace (default ``True``).

    source
        A list of strings.
        Defaults to ``[]``.

    items
        The max number of items to display in the dropdown. Defaults to
        ``8``.

    """

    readonly_template = "readonly/textinput"
    size = None
    strip = True
    template = "typeahead_input"
    source = []
    items = 8

    def serialize(self, field, cstruct, readonly=False):
        if cstruct in (null, None):
            cstruct = ""
        options = dict(size=self.size, source=self.source)
        template = readonly and self.readonly_template or self.template
        return field.renderer(
            template, cstruct=cstruct, field=field, options=json.dumps(options)
        )

class DateTimeInputWidget(DateTimeInputWidgetBase):

    template = "splitted_datetimeinput"
    readonly_template = "readonly/textinput"
    requirements = ()

    def serialize(self, field, cstruct, readonly=False):
        if cstruct is null or not cstruct:
            _date = ""
            _time = ""
        else:
            if len(cstruct) == 25:  # strip timezone if it's there
                cstruct = cstruct[:-6]
            try:
                _date, _time = cstruct.split("T")
            except ValueError:
                _date, _time = cstruct.split(" ")
        template = readonly and self.readonly_template or self.template
        return field.renderer(
            template, field=field, cstruct=cstruct, date=_date, time=_time
        )

    def deserialize(self, field, pstruct):
        if pstruct is null:
            return null
        else:
            _date = pstruct["date"].strip()
            _time = pstruct["time"].strip()

            if not _date and not _time:
                return null

            if not _date:
                raise Invalid(field.schema, _("Incomplete date"), "")

            if not _time:
                _time = "00:00:00"

            result = " ".join([_date, _time])

            return result

class ChosenSingleWidget(SelectWidget):
    template = "chosen_single"

class ChosenOptGroupWidget(SelectWidget):
    template = "chosen_optgroup"

class ChosenMultipleWidget(Widget):
    template = "chosen_multiple"
    values = ()
    size = 1

    def serialize(self, field, cstruct, readonly=False):
        if cstruct in (null, None):
            cstruct = ()
        template = readonly and self.readonly_template or self.template
        return field.renderer(template, field=field, cstruct=cstruct)

    def deserialize(self, field, pstruct):
        if pstruct is null:
            return null
        if isinstance(pstruct, string_types):
            return (pstruct,)
        return tuple(pstruct)


import wx

class DisplayPanel(wx.Panel):

    #---------------------------------------------------------------------------
    def __init__(self, parent):
        """ Constructor """
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("WHITE")
        self.WIDTH = (parent.GetSize()[0] / 3) - 10
        self.index = 0

        self.__createSizer()
        self.__createListCtrl()

        self.__addSizerContent()

        self.SetSizer(self.main_sizer)

    #---------------------------------------------------------------------------
    def __createSizer(self):
        """ Create sizer for class """
        self.main_sizer = wx.BoxSizer(wx.VERTICAL)

    #---------------------------------------------------------------------------
    def __createListCtrl(self):
        self.list_ctrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT)
        self.list_ctrl.InsertColumn(0, 'Tweeter Handler', width=self.WIDTH)
        self.list_ctrl.InsertColumn(1, 'Sentiment Score', width=self.WIDTH)
        self.list_ctrl.InsertColumn(2, 'Top Hash Tag', width=self.WIDTH)

    #---------------------------------------------------------------------------
    def __addSizerContent(self):
        """ Add objects to main sizer """
        self.main_sizer.Add(self.list_ctrl, 1, wx.EXPAND)

    #---------------------------------------------------------------------------
    def addToList(self, name, sentiment=None, hashtag=None):
        """ Add information to list control """
        if name == None:
            self.list_ctrl.InsertStringItem(self.index, "None")
        else:
            self.list_ctrl.InsertStringItem(self.index, name)
        if sentiment == None:
            self.list_ctrl.SetStringItem(self.index, 1, "N/A")
        else:
            self.list_ctrl.SetStringItem(self.index, 1, sentiment)

        if hashtag == None or hashtag == "None":
            self.list_ctrl.SetStringItem(self.index, 2, "N/A")
        else:
            self.list_ctrl.SetStringItem(self.index, 2, eval(hashtag)[0])
        self.index += 1


from API import *

### in API.py
# QUEUE       = "RANKED_SOLO_5x5"
# TIER        = "GOLD"
# DIVISION    = "III"
# PAGE        = "1"

### get league data
url = GET("kr", "lol/league/v4/entries/{queue}/{tier}/{division}?page={page}".format(tier=TIER, division=DIVISION, queue=QUEUE, page="1"), True)
res = requests.get(url)

if res.status_code == 200:
    json_data = json.loads(res.text)
    print("read successfully : {length}".format(length=len(json_data)))
    with open(FILE_NAME, 'w') as outfile:
        json.dump(json_data, outfile, indent=4)
else:
    print("error")


from rest_framework.generics import (
    ListAPIView,
    CreateAPIView,
    RetrieveAPIView,
    RetrieveUpdateAPIView,
    RetrieveDestroyAPIView,
)

from rest_framework.response import Response

from rest_framework.views import APIView

from ..models import Follow
from .serializers import FollowSerializer

class FollowerListAPIView(ListAPIView):
    serializer_class = FollowSerializer

    def get_queryset(self,*arg,**kwargs):
        user = self.kwargs['user']
        queryset = Follow.objects.filter(followed__user=user).order_by('-timestamp')
        return queryset

class FollowedListAPIView(ListAPIView):
    serializer_class = FollowSerializer

    def get_queryset(self,*arg,**kwargs):
        user = self.kwargs['user']
        queryset = Follow.objects.filter(follower__user=user).order_by('-timestamp')
        return queryset

class FollowAPIView(CreateAPIView):
    queryset = Follow.objects.all()
    serializer_class = FollowSerializer

class UnfollowAPIView(APIView):
    queryset = Follow.objects.all()
    serializer_class = FollowSerializer

    def delete(self,*args,**kwrags):
        followerUser = self.kwargs['follower']
        followedUser = self.kwargs['followed']

        Follow.objects.filter(follower__user=followerUser,followed__user=followedUser).delete()
        return Response({})

class IsFollowerAPIView(APIView):
    serializer_class = FollowSerializer

    def get(self,*args,**kwargs):
        followerUser = self.kwargs['follower']
        followedUser = self.kwargs['followed']

        isFollower = Follow.objects.filter(follower__user=followerUser,followed__user=followedUser).count() >  0
        return Response({
            "isFollower": isFollower,
        })

class IsFollowedAPIView(APIView):
    serializer_class = FollowSerializer

    def get(self,*args,**kwargs):
        followerUser = self.kwargs['follower']
        followedUser = self.kwargs['followed']

        isFollowed = Follow.objects.filter(follower__user=followerUser,followed__user=followedUser).count() >  0
        return Response({
            "isFollowed": isFollowed,
        })


import numpy as np
import insectum as im

target = im.realTask.toMin(target=lambda x: np.sum(np.square(x)), dimension=2, bounds=[-10, 10])
#target = im.binaryTask.toMin(target=lambda x: np.sum(x), dimension=100)
stop = im.stopMaxGeneration(500)
#stop = im.stopValue(0.000001, 1000)
m = im.metrics(target, stop, verbose=50)

bees = im.beesAlgorithm(metrics=m, popSize=20, plNum=10, probScout=0.01)

#bees.opPlaceProbs = im.uniformPlacesProbs
bees.opPlaceProbs = im.linearPlacesProbs(0.9)

loc = im.realMutation(im.expCool(0.1, 0.99))
glob = im.fillAttribute(im.randomRealVector(target.bounds))
#loc = im.binaryMutation(im.expCool(0.1, 0.99))
#glob = im.fillAttribute(im.randomBinaryVector())
bees.opFlight = im.beeFlight(loc, glob)

bees()
m.show(log=True)


import tkinter as tk

window = tk.Tk()
window.title('JustPython')
window.minsize(width=400, height=400)

title_label = tk.Label(master=window, text='สูตรคูณแม่')
title_label.pack()

number_input = tk.Entry(master=window)
number_input.pack()

go_button = tk.Button(master=window, text='ได้แก่')
go_button.pack()

output_label = tk.Label(master=window)
output_label.pack()


import torch
import torch.nn as nn
import pickle

class Shufflenet(nn.Module):

    def __init__(self, inp, oup, mid_channels, *, ksize, stride):
        super(Shufflenet, self).__init__()
        self.stride = stride
        assert stride in [1, 2]
        assert ksize in [3, 5, 7]

        self.base_mid_channel = mid_channels
        self.ksize = ksize
        pad = ksize // 2
        self.pad = pad
        self.inp = inp

        outputs = oup - inp

        branch_main = [
            # pw
            nn.Conv2d(inp, mid_channels, 1, 1, 0, bias=False),
            nn.BatchNorm2d(mid_channels),
            nn.ReLU(inplace=True),
            # dw
            nn.Conv2d(mid_channels, mid_channels, ksize,
                      stride, pad, groups=mid_channels, bias=False),
            nn.BatchNorm2d(mid_channels),
            # pw-linear
            nn.Conv2d(mid_channels, outputs, 1, 1, 0, bias=False),
            nn.BatchNorm2d(outputs),
            nn.ReLU(inplace=True),
        ]
        self.branch_main = nn.Sequential(*branch_main)

        if stride == 2:
            branch_proj = [
                # dw
                nn.Conv2d(
                    inp, inp, ksize, stride, pad, groups=inp, bias=False),
                nn.BatchNorm2d(inp),
                # pw-linear
                nn.Conv2d(inp, inp, 1, 1, 0, bias=False),
                nn.BatchNorm2d(inp),
                nn.ReLU(inplace=True),
            ]
            self.branch_proj = nn.Sequential(*branch_proj)

    def forward(self, old_x):
        if self.stride == 1:
            x_proj, x = channel_shuffle(old_x)
            return torch.cat((x_proj, self.branch_main(x)), 1)
        elif self.stride == 2:
            x_proj = old_x
            x = old_x
            return torch.cat((self.branch_proj(x_proj), self.branch_main(x)), 1)

class Shuffle_Xception(nn.Module):

    def __init__(self, inp, oup, mid_channels, *, stride):
        super(Shuffle_Xception, self).__init__()

        assert stride in [1, 2]

        self.base_mid_channel = mid_channels
        self.stride = stride
        self.ksize = 3
        self.pad = 1
        self.inp = inp
        outputs = oup - inp

        branch_main = [
            # dw
            nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
            nn.BatchNorm2d(inp),
            # pw
            nn.Conv2d(inp, mid_channels, 1, 1, 0, bias=False),
            nn.BatchNorm2d(mid_channels),
            nn.ReLU(inplace=True),
            # dw
            nn.Conv2d(mid_channels, mid_channels, 3,
                      1, 1, groups=mid_channels, bias=False),
            nn.BatchNorm2d(mid_channels),
            # pw
            nn.Conv2d(mid_channels, mid_channels, 1, 1, 0, bias=False),
            nn.BatchNorm2d(mid_channels),
            nn.ReLU(inplace=True),
            # dw
            nn.Conv2d(mid_channels, mid_channels, 3,
                      1, 1, groups=mid_channels, bias=False),
            nn.BatchNorm2d(mid_channels),
            # pw
            nn.Conv2d(mid_channels, outputs, 1, 1, 0, bias=False),
            nn.BatchNorm2d(outputs),
            nn.ReLU(inplace=True),
        ]

        self.branch_main = nn.Sequential(*branch_main)

        if self.stride == 2:
            branch_proj = [
                # dw
                nn.Conv2d(inp, inp, 3, stride, 1, groups=inp, bias=False),
                nn.BatchNorm2d(inp),
                # pw-linear
                nn.Conv2d(inp, inp, 1, 1, 0, bias=False),
                nn.BatchNorm2d(inp),
                nn.ReLU(inplace=True),
            ]
            self.branch_proj = nn.Sequential(*branch_proj)

    def forward(self, old_x):
        if self.stride == 1:
            x_proj, x = channel_shuffle(old_x)
            return torch.cat((x_proj, self.branch_main(x)), 1)
        elif self.stride == 2:
            x_proj = old_x
            x = old_x
            return torch.cat((self.branch_proj(x_proj), self.branch_main(x)), 1)

def channel_shuffle(x):
    batchsize, num_channels, height, width = x.data.size()
    assert (num_channels % 4 == 0)
    x = x.reshape(batchsize * num_channels // 2, 2, height * width)
    x = x.permute(1, 0, 2)
    x = x.reshape(2, -1, num_channels // 2, height, width)
    return x[0], x[1]

class ShuffleNetV2_OneShot(nn.Module):

    def __init__(self, input_size=224, n_class=1000, architecture=None, channels_scales=None):
        super(ShuffleNetV2_OneShot, self).__init__()

        assert input_size % 32 == 0
        assert architecture is not None and channels_scales is not None

        self.stage_repeats = [4, 4, 8, 4]
        self.stage_out_channels = [-1, 16, 64, 160, 320, 640, 1024]

        # building first layer
        input_channel = self.stage_out_channels[1]
        self.first_conv = nn.Sequential(
            nn.Conv2d(3, input_channel, 3, 2, 1, bias=False),
            nn.BatchNorm2d(input_channel),
            nn.ReLU(inplace=True),
        )

        self.features = []
        archIndex = 0
        for idxstage in range(len(self.stage_repeats)):
            numrepeat = self.stage_repeats[idxstage]
            output_channel = self.stage_out_channels[idxstage + 2]

            for i in range(numrepeat):
                if i == 0:
                    inp, outp, stride = input_channel, output_channel, 2
                else:
                    inp, outp, stride = input_channel // 2, output_channel, 1

                blockIndex = architecture[archIndex]
                base_mid_channels = outp // 2
                mid_channels = int(
                    base_mid_channels * channels_scales[archIndex])
                archIndex += 1
                if blockIndex == 0:
                    self.features.append(
                        Shufflenet(inp, outp, mid_channels=mid_channels, ksize=3, stride=stride))
                elif blockIndex == 1:
                    self.features.append(
                        Shufflenet(inp, outp, mid_channels=mid_channels, ksize=5, stride=stride))
                elif blockIndex == 2:
                    self.features.append(
                        Shufflenet(inp, outp, mid_channels=mid_channels, ksize=7, stride=stride))
                elif blockIndex == 3:
                    self.features.append(
                        Shuffle_Xception(inp, outp, mid_channels=mid_channels, stride=stride))
                else:
                    raise NotImplementedError
                input_channel = output_channel

        assert archIndex == len(architecture)
        self.features = nn.Sequential(*self.features)

        self.conv_last = nn.Sequential(
            nn.Conv2d(
                input_channel, self.stage_out_channels[
                    -1], 1, 1, 0, bias=False),
            nn.BatchNorm2d(self.stage_out_channels[-1]),
            nn.ReLU(inplace=True),
        )
        self.globalpool = nn.AvgPool2d(7)
        self.dropout = nn.Dropout(0.1)
        self.classifier = nn.Sequential(
            nn.Linear(self.stage_out_channels[-1], n_class, bias=False))
        self._initialize_weights()

    def forward(self, x):
        x = self.first_conv(x)
        x = self.features(x)
        x = self.conv_last(x)

        x = self.globalpool(x)

        x = self.dropout(x)
        x = x.contiguous().view(-1, self.stage_out_channels[-1])
        x = self.classifier(x)
        return x

    def _initialize_weights(self):
        for name, m in self.named_modules():
            if isinstance(m, nn.Conv2d):
                if 'first' in name:
                    nn.init.normal_(m.weight, 0, 0.01)
                else:
                    nn.init.normal_(m.weight, 0, 1.0 / m.weight.shape[1])
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0.0001)
                nn.init.constant_(m.running_mean, 0)
            elif isinstance(m, nn.BatchNorm1d):
                nn.init.constant_(m.weight, 1)
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0.0001)
                nn.init.constant_(m.running_mean, 0)
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight, 0, 0.01)
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)

def get_flops(model, input_shape=(3, 224, 224)):
    list_conv = []

    def conv_hook(self, input, output):
        batch_size, input_channels, input_height, input_width = input[0].size()
        output_channels, output_height, output_width = output[0].size()

        assert self.in_channels % self.groups == 0

        kernel_ops = self.kernel_size[0] * self.kernel_size[
            1] * (self.in_channels // self.groups)
        params = output_channels * kernel_ops
        flops = batch_size * params * output_height * output_width

        list_conv.append(flops)

    list_linear = []

    def linear_hook(self, input, output):
        batch_size = input[0].size(0) if input[0].dim() == 2 else 1

        weight_ops = self.weight.nelement()

        flops = batch_size * weight_ops
        list_linear.append(flops)

    def foo(net):
        childrens = list(net.children())
        if not childrens:
            if isinstance(net, torch.nn.Conv2d):
                net.register_forward_hook(conv_hook)
            if isinstance(net, torch.nn.Linear):
                net.register_forward_hook(linear_hook)
            return
        for c in childrens:
            foo(c)

    foo(model)
    input = torch.autograd.Variable(
        torch.rand(*input_shape).unsqueeze(0), requires_grad=True)
    out = model(input)

    total_flops = sum(sum(i) for i in [list_conv, list_linear])
    return total_flops

'''
def get_cand_flops(cand):
    model=ShuffleNetV2_OneShot(architecture=tuple(cand),channels_scales=(1.0,)*20)
    return get_flops(model)
'''

op_flops_dict = pickle.load(open('./data/op_flops_dict.pkl', 'rb'))
backbone_info = [  # inp, oup, img_h, img_w, stride
    (3,     16,     224,    224,    2),  # conv1
        (16,    64,     112,    112,    2),
        (64,    64,     56,     56,     1),
        (64,    64,     56,     56,     1),
        (64,    64,     56,     56,     1),
        (64,    160,    56,     56,     2),  # stride = 2
        (160,   160,    28,     28,     1),
        (160,   160,    28,     28,     1),
        (160,   160,    28,     28,     1),
        (160,   320,    28,     28,     2),  # stride = 2
        (320,   320,    14,     14,     1),
        (320,   320,    14,     14,     1),
        (320,   320,    14,     14,     1),
        (320,   320,    14,     14,     1),
        (320,   320,    14,     14,     1),
        (320,   320,    14,     14,     1),
        (320,   320,    14,     14,     1),
        (320,   640,    14,     14,     2),  # stride = 2
        (640,   640,    7,      7,      1),
        (640,   640,    7,      7,      1),
        (640,   640,    7,      7,      1),
        (640,   1000,   7,      7,      1),  # rest_operation
]
blocks_keys = [
    'shufflenet_3x3',
    'shufflenet_5x5',
    'shufflenet_7x7',
    'xception_3x3',
]

def get_cand_flops(cand):
    conv1_flops = op_flops_dict['conv1'][(3, 16, 224, 224, 2)]
    rest_flops = op_flops_dict['rest_operation'][(640, 1000, 7, 7, 1)]
    total_flops = conv1_flops + rest_flops
    for i in range(len(cand)):
        op_ids = cand[i]
        inp, oup, img_h, img_w, stride = backbone_info[i + 1]
        key = blocks_keys[op_ids] + '_stride_' + str(stride)
        mid = int(oup // 2)
        mid = int(mid)
        total_flops += op_flops_dict[key][
            (inp, oup, mid, img_h, img_w, stride)]
    return total_flops

def main():
    for i in range(4):
        print(i, get_cand_flops((i,) * 20))

if __name__ == '__main__':
    main()


from django.shortcuts import render
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse, HttpResponseRedirect
from datetime import datetime
from .models import Comment
from blog.models import Post

# Create your views here.

@csrf_exempt
@login_required(login_url='/auth/login')
def create_comment(request, post_id):
	args = {}
	post = Post.objects.get(pk = post_id)
	args['image'] = post.image.url
	args['name'] = post.name
	args['description'] = post.description
	args['username'] = post.owner
	if request.POST:
		text = request.POST.get('comment', '')
		if len(text) == 0:
			return render(request, 'blog/post.html', args)
		owner = request.user
		date = datetime.now()
		post = Post.objects.get(pk=post_id)
		likes = 0
		comment = Comment.objects.create(text=text, likes=likes, date=date, post=post, owner=owner)
		comment.save()
		comments = Comment.objects.all().filter(post=post)
		args['comments'] = comments
	return HttpResponseRedirect("/posts/" + str(post.id))


import numpy as np
import geral.runge

def spline_linear(x, f, x_k, x_ki):
    """Returns the linear interpolation of f(x) beteween x_k and x_ki."""
    A = (x_ki - x) / (x_ki - x_k)
    B = (x - x_k)  / (x_ki - x_k)

    return A*f(x_k) + B*f(x_ki)

def plota_spline_linear(x, f, pontos=10, legenda=None):

    z = np.empty(0)
    l = np.empty(0)

    for i in range(len(x)-1):
        z_i = np.linspace(x[i],x[i+1],pontos)[1:-1]
        l_i = spline_linear(z_i, runge, x[i], x[i+1])
        z = np.concatenate((z, z_i))
        l = np.concatenate((l, l_i))

    plotargs = {}
    if legenda is not None:
        plotargs['label'] = legenda

    return plt.plot(z, l, marker='.', linestyle='', alpha=.1, **plotargs)


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

from setuptools import setup, find_packages

with open('README.md') as f:
    readme = f.read()

with open('LICENSE') as f:
    license = f.read()

setup(
    name='simple-blockchain',
    version='0.1.1',
    description='This is a simplified model of a blockchain, which is also the technology behind the well known crypto-currency Bitcoin.',
    long_description=readme,
    author='Aleksander Sadowski',
    author_email='aleksander.sadowski@alsado.de',
    url='https://github.com/alekssadowski95/simple-blockchain',
    license=license,
    packages=find_packages(exclude=('tests', 'docs')),
    classifiers = [
        'Development Status :: 4 - Beta',
        'Intended Audience :: Education',
        'Operating System :: Microsoft :: Windows :: Windows 10',
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python :: 3'
    ]
)


#!/usr/bin/env python3
"""
A file for creating a one-hot encoding of all characters, including madd and harakat, in Tarteel's Qur'an dataset.

The output pickle file will contain an object with the one-hot encoded Qur'an, an encoding function, and a decoding
function.

Author: Hamzah Khan
Date: Jan. 12, 2019
"""

import copy
import dill as pickle
import json
import numpy as np

from argparse import ArgumentParser

parser = ArgumentParser(description='Tarteel Arabic One Hot Encoding Generator')
parser.add_argument('-i', '--input_json_path', type=str)
parser.add_argument('-o', '--output_pickle_path', type=str)
parser.add_argument('-v', '--verbose', type=bool, default=False)
args = parser.parse_args()

# Define constants.
QURAN_KEY  = "quran"
SURAHS_KEY = "surahs"
AYAHS_KEY  = "ayahs"
TEXT_KEY   = "text"

NUM_KEY       = "num"
NAME_KEY      = "name"
BISMILLAH_KEY = "bismillah"

ENCODING_MAP_KEY = "encoding_map"
DECODING_MAP_KEY = "decoding_map"
CHAR_TO_INT_MAP_KEY = "char_to_int"
INT_TO_CHAR_MAP_KEY = "int_to_char"

def create_list_of_quranic_chars(quran_obj, surahs_key=SURAHS_KEY, ayahs_key=AYAHS_KEY, text_key=TEXT_KEY):
    """
    Create a sorted list containing every character in the Qur'an text provided and return it.
    :param quran_obj: An object containing surah objects.
    :type quran_obj: object
    :param surahs_key: The key in quran_obj to the list of surah objects.
    :type surahs_key: string
    :param ayahs_key: The key in each surah object to the list of ayah objects in that surah.
    :type ayahs_key: string
    :param text_key: The key to the actual Qur'anic text in each ayah object.
    :type text_key: string
    :returns: A sorted list containing every Arabic character in the Qur'an exactly once.
    :rtype: list string
    """
    quranic_char_set = set()

    for surah_obj in quran_obj[surahs_key]:
        for ayah_obj in surah_obj[ayahs_key]:
            ayah_text = ayah_obj[text_key]

            for char in ayah_text:
                quranic_char_set.add(char)

    return sorted(list(quranic_char_set))

def create_one_hot_encoding(quranic_char_list):
    """
    Creates a one-hot encoding that associates each character in the argument list to a number and vice versa.
    :param quranic_char_list: A list of characters.
    :type quranic_char_list: list string
    :returns: A tuple containing the encoding and decoding functions for the alphabet.
    :rtype: tuple (function string => int, function int => string)
    """

    # Define an encoding of characters to integers.
    char_to_int = dict((c, i) for i, c in enumerate(quranic_char_list))
    int_to_char = dict((i, c) for i, c in enumerate(quranic_char_list))

    def encode_char_as_one_hot(string, char_to_int):
        """
        Converts a string of characters from our alphabet into a one_hot encoded string.
        """
        str_len = len(string)
        int_list = np.array([char_to_int[char] for char in string])

        one_hot_string = np.zeros((str_len, len(char_to_int)))
        one_hot_string[np.arange(str_len), int_list] = 1

        return one_hot_string

    def decode_one_hot_as_string(one_hot_string, int_to_char):
        """
        Converts a one_hot encoded numpy array back into a string of characters from our alphabet.
        """
        int_list = list(np.argmax(one_hot_string, axis=1))
        char_list = [int_to_char[integer] for integer in int_list]

        return str(char_list)

    return char_to_int, int_to_char, encode_char_as_one_hot, decode_one_hot_as_string

def generate_a_one_hot_encoded_script(quran_obj,
                                      encoding_fn,
                                      surahs_key=SURAHS_KEY,
                                      ayahs_key=AYAHS_KEY,
                                      text_key=TEXT_KEY,
                                      num_key=NUM_KEY,
                                      name_key=NAME_KEY,
                                      bismillah_key=BISMILLAH_KEY):
    """
    Translates each ayah in the given quran_obj into a vector of one-hot encoded characters using the given encoding.
    Create a sorted list containing every character in the Qur'an text provided and return it.
    :param quran_obj: An object containing surah objects.
    :type quran_obj: object
    :param quran_obj: A function that converts Arabic Qur'anic characters to a one-hot encoding.
    :type quran_obj: function (Arabic string => numpy 2darray)
    :param surahs_key: The key in quran_obj to the list of surah objects.
    :type surahs_key: string
    :param ayahs_key: The key in each surah object to the list of ayah objects in that surah.
    :type ayahs_key: string
    :param text_key: The key to the actual Qur'anic text in each ayah object.
    :type text_key: string
    :param num_key: The key in surah and ayah objects to the ordering of the surah or ayah.
    :type num_key: string
    :param name_key: The key in each surah object to the name of that surah.
    :type name_key: string
    :param bismillah_key: The key to the bismillah text in the first ayah object of each surah object.
    :type bismillah_key: string
    :returns: An object identical to the quran_obj but with one-hot encodings of all Arabic text (not names).
    :rtype: object
    """
    one_hot_quran_encoding = {}
    one_hot_quran_encoding[SURAHS_KEY] = []

    for surah_obj in quran_obj[surahs_key]:
        # Copy new surah object for one-hot Json container.
        one_hot_surah_obj            = {}
        one_hot_surah_obj[num_key]   = surah_obj[num_key]
        one_hot_surah_obj[name_key]  = surah_obj[name_key]
        one_hot_surah_obj[ayahs_key] = []

        for ayah_obj in surah_obj[ayahs_key]:
            ayah_text = ayah_obj[text_key]

            # Make new ayah object for one-hot Json container.
            one_hot_ayah_obj           = {}
            one_hot_ayah_obj[num_key]  = ayah_obj[num_key]
            one_hot_ayah_obj[text_key] = encoding_fn(ayah_text)

            if bismillah_key in ayah_obj:
                one_hot_ayah_obj[bismillah_key] = encoding_fn(ayah_obj[bismillah_key])

            one_hot_surah_obj[ayahs_key].append(one_hot_ayah_obj)
        one_hot_quran_encoding[surahs_key].append(one_hot_surah_obj)

    return one_hot_quran_encoding

def run_script(args):
    """
    Runs the script to find all characters, generate the encoding, and translate and store it in the output file.
    """
    # try:
    with open(args.input_json_path, 'rb') as quran_json_file:

        # Import json file.
        quran_obj = json.load(quran_json_file)[QURAN_KEY]
    #
    # except:
    #     print("Json file failed to open. Exiting script...")
    #     return

    # Get the list of every character in the Qur'an.
    quranic_char_list = create_list_of_quranic_chars(quran_obj)

    if args.verbose:
        print(quranic_char_list, ' has ', len(quranic_char_list), ' characters.')

    # Create the one-hot encodings.
    char_to_int_map, \
    int_to_char_map, \
    encode_char_as_one_hot, \
    decode_one_hot_as_string = create_one_hot_encoding(quranic_char_list)

    if args.verbose:
        print("encode!")
        x = encode_char_as_one_hot("".join(quranic_char_list))
        print(x)
        print("decode!")
        print(decode_one_hot_as_string(x))

    # Generate the Qur'anic text in one-hot encoding.
    one_hot_quran_encoding = generate_a_one_hot_encoded_script(
        quran_obj,
        lambda string: encode_char_as_one_hot(string, char_to_int_map))

    # Create an object with the encoding and the two functions.
    full_object = {
        QURAN_KEY: one_hot_quran_encoding,
        ENCODING_MAP_KEY: encode_char_as_one_hot,
        DECODING_MAP_KEY: decode_one_hot_as_string,
        CHAR_TO_INT_MAP_KEY: char_to_int_map,
        INT_TO_CHAR_MAP_KEY: int_to_char_map
    }

    with open(args.output_pickle_path, 'wb') as one_hot_quran_pickle_file:
        pickle.dump(full_object, one_hot_quran_pickle_file)

def load_data(pickle_file):
    """
    A sample function to demonstrate how to load the object.
    """
    try:
        with open(pickle_file, 'rb') as one_hot_pickle:
            one_hot_obj = pickle.load(one_hot_pickle)

            print('Now, we can do things with it! Keys: ', one_hot_obj.keys())

    except:
        print("Pickle file failed to open. Exiting...")
        return

if __name__ == "__main__":
    run_script(args)


import time
from crawler.models import Vendor, ListPage, Product
from crawler.tools.abstractcrawler import AbstractCrawler
from crawler.tools.banekala import filters

class BaneCrawler(AbstractCrawler):

    def __init__(self):
        super()
        self.vendor = Vendor.objects.update_or_create(
            name='banekala',
            start_url = 'http://banekala.ir/AllProducts/259/group/groupID/%D8%AA%D9%84%D9%88%DB%8C%D8%B2%DB%8C%D9%88%D9%86/?MinPrice=0&MaxPrice=36100000&TakeItems=20&Page=1&IsAvailable=true&MySortID=NewProduct&MyOrderBy=desc&',
        )
        self.driver = super.create_driver()

    def get_pagination_urls(self):
        print('<CRAWLER> - GETTING PAGINATION URLS.')
        self.driver.get(self.vendor.start_url)

        # Create pagination urls based on max page numbers
        max_pages = int(self.driver.find_element_by_css_selector('ul.pagination li:last-child a').text)
        url_pattern = 'http://banekala.ir/AllProducts/259/group/groupID/%D8%AA%D9%84%D9%88%DB%8C%D8%B2%DB%8C%D9%88%D9%86/?MinPrice=0&MaxPrice=100000000&TakeItems=20&IsAvailable=true&MySortID=NewProduct&MyOrderBy=desc&Page='
        urls = [url_pattern + str(i + 1) for i in range(0, max_pages)]

        print('<CRAWLER> - PAGINATION URLS CREATED:')
        for url in urls:
            ListPage.objects.update_or_create(url=url, vendor=self.vendor)

    def get_product_listings(self, list_page):
        page_url = list_page.url

        print('<CRAWLER> - LISTING ALL PRODUCTS IN PAGE [%s].' % page_url)
        self.driver.get(page_url)
        time.sleep(1)

        titles = self.driver.find_elements_by_css_selector('ul.list-item li.item a.grid .type')
        links = self.driver.find_elements_by_css_selector('ul.list-item li.item a.grid')
        prices = self.driver.find_elements_by_css_selector('ul.list-item li.item a.grid .pirces .price1-2')
        images = self.driver.find_elements_by_css_selector('ul.list-item li.item a.grid>img')

        print('<CRAWLER> - %d PRODUCTS FOUND IN PAGE [%s]:' % (len(titles), page_url))

        for i in range(len(links)):
            try:
                price = int(prices[i].text.split(' ')[0].replace(',', ''))
            except:
                price = 0
            title = titles[i].text
            url = links[i].get_attribute('href')
            image = images[i].get_attribute('src')

            Product.objects.update_or_create(
                title=title,
                price=price,
                vendor=self.vendor.name,
                url=url,
                image=image
            )

    def get_single_product(self, product):
        self.driver.get(product.url)
        funcs = filters.filter_funcs()
        spec = {}
        for spec_filter in funcs:
            spec.update(spec_filter(self.driver))

        product.spec = spec
        product.save()