#!/usr/bin/env python
# coding: utf-8

# In[133]:

import numpy as np
import pandas as pd
from numpy.linalg import eig
import math
from collections import Counter
import random as rd
from collections import Counter
import matplotlib.pyplot as plt
import copy
import csv

# In[80]:

def der_tanh(z):
    return (1 - (np.tanh(z)**2))

# In[30]:

def sigmoid(z):
    return 1.0 / (1.0 + np.exp(-z))

# In[5]:

def sigmoidPrime(z):
    return np.exp(-z) / ((1 + np.exp(-z)) ** 2)

# In[6]:

def softMax(Z):
    E = np.exp(Z - np.max(Z, axis = 1, keepdims=True))
    S = np.sum(E, axis = 1, keepdims= True)
    A = E/S
#     print(A)
    return A

# In[86]:

def reLu(z):
    z1 = copy.deepcopy(z)
    z1[z1 < 0] = 0
    return z1

# In[88]:

def der_reLu(z):
    z1 = copy.deepcopy(z)
    z1[z1 <= 0] = 0
    z1[z1 > 0] = 1
    return z1

# In[97]:

def createBatch(epoch):
    for i  in range(epoch):
        batchSize = 100
        start = 0
        end = batchSize
        while(end < len(training_data)):
            batch = training_data.iloc[start:end]
            output = neuralNet.forwardPropagation(batch)
            neuralNet.backwardPropagation(batch, modifiedTrainLabel[start:end,:])
            start = start + batchSize
            end = end + batchSize

# In[8]:

def modifyLabelVector(x, trainLabel):
    columns = len(np.unique(trainLabel))
    rows = x.shape[0]
    modifiedLabels = np.zeros((rows, columns))

    for i in range(rows):
        modifiedLabels[i, trainLabel[i]] = 1

    return modifiedLabels

# In[127]:

class NeuralNet:
    def __init__(self, x, y, hiddenLayers):
        self.initialLayerSize = x.shape[1]
        self.outputLayerSize = len(y.unique())

        self.hiddenLayersCount = len(hiddenLayers)

        self.Weights = [0] * (self.hiddenLayersCount + 1)
        self.Z = [0] * (self.hiddenLayersCount + 1)
        self.ActivateFunc = [0] * (self.hiddenLayersCount + 1)

        for i in range(len(hiddenLayers) + 1):
            if i == 0:
                self.Weights[i] = np.random.randn(self.initialLayerSize, hiddenLayers[0])
            elif i == self.hiddenLayersCount:
                self.Weights[i] = np.random.randn(hiddenLayers[self.hiddenLayersCount - 1], self.outputLayerSize)
            else:
                self.Weights[i] = np.random.randn(hiddenLayers[i - 1], hiddenLayers[i])

#             print("Weight ", i, " ", self.Weights[i].shape)

    def forwardPropagation(self, X):
        self.Z[0] = np.dot(X, self.Weights[0])
        self.ActivateFunc[0] = np.tanh(self.Z[0])

        for i in range(1, self.hiddenLayersCount + 1):
            self.Z[i] = np.dot(self.ActivateFunc[i - 1], self.Weights[i])
            self.ActivateFunc[i] = np.tanh(self.Z[i])

        self.sm = softMax(self.Z[self.hiddenLayersCount])
        return self.sm

    def backwardPropagation(self, X, Y):

        delta = [None] * (self.hiddenLayersCount + 1)
        dJdW = [None] * (self.hiddenLayersCount + 1)

#         print("Active Func Shape: ", self.ActivateFunc[self.hiddenLayersCount - 1].shape)
        delta[self.hiddenLayersCount] = -(Y - self.sm) * der_tanh(self.ActivateFunc[-1])
        dJdW[self.hiddenLayersCount] = np.dot(self.ActivateFunc[self.hiddenLayersCount - 1].T, delta[self.hiddenLayersCount])

#         print("dj/dw: ", self.hiddenLayersCount, " ", dJdW[self.hiddenLayersCount])

        i = self.hiddenLayersCount - 1

        while i >= 0:
            if i == 0:
                delta[i] = np.dot(delta[i + 1], self.Weights[i + 1].T) * der_tanh(self.ActivateFunc[i])
                dJdW[i] = np.dot(X.T, delta[i])
            else:
                delta[i] = np.dot(delta[i + 1], self.Weights[i + 1].T) * der_tanh(self.ActivateFunc[i])
                dJdW[i] = np.dot(self.ActivateFunc[i - 1].T, delta[i])

            i -= 1

        i = self.hiddenLayersCount
        while i >= 0 :
            self.Weights[i] = self.Weights[i] - 0.01 * dJdW[i]

#             print(self.Weights[i])
            i -= 1

    def predict(self, data):
        return self.forwardPropagation(data)

# In[10]:

data = pd.read_csv('Apparel/apparel-trainval.csv')

training_data, test_data = np.split(data, [int(0.8*len(data))])

trainLabel = training_data['label']
testLabel = test_data['label']

training_data = training_data.drop(columns='label')
test_data = test_data.drop(columns='label')

# In[11]:

training_data=training_data.astype('float64')
means = np.mean(training_data, axis = 0)
stdDev = np.std(training_data, axis = 0)
training_data = (training_data - means) / stdDev

# In[12]:

test_data=test_data.astype('float64')
testMeans = np.mean(test_data, axis = 0)
testStdDev = np.std(test_data, axis = 0)
test_data = (test_data - testMeans) / testStdDev

# In[13]:

trainLabelValues = trainLabel.values
modifiedTrainLabel = modifyLabelVector(training_data, trainLabelValues)

# In[14]:

testLabelValues = testLabel.values
modifiedTestLabel = modifyLabelVector(test_data, testLabelValues)

# In[128]:

neuralNet = NeuralNet(training_data, trainLabel, [128])
epoch = 20
epochs.append(epoch)
createBatch(epoch)

# In[77]:

activAccuracy = []

# In[129]:

prediction = neuralNet.forwardPropagation(test_data)
print(len(prediction))
correct_cnt = 0
for i in range(len(prediction)):
    temp1 = np.argmax(modifiedTestLabel[i])
    temp2 = np.argmax(prediction[i])
    if(temp1 == temp2):
        correct_cnt += 1
# accuracies.append(correct_cnt * 1.0 / len(prediction))
# epochAcc.append(correct_cnt * 1.0 / len(prediction))
print("Accuracy:", correct_cnt * 1.0 / len(prediction))

# In[85]:

activAccuracy

# # Accuracy vs Number of Hidden Layers

# In[40]:

accuracies = []
layers = []

# In[72]:

layers.append(neuralNet.hiddenLayersCount)

# In[74]:

plt.figure()
plt.plot(layers, accuracies)
plt.show()

# # Accuracy vs No. of Epochs

# In[103]:

epochs = []
epochAcc = []

# In[124]:

epochAcc

# In[125]:

plt.figure()
plt.plot(epochs, epochAcc)
plt.show()

# In[144]:

test = pd.read_csv('apparel-test.csv')

test = test.astype('float64')
means = np.mean(test, axis = 0)
stdDev = np.std(test, axis = 0)
test = (test - means) / stdDev

result = []

prediction = neuralNet.forwardPropagation(test)
for i in range(len(prediction)):
    result.append(np.argmax(prediction[i]))

np.savetxt('2018202021_prediction.csv', result, delimiter=",")


# Day 7: No Space Left On Device

import input_load as load
from typing import Tuple

def find_space(input_filepath: str) -> Tuple[int, int]:
    """Takes the filepath of a text file and reads lines from
    terminal output. Parses terminal commands and sums directories
    with a total size of at most 100000 as well as identifies size
    of smallest viable folder for deletion.

    Parameters
    ----------
    input_filepath : str
        filepath to input txt file

    Returns
    -------
    int
        sum size of folders <= 100000
    int
        size of smallest viable folder for deletion
    """
    folders = {}
    filepath = []

    # Parse Text File Identifying Terminal Output Lines
    input_file = load.txt_to_str(input_filepath)
    lines = [line for line in input_file.strip().split('\n')]
    for line in lines:
        line_data = line.strip().split()
        if line_data[1] == 'cd':
            if line_data[2] == '..':
                filepath.pop()
            else:
                filepath.append(line_data[2])
        elif line_data[1] == 'ls':
            continue
        elif line_data[0] == 'dir':
            continue
        else:
            folder_size = int(line_data[0])
            for i in range(1, len(filepath)+1):
                path = '/'.join(filepath[:i])
                if path in folders.keys():
                    size_count = {path: (folders.get(path) + folder_size)}
                    folders.update(size_count)
                else:
                    folders.setdefault(path, folder_size)

    # Disk Space
    total = 70000000
    needed = 30000000
    used = folders.get('/')
    used_target = total-needed

    # Puzzle Answers
    total_size = 0
    viable_folders = []

    for folder, size in folders.items():
        if size <= 100000:
            total_size += size
        if (used-size) <= used_target:
            viable_folders.append(size)

    smallest_viable = sorted(viable_folders)[0]

    return total_size, smallest_viable


#IMPORTS

from OSMPythonTools.nominatim import Nominatim
from OSMPythonTools.overpass import overpassQueryBuilder, Overpass

import pandas as pd
import geopandas as gpd
from shapely import wkt
from shapely.geometry import MultiPoint
from loguru import logger

#GATHERER

nominatim = Nominatim()
overpass = Overpass()

def osm_frame(osm_query, type, color):
    id = []
    geometry = []
    osm_type = []
    tags = []

    for elemento in osm_query.elements():
        id.append(elemento.id())
        geometry.append(elemento.geometry())
        osm_type.append(elemento.type())
        tags.append(elemento.tags())

    d = {'id':id, 'geometry':geometry, 'type':osm_type, 'tags':tags, 'type':type, 'color':color}

    df = pd.DataFrame(data = d, index = d['id'])
    return df

def get_features(area : str, keywords:dict):
    return overpass.query(overpassQueryBuilder(
        area= area,
        elementType = keywords['elementType'],
        selector=keywords['selector'],
        out='body',
        includeGeometry=True))

def download_osm_data(path: str, areas: list, categories: dict):
    data = {}
    for area_name in areas:
        logger.info(f'Downloading OSM data for {area_name}...')
        area = nominatim.query(area_name, wkt=True)
        gdf = pd.concat(
            [gpd.GeoDataFrame(
                osm_frame(
                    get_features(
                        area,
                        categories[cat]),
                    cat,
                    categories[cat]['color'])
                ) for cat in categories]
            )

        data[area_name] = gdf

    for k,v in data.items():
        outdir = f"{path}\level0"
        out_data = r"{outdir}\level0_osm_{d}.csv".format(outdir=outdir,d=k)
        logger.info(f'Saving file in {out_data}...')
        v.to_csv(out_data,sep=";", index = False)

def json_data(data: pd.DataFrame, columns: list, idx: str) -> pd.Series:
    """
    Create JSON data from a DataFrame.

    Parameters:
        data (pd.DataFrame): The DataFrame to be converted.
        columns (List[str]): The columns to include in the JSON.
        idx (str): The column to use as the JSON index.

    Returns:
        A pandas Series with the JSON data.
    """
    try:
        d = data.set_index(idx)[[c for c in columns if c in data.columns]].to_dict(orient='records')
        logger.info('Making JSON DATA columns...')
        return pd.Series(d)
    except Exception as e:
        logger.error(f"Failed to create JSON data. Error: {e}")
        return pd.Series()

def transform_osm(path: str, areas: list, provider: int):
    DATACOLS = ['type'] #,'tags','color'] TAGS NESTING IS NOT WORKING AS JSON. BEWARE
    for area_name in areas:
        logger.info(f'Reading OSM data for {area_name}...')
        df = pd.read_csv(r"{path}\level0\level0_osm_{d}.csv".format(path=path,d=area_name),sep=";")
        logger.info(f'Making columns...')
        df['geometry'] = df.geometry.apply(wkt.loads)
        df = gpd.GeoDataFrame(df, geometry='geometry')
        df['provider'] = provider
        df['category'] = 'land use'+" - "+df['type']
        df['id_class'] = 'pois'
        df['data'] = json_data(df, DATACOLS, 'id' )
        df['id'] = df['provider'].astype(str)+"-"+df['id'].astype(int).astype(str).str.strip()
        df.drop_duplicates(subset='id',inplace=True)
        df.loc[~df.geometry.geom_type.isin(['MultiPoint','Point']),'geometry'] = df['geometry'].centroid
        df = df[['id', 'id_class', 'category', 'provider', 'data','geometry']]
        out_data = r"{path}\level2\level2_osm_{d}.csv".format(path=path,d=area_name)
        logger.info(f'\nSaving LEVEL2 data for {area_name} in:\n {out_data}...')
        df.to_csv(out_data,sep=";",index=False)

def gather(source_instance, **kwargs):
    download_osm_data(path=kwargs.get('path'), areas= kwargs.get('areas'),  categories= kwargs.get('categories'))
def level0(source_instance, **kwargs):
    logger.warning('level0 is not needed in this source')
def level1(source_instance, **kwargs):
    transform_osm(path=kwargs.get('path'), areas= kwargs.get('areas'),provider=kwargs.get('provider'))


#coding=utf-8
import os
import collections

def getAllDirQU(path):
    queue = collections.deque()  # 创建一个队列
    print(queue)
    # 进队
    queue.append(path)
    print(queue)

    while len(queue) != 0:
        # 出队数据
        dirPath = queue.popleft()
        print(dirPath)
        # 找出所有的文件
        filesList = os.listdir(dirPath)

        for fileName in filesList:
            # 绝对路径
            fileAbsPath = os.path.join(dirPath, fileName)
            # 判断是否是目录，是目录就进队，不是就打印
            if os.path.isdir(fileAbsPath):
                print("Dir:", fileName)
                queue.append(fileAbsPath)
            else:
                print("File:", fileName)

path = r"E:\study\untitled\Scripts\test"
print("遍历的顶层目录 == %s" % (path))
getAllDirQU(path)

untitled/目录遍历/队列模拟递归遍历目录（广度遍历）.py

队列模拟递归遍历目录（广度遍历）.py


"""
높이를 입력받아 비 온 후 얼마나 많은 물이 쌓일 수 있는지 계산하라.

입력:
[0,1,0,2,1,0,1,3,2,1,2,1]
출력:
6
"""
from typing import List

# 투 포인터 방식 O(n), 스택 O(n) 실행 시간은 투포인터가 살짝 빠르다..
class TrappingRain:

    # 투 포인터를 활용
    def trappingRainTwoPointer(self, height: List[int]) -> int:
        # height: [] 리스트 값이 없을 경우 0을 반환한다.
        if not height:
            return 0

        volume = 0
        left, right = 0, len(height) - 1
        left_max, right_max = height[left], height[right]

        # while 종료 조건 left 포인터가 right 포인터랑 같아지거나 넘어가면 종료
        while left < right:

            # 변경되는 최대 높이를 갱신
            left_max, right_max = max(height[left], left_max), \
                                  max(height[right], right_max)

            # 더 높은 쪽을 향해 투 포인터 이동
            # 양쪽 중 낮은 높이가 더 높은 쪽을 향해 이동하면서, 높이가 줄어들면 공간이 비는 것이므로,
            # volume 에 + 하도록 left_max - height[left] 릃 해준다.
            if left_max <= right_max:
                volume += left_max - height[left]
                left += 1
            else:
                volume += right_max - height[right]
                right -= 1

            print(volume)

        return volume

    def trappingRainStack(self, height: List[int]) -> int:
        stack = []
        volume = 0

        # 스택을 쌓아가면서 풀어야 하기 때문에 최대 크기만큼 반복
        for i in range(len(height)):

            # 변곡점을 만나는 경우
            # 스택에 값이 들어있으면서 현재 높이가 stack[-1] 인덱스 보다 높으면
            while stack and height[i] > height[stack[-1]]:

                # 스택에서 꺼낸다.
                top = stack.pop()

                # 예외처리
                if not len(stack):
                    break

                # 이전과의 차이만큼 물 높이 처리
                distance = i - stack[-1] - 1
                waters = min(height[i], height[stack[-1]]) - height[top]

                volume += distance * waters

            stack.append(i)

        return volume

height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]

TrappingRain = TrappingRain()
TrappingRain.trappingRainTwoPointer(height)


"""
Nonlinear solvers to be used with model classes.
Implemented classes
    NewtonSolver
"""
import logging

import numpy as np

# ``tqdm`` is not a dependency. Up to the user to install it.
try:
    # Avoid some mypy trouble.
    from tqdm.autonotebook import trange  # type: ignore

    # Only import this if needed
    from porepy.utils.ui_and_logging import (
        logging_redirect_tqdm_with_level as logging_redirect_tqdm,
    )

except ImportError:
    _IS_TQDM_AVAILABLE: bool = False
else:
    _IS_TQDM_AVAILABLE = True

# Module-wide logger
logger = logging.getLogger(__name__)

class NewtonSolver:
    def __init__(self, params=None) -> None:
        if params is None:
            params = {}

        default_options = {
            "max_iterations": 10,
            "nl_convergence_tol": 1e-10,
            "nl_divergence_tol": 1e5,
        }
        default_options.update(params)
        self.params = default_options

        self.progress_bar: bool = params.get("progressbars", False)
        # Allow the position of the progress bar to be flexible, depending on whether
        # this is called inside a time loop, a time loop and an additional propagation
        # loop or inside a stationary problem (default).
        self.progress_bar_position: int = params.get("progress_bar_position", 0)

    def solve(self, model) -> tuple[float, bool, int]:
        """Solve the nonlinear problem.

        Parameters:
            model: The model instance specifying the problem to be solved.

        Returns:
            A 3-tuple containing:

            float:

                The error estimate.
            bool:

                True if the solution is converged.
            int:

                Number of iterations used.

        """
        model.before_nonlinear_loop()

        iteration_counter = 0

        is_converged = False
        is_diverged = False
        prev_sol = model.equation_system.get_variable_values(time_step_index=0)

        init_sol = prev_sol
        sol = init_sol
        errors = []
        error_norm = 1.0

        # Define a function that does all the work during one Newton iteration, except
        # for everything ``tqdm`` related.
        def newton_step() -> None:
            # Bind to variables in the outer function
            nonlocal prev_sol
            nonlocal sol
            nonlocal error_norm
            nonlocal is_converged
            nonlocal is_diverged

            # Logging.
            logger.info(
                f"Newton iteration number {iteration_counter}"
                + f" of {self.params['max_iterations']}"
            )

            # Re-discretize the nonlinear term
            model.before_nonlinear_iteration()

            sol = self.iteration(model)

            model.after_nonlinear_iteration(sol)

            error_norm, is_converged, is_diverged = model.check_convergence(
                sol, prev_sol, init_sol, self.params
            )
            prev_sol = sol
            errors.append(error_norm)

        # Progressbars turned off or tqdm not installed:
        if not self.progress_bar or not _IS_TQDM_AVAILABLE:
            while (
                iteration_counter <= self.params["max_iterations"] and not is_converged
            ):
                newton_step()

                if is_diverged:
                    model.after_nonlinear_failure(sol, errors, iteration_counter)
                elif is_converged:
                    model.after_nonlinear_convergence(sol, errors, iteration_counter)

                iteration_counter += 1

        # Progressbars turned on:
        else:
            # Redirect the root logger, s.t. no logger interferes with the progressbars.
            with logging_redirect_tqdm([logging.root]):
                # Initialize a progress bar. Length is the number of maximal Newton
                # iterations.
                solver_progressbar = trange(  # type: ignore
                    self.params["max_iterations"],
                    desc="Newton loop",
                    position=self.progress_bar_position,
                    leave=False,
                )

                while (
                    iteration_counter <= self.params["max_iterations"]
                    and not is_converged
                ):
                    solver_progressbar.set_description_str(
                        f"Newton iteration number {iteration_counter + 1} of \
                            {self.params['max_iterations']}"
                    )
                    newton_step()
                    solver_progressbar.update(n=1)
                    solver_progressbar.set_postfix_str(f"Error {error_norm}")

                    if is_diverged:
                        # If the process finishes early, the tqdm bar needs to be
                        # manually closed. See https://stackoverflow.com/a/73175351.
                        solver_progressbar.close()
                        model.after_nonlinear_failure(sol, errors, iteration_counter)
                        break
                    elif is_converged:
                        solver_progressbar.close()
                        model.after_nonlinear_convergence(
                            sol, errors, iteration_counter
                        )
                        break

                    iteration_counter += 1

        if not is_converged:
            model.after_nonlinear_failure(sol, errors, iteration_counter)

        return error_norm, is_converged, iteration_counter

    def iteration(self, model) -> np.ndarray:
        """A single nonlinear iteration.

        Right now, this is an almost trivial function. However, we keep it as a separate
        function to prepare for possible future introduction of more advanced schemes.

        """
        model.assemble_linear_system()
        sol = model.solve_linear_system()
        return sol


import sys
sys.setrecursionlimit(100000)

def factorial(n):
    if n == 0:
        return 1
    elif n == 1:
        return 1
    return n * factorial(n-1)
    # Provide your code here

print("factorial(5):", factorial(5))
# Expected 120
def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    return fib(n-1) + fib(n-2)
    # Provide your code here

print ("fib(7):", fib(7))
# Expected 13

def equal(A, B):
    if len(A) == 0 and len(B) == 0:
        return True
    elif len(A) == 0:
        return False
    elif len(B) == 0:
        return False
    elif A[len(A)-1] != B[len(B)-1]:
        return False
    else:
        A = A[1:len(A)]
        B = B[1:len(B)]
        return equal(A, B)
print ("equal('ALICE', 'BOB):", equal('ALICE', 'BOB'))
# Expected False
print ("equal('ALICE', 'ALICE'):", equal('ALICE', 'ALICE'))
# Expected True

def addup(list):
    if len(list) == 1:
        return list[0]
    else:
        x = list[0]
        list = list[1:len(list)]
        return x + addup(list)
    # Provide your code here

print ("addup([1,2,3,4,5]):", addup([1,2,3,4,5]))
# Expected 15
print ("addup(range(101)):", addup(range(101)))
# Expected 5050

def reverse(A):
    if len(A) == 0:
        return A
    else:
        B = A[0]
        A = A[1:len(A)]
        return reverse(A) + B
    # Provide your code here
print ("reverse('hello'):", reverse('hello'))
# Expected olleh


# -*- coding: utf-8 -*-
"""
请在此处完善你个人的信息
学院：
班级：
学号：
姓名：
"""
# 决战三字经

import simpleguitk as simplegui
import random
import copy

# 全局变量
has_rising_box = True                 # 是否有文字块正在上升
canvas_height = 600                   # 画布高度，单位为像素
canvas_width = 480                    # 画布宽度，单位为像素
box_height = 30                       # 文字块高度，单位为像素
box_width = 120                       # 文字块宽度，单位为像素，包含3个汉字
rising_speed = -1                     # 上升速度，单位为像素
horizontal_move_distance = box_width  # 按左右箭头键时，水平移动的距离，单位为像素
game_over = False                     # 游戏是否结束
rising_box = None                     # 正在运动的文字块对象
stopped_box = set([])                 # 停止移动的文字块
prime_sentence_list = []              # 三字经全文列表，每句为一个列表元素
current_section_list = []             # 当前处理的段落文字列表，每句为一个列表元素，4句为一个段落
last_four_box = []                    # 最近的4个文字块对象列表
score = 0                             # 游戏得分

# 从文本文件读入三字经，存储在列表中，并返回该列表,三字经文件的格式如下
'''
rén zhī chū    xìng běn shàn    xìng xiāng jìn    xí xiāng yuǎn
人之初    性本善    性相近    习相远
gǒu bú jiào    xìng nǎi qiān    jiào zhī dào    guì yǐ zhuān
苟不教    性乃迁    教之道    贵以专
xī mèng mǔ    zé lín chǔ    zǐ bù xué    duàn jī zhù
昔孟母    择邻处    子不学    断机杼
dòu yān shān    yǒu yì fāng    jiāo wǔ zǐ    míng jù yáng
窦燕山    有义方    教五子    名俱扬
yǎng bú jiào    fù zhī guò     jiào bù yán    shī zhī duò
养不教    父之过    教不严    师之惰
......
'''
def read_from_file(filename):
    # 奇数行为诗句拼音，偶数行为诗句文本
    # 三字经每3个汉字为1句，每1句作为列表的1个元素，四句为一行（一段），句间隔为空格
    prime_list = []
    input_file = open(filename, encoding='utf-8')
    i = 1
    for line in input_file.readlines():
        if i % 2 == 0:
            line_list = line.split()
            for sentence in line_list:
                prime_list.append(sentence)
        i = i + 1
    input_file.close()
    return prime_list
print(read_from_file('三字经.txt'))
print(read_from_file ('三字经.txt')[0])
print(read_from_file ('三字经.txt')[491])
text = read_from_file ('三字经.txt')
for t in text:
    print(t)

def text_shuffle(text):
        tmp_list = list(text)
        random.shuffle(tmp_list)
        return ''.join(tmp_list)
print(text_shuffle ('人之初'))

def draw_all_stopped_box(stopped_box,canvas):
    for box in stopped_box:
        box.draw(canvas)

# 生成当前段落四句诗歌列表
def generate_current_section_list():
    tmp_list = []
    for i in range(4):
        tmpstr = str(i) + prime_sentence_list.pop(0)
        tmp_list.append(tmpstr)
        random.shuffle(tmp_list)
    return tmp_list
prime_sentence_list = read_from_file('三字经.txt')
print(generate_current_section_list())
print(generate_current_section_list())
print(generate_current_section_list())

def check_collision(group, moving_box):
    for box in group:
        if box.collide(moving_box):
            return True
    return False

def stop_box(group, moving_box):
    global has_rising_box, game_over,score, label, last_four_box
    if moving_box.get_processed():
        return
    if moving_box.get_pos()[1] == 0 or check_collision(group, moving_box):
        moving_box.set_rising(False)
        stopped_box = copy.deepcopy(moving_box)
        if stopped_box.get_sentence() == stopped_box.get_correct_sentence():
            score += 5
            label_text = "游戏得分 = " + str(score) + "分"
            label.set_text(label_text)
        if (int(stopped_box.get_pos()[0] / box_width)) != stopped_box.get_order():
            stopped_box.set_proper_order(False)
        group.add(stopped_box)

        moving_box.set_processed()
        box_size = len(group)
        last_section_fine = False
        if box_size % 4 ==1:
            last_four_box.clear()
        last_four_box.append(stopped_box)
        if box_size % 4 ==0:
            if (last_four_box[0].get_proper_order()
                 and last_four_box[0].get_sentence() == last_four_box[0].get_correct_sentence()
                 and last_four_box[1].get_proper_order()
                 and last_four_box[1].get_sentence() == last_four_box[1].get_correct_sentence()
                 and last_four_box[2].get_proper_order()
                 and last_four_box[2].get_sentence() == last_four_box[2].get_correct_sentence()
                 and last_four_box[3].get_proper_order()
                 and last_four_box[3].get_sentence() == last_four_box[3].get_correct_sentence()) :
                score += 20
                label_text = "游戏得分 = " + str(score) + "分"
                label.set_text(label_text)
                last_section_fine = True
        if last_section_fine:
            for box in last_four_box:
                group.discard(box)

        line_index = (stopped_box.get_pos()[1] + 15) // box_height
        if line_index >= 10:
            game_over = True
        else:
            has_rising_box = False

# 绘制游戏结束信息
def draw_game_over_msg(canvas, msg):
    msgwidth = frame.get_canvas_textwidth(msg, 48, 'sans-serif')
    canvas.draw_text(msg, ((canvas_width - msgwidth) / 2, canvas_height / 2), 48, 'Red', 'sans-serif')

# Box类
class Box:
    def __init__(self, pos, width, height, sentence, correct_sentence, order):
        self.pos = [pos[0],pos[1]]
        self.width = width
        self.height = height
        self.sentence = sentence
        self.correct_sentence = correct_sentence
        self.rising = True
        self.processed = False
        self.order = order
        self.proper_order = True

    def set_processed(self):
        self.processed = True
    def get_processed(self):
        return self.processed
    def set_proper_order(self, is_proper_order):
        self.proper_order = is_proper_order
    def get_proper_order(self):
        return self.proper_order
    def get_order(self):
        return self.order
    def set_rising(self, is_rising):
        self.rising = is_rising
    def get_sentence(self):
        return self.sentence
    def get_correct_sentence(self):
        return self.correct_sentence
    def get_pos(self):
        return self.pos
    def set_pos(self, new_pos):
        self.pos = new_pos

    def shuffle_sentence(self):
        self.sentence = text_shuffle(self.sentence)

    def collide(self,moving_object):
        if (self.pos[1]) + self.height == moving_object.get_pos()[1] and self.pos[0] == moving_object.get_pos()[0]:
            return True
        else:
            return False

    def draw(self, canvas):
        text_width = frame.get_canvas_textwidth(self.sentence, 24, 'sans-serif')
        if self.sentence == self.correct_sentence and self.proper_order:
            canvas.draw_polygon([self.pos, [self.pos[0] + self.width, self.pos[1]], [self.pos[0] + self.width, self.pos[1] + self.height], [self.pos[0], self.pos[1] + self.height]], 2, 'Green', 'Green')
            canvas.draw_text(self.sentence, (self.pos[0] + (self.width - text_width) / 2, self.pos[1] + self.height - 2), 24, 'White', 'sans-serif')
        else:
            canvas.draw_polygon([self.pos, [self.pos[0] + self.width, self.pos[1]], [self.pos[0] + self.width, self.pos[1] + self.height], [self.pos[0], self.pos[1] + self.height]], 2, 'Red', 'Red')
            canvas.draw_text(self.sentence, (self.pos[0] + (self.width - text_width) / 2, self.pos[1] + self.height - 2), 24, 'Yellow', 'sans-serif')
    def update(self):
        if self.rising == True:
            self.pos[1] += rising_speed

test_box = Box([120,100], box_width, box_height, '人之初', '之人初', 0)
print(test_box.get_pos())
print(test_box.get_sentence())
print(test_box.get_correct_sentence())
print(test_box.get_order())
print(test_box.get_processed())
test_box.shuffle_sentence()
print(test_box.get_sentence())

# 时钟事件处理函数，生产一个上升的方块
def box_spawner():
    global has_rising_box,rising_box,current_section_list,game_over

    if game_over:
        return
    if not has_rising_box:
        if len(current_section_list) == 0:
            current_section_list = generate_current_section_list()
        sentence = current_section_list.pop()
        random_pos = [random.randrange(4) * box_width,canvas_height]
        rising_box = Box(random_pos, box_width, box_height, text_shuffle(sentence[1:]), sentence[1:], int(sentence[0]))

    has_rising_box = True

# 屏幕刷新事件处理函数
def draw(canvas):
    if game_over:
        draw_game_over_msg(canvas,'游戏结束！')
    else:
        rising_box.draw(canvas)
        rising_box.update()
        draw_all_stopped_box(stopped_box, canvas)
        stop_box(stopped_box,rising_box)

# 处理键盘按下事件的函数
def keydown(key):
    if not game_over:
        if key == simplegui.KEY_MAP["left"]:    # 向左移动方块
            if rising_box.get_pos()[0] - horizontal_move_distance >= 0:
                rising_box.set_pos([rising_box.get_pos()[0] - horizontal_move_distance,rising_box.get_pos()[1]])
        elif key == simplegui.KEY_MAP["right"]: # 向右移动方块
            if rising_box.get_pos()[0] + box_width + horizontal_move_distance <= canvas_width:
                rising_box.set_pos([rising_box.get_pos()[0] + horizontal_move_distance,rising_box.get_pos()[1]])
        elif key == simplegui.KEY_MAP["space"]: # 重排文字顺序
            rising_box.shuffle_sentence()

# 为游戏开始或重新开始初始化全局变量，也是鼠标点击按钮的事件处理函数
def start_game():
    global prime_sentence_list, stopped_box, rising_box,current_section_list, has_rising_box, game_over, score, last_four_box
    score = 0
    label.set_text("游戏得分 = 0分")
    game_over = False
    prime_sentence_list = read_from_file('三字经.txt')
    stopped_box = set([])
    last_four_box = []
    current_section_list = generate_current_section_list()
    rising_sentence = current_section_list.pop()
    rising_box = Box([0,canvas_height], box_width, box_height, text_shuffle(rising_sentence[1:]), rising_sentence[1:], int(rising_sentence[0]))

    has_rising_box = True

# 创建窗口初始化画布
frame = simplegui.create_frame("挑战《三字经》", canvas_width, canvas_height)
label = frame.add_label("游戏得分 = 0分")

# 注册事件处理函数
frame.set_keydown_handler(keydown)                         # 按键处理，每次按键会调用keydown函数
frame.set_draw_handler(draw)                               # 显示处理，每秒调用draw函数60次
timer = simplegui.create_timer(1000.0, box_spawner)        # 每秒调用box_spawner函数1次
button = frame.add_button('重新开始游戏', start_game, 100)   # 鼠标每次点击“重新开始游戏”按钮，调用start_game函数1次

# 启动游戏
start_game()     # 为游戏开始或重新开始初始化全局变量
timer.start()    # 启动定时器
frame.start()    # 显示窗口


import itertools
from dataclasses import dataclass
from pprint import pprint
from typing import Iterator, NamedTuple

class Point(NamedTuple):
    x: int
    y: int

@dataclass
class Rock:
    points: list[tuple[int, int]]

    def move(self, dx: int, dy: int, chamber: list[Point]) -> bool:
        target_points = [Point(x + dx, y + dy) for x, y in self.points]
        for point in target_points:
            if point.x < 0 or point.x > 6:
                return False
            if point in chamber:
                return False
        self.points = target_points
        return True

@dataclass
class RockFactory:
    height: int
    width: int
    layout: list[tuple[int, int]]

    def create(self, x: int, y: int) -> Rock:
        return Rock(points=[Point(x + dx, y + dy) for dx, dy in self.layout])

    @staticmethod
    def parse(data: str) -> "RockFactory":
        lines = data.splitlines(keepends=False)
        layout = []
        for column, line in enumerate(reversed(lines)):
            for row, char in enumerate(line):
                if char == "#":
                    layout.append((row, column))
        return RockFactory(height=len(lines), width=len(line), layout=layout)

def load_shapes() -> list[RockFactory]:
    with open("shapes.txt") as f:
        data = f.read()
    shapes = data.split("\n\n")
    return [RockFactory.parse(portion) for portion in shapes]

def load_data(input_file: str) -> list[str]:
    with open(input_file) as f:
        return list(f.readline().strip())

def draw_chamber(chamber: list[Point], hight: int):
    for y in range(hight + 1, -1, -1):
        for x in range(7):
            print("#" if Point(x=x, y=y) in chamber else ".", end="")
        print()
    print("\n\n")

def fall(
    chamber: list[Point], rock_factory: RockFactory, jet_gen: Iterator[str], hight: int
) -> int:
    rock = rock_factory.create(x=2, y=hight + 4)
    new_hight = hight
    while True:
        dx = 1 if next(jet_gen) == ">" else -1
        rock.move(dx=dx, dy=0, chamber=chamber)
        if rock.move(dx=0, dy=-1, chamber=chamber) is False:
            # contact
            for point in rock.points:
                chamber.append(point)
                new_hight = max(new_hight, point.y)
            return new_hight

def part1(shapes: list[RockFactory], jets: str) -> int:
    chamber = [Point(x=x, y=0) for x in range(7)]
    jet_gen = itertools.cycle(jets)
    hight = 0
    for rock_id, shape in enumerate(itertools.cycle(shapes), start=1):
        hight = fall(chamber=chamber, rock_factory=shape, jet_gen=jet_gen, hight=hight)
        # draw_chamber(chamber=chamber, hight=hight)
        if rock_id == 2022:
            return hight

if __name__ == "__main__":
    shapes = load_shapes()
    pprint(shapes)
    jets = load_data("input.txt")
    print(f"Part1: {part1(shapes=shapes, jets=jets)}")


__version__ = '$Id: optimize.py 3232 2009-01-27 12:31:49Z montanaro $'
import copy
def SimplexMaximize(var, err, func, convcrit = 0.001, minerr = 0.001):
    import numpy
    var = numpy.array(var)
    simplex = [var]
    for i in range(len(var)):
        var2 = copy.copy(var)
        var2[i] = var[i] + err[i]
        simplex.append(var2)
    value = []
    for i in range(len(simplex)):
        value.append(func(simplex[i]))
    while 1:
        wi = 0
        bi = 0
        for i in range(len(simplex)):
            if value[wi] > value[i]:
                wi = i
            if value[bi] < value[i]:
                bi = i
        if abs(value[bi] - value[wi]) <= convcrit:
            return simplex[bi]
        ave = numpy.zeros(len(var), dtype=numpy.float)
        for i in range(len(simplex)):
            if i != wi:
                ave = ave + simplex[i]
        ave = ave / (len(simplex) - 1)
        worst = numpy.array(simplex[wi])
        simsize = numpy.add.reduce(numpy.absolute(ave - worst))
        if simsize <= minerr:
            return simplex[bi]
        new = 2 * ave - simplex[wi]
        newv = func(new)
        if newv <= value[wi]:
            new = 0.5 * ave + 0.5 * worst
            newv = func(new)
        elif newv > value[bi]:
            new2 = 3 * ave - 2 * worst
            newv2 = func(new2)
            if newv2 > newv:
                new = new2
                newv = newv2
        simplex[wi] = new
        value[wi] = newv
def DoubleSimplexMaximize(var, err, func, convcrit=0.001, minerr=0.001):
    import numpy
    err = numpy.array(err)
    var = SimplexMaximize(var, err, func, convcrit*5, minerr*5)
    return SimplexMaximize(var, 0.4 * err, func, convcrit, minerr)


# !/usr/bin/env python

# get the train list of segmentation needed
# in this format
# /path/to/image.jpg /path/to/label_image.jpg

# assumes image under train/ labeled_image under train_labels/

# do not using ./
img_dir = 'train'
label_dir = 'train_labels'

target_save_f = 'image_label.list'

# list the img dir, found the label under label dir, and write a line
import os

base_dir = os.path.dirname(os.path.abspath(__file__))
all_image_f = [os.path.join(base_dir, img_dir, i) for i in os.listdir(img_dir) if os.path.isfile(os.path.join(base_dir, img_dir, i))]

f = open(target_save_f, 'a+')
f.truncate()
for img_f in all_image_f:
    print(img_f)
    current_img_name = os.path.basename(img_f)

    label_img_f = os.path.join(base_dir, label_dir, current_img_name)
    if os.path.exists(label_img_f):
        l = '{} {}'.format(img_f, label_img_f)
        f.write(l + '\n')
f.close()
print('Done, image_label.list has been generated.')


# -*- coding: utf-8 -*-
'''
@createTool    : PyCharm-2020.3.3
@projectName   : pythonProjectPy3.9
@originalAuthor: Made in win10.Sys design by deHao.Zou
@createTime    : 2020/3/15 15:34
'''
'''
# -Begin-----------------------------------------------------------------

# -Packages--------------------------------------------------------------
from ctypes import *

# -Structures------------------------------------------------------------
class RFC_ERROR_INFO(Structure):
    _fields_ = [("code", c_long),
                ("group", c_long),
                ("key", c_wchar * 128),
                ("message", c_wchar * 512),
                ("abapMsgClass", c_wchar * 21),
                ("abapMsgType", c_wchar * 2),
                ("abapMsgNumber", c_wchar * 4),
                ("abapMsgV1", c_wchar * 51),
                ("abapMsgV2", c_wchar * 51),
                ("abapMsgV3", c_wchar * 51),
                ("abapMsgV4", c_wchar * 51)]

class RFC_CONNECTION_PARAMETER(Structure):
    _fields_ = [("name", c_wchar_p),
                ("value", c_wchar_p)]

# -Main------------------------------------------------------------------
ErrInf = RFC_ERROR_INFO;
RfcErrInf = ErrInf()
ConnParams = RFC_CONNECTION_PARAMETER * 5;
RfcConnParams = ConnParams()

SAPNWRFC = "sapnwrfc.dll"
SAP = windll.LoadLibrary(SAPNWRFC)

# -Prototypes------------------------------------------------------------
SAP.RfcOpenConnection.argtypes = [POINTER(ConnParams), c_ulong, POINTER(ErrInf)]
SAP.RfcOpenConnection.restype = c_void_p
SAP.RfcCloseConnection.argtypes = [c_void_p, POINTER(ErrInf)]
SAP.RfcCloseConnection.restype = c_ulong

# -Connection parameters-------------------------------------------------
RfcConnParams[0].name = "ASHOST";
RfcConnParams[0].value = "ABAP"
RfcConnParams[1].name = "SYSNR";
RfcConnParams[1].value = "00"
RfcConnParams[2].name = "CLIENT";
RfcConnParams[2].value = "001"
RfcConnParams[3].name = "USER";
RfcConnParams[3].value = "BCUSER"
RfcConnParams[4].name = "PASSWD";
RfcConnParams[4].value = "minisap"

hRFC = SAP.RfcOpenConnection(RfcConnParams, 5, RfcErrInf)
if hRFC != None:

    windll.user32.MessageBoxW(None, "Check connection with TAC SMGW", "", 0)

    # ---------------------------------------------------------------------
    # -
    # - Check connection with TAC SMGW in the SAP system
    # -
    # ---------------------------------------------------------------------

    rc = SAP.RfcCloseConnection(hRFC, RfcErrInf)

else:
    print(RfcErrInf.key)
    print(RfcErrInf.message)

# -End-------------------------------------------------------------------
'''
# -*- coding: utf-8 -*-
from flask import Flask, request
import json

app = Flask(__name__)

@app.route('/hci', methods=["POST"])
def check():
    data = request.get_data()
    url = json.loads(data)
    result_ = []
    score_datas = []
    temp_1 = {}
    for i in range(len(url)):
        answer = url["data{}".format(i + 1)]
        id = answer["id"]
        q1 = answer["q1"]
        q2 = answer["q2"]
        score = Similarity(q1, q2)

        temp_2 = {}
        temp_2["id"] = str(id)
        temp_2["score"] = str(score)
        result_.append(temp_2)
    total_score = get_Total_score()
    temp_1["TotalScore"] = str(total_score)
    temp_1["data"] = result_
    score_datas.append(temp_1)
    score_datas = json.dumps(score_datas, ensure_ascii=False)
    return score_datas

def Similarity(str1, str2):
    _score = 80
    return _score

def get_Total_score():
    _score = 80
    return _score

if __name__ == '__main__':
    app.run()

# ======================================================================================

# 把Excel数据转换为Json文件
import xlrd, json

def read_xlsx_file(filename):
    # 打开Excel文件
    data = xlrd.open_workbook(filename)
    # 读取第一个工作表
    table = data.sheets()[0]
    # 统计行数
    rows = table.nrows
    data = []  # 存放数据
    for i in range(1, rows):
        values = table.row_values(i)
        data.append(
            (
                {
                    "业务伙伴编码": values[0],
                    "流向门店名称": values[1],
                    "原始物料描述": values[2],
                    "原始物料规格": values[3],
                    "数量": values[4],
                    "单位": values[5],
                    "交易日期": values[6],
                }
            )

        )
    return data

if __name__ == '__main__':
    d1 = read_xlsx_file("C:/Users/Zeus/Desktop/网上客户流向3月份数据.xlsx")
    # 字典中的数据都是单引号，但是标准的json需要双引号
    js = json.dumps(d1, sort_keys=True, ensure_ascii=False, indent=4, separators=(',', ':'))
    print(js)
    # 前面的数据只是数组，加上外面的json格式大括号
    js = "{" + js + "}"
    # 可读可写，如果不存在则创建，如果有内容则覆盖
    jsFile = open("C:/Users/Zeus/Desktop/text3.json", "w+", encoding='utf-8')
    jsFile.write(js)
    jsFile.close()

# =========================================================================================
# 模拟postman上传数据
import requests

files = {'skFile': open("C:/Users/Zeus/Desktop/test.json", 'rb')}

r = requests.post("http://192.168.20.207:8000/wm/obtain?sap-client=600", files=files)

from urllib3 import encode_multipart_formdata
import requests

def post_files(url, header, data, filename, filepath):
    """
        :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
        ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
        or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
        defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
        to add for the file.
    """
    data['file'] = (filename, open(filepath, 'rb').read())
    encode_data = encode_multipart_formdata(data)
    data = encode_data[0]
    header['Content-Type'] = encode_data[1]
    r = requests.post(url, headers=header, data=data)
    print(r.content)

if __name__ == "__main__":
    # url,filename,filepath string
    # header,data dict
    print(post_files("url", {"header": "value"}, {"data": "value"}, "filename", "filepath"))

# ======================================================================================

from urllib3 import encode_multipart_formdata
import requests

url = "http://192.168.20.207:8000/wm/obtain?sap-client=600"
data = {}
headers = {}
filename = 'JsonFiles'  # 上传至服务器后，用于存储文件的名称
filepath = 'C:/Users/Zeus/Desktop/text3.json'  # 当前要上传的文件路径
proxies = {
    "http": "http://192.168.20.207:8000",
    "https": "http://192.168.20.207:8000",
    # 如果代理ip需要用户名和密码的话 'http':'user:password@192.168.1.1:88'
}
####
data['upload_file'] = (filename, open(filepath, 'rb').read())
data['submit'] = "提交"
encode_data = encode_multipart_formdata(data)
data = encode_data[0]
headers['Content-Type'] = encode_data[1]
# r = requests.post(url, headers=headers, data=data, timeout=5)
r = requests.post(url, headers=headers, data=data, proxies=proxies, timeout=5)
print(r.status_code)

# ======================================================================================

import requests
import json
import xlrd

host = "http://httpbin.org/"
endpoint = "post"
url = ''.join([host, endpoint])
url = "http://zycrmqas.zeus.com:8000/ZWEB/DKHLX?sap-client=600"

dataJson = {
    "sites": [
        {"name": "test", "url": "www.test.com"},
        {"name": "google", "url": "www.google.com"},
        {"name": "weibo", "url": "www.weibo.com"}
    ]
}
dataJson = {
    "ZNB": "123123123",
    "ZDATA": [
        {
            "PARTNER": "111111111",
            "ZQDCY_FROM": "老百姓",
            "MATNR_FROM": "302020202",
            "ZGGE_FROM": "32g",
            "MENGE": "32",
            "MEINS_FROM": "罐",
            "ZDATE_DEAL": "20210101"

        }, {
            "PARTNER": "111111111",
            "ZQDCY_FROM": "老百姓",
            "MATNR_FROM": "302020202",
            "ZGGE_FROM": "32g",
            "MENGE": "32",
            "MEINS_FROM": "罐",
            "ZDATE_DEAL": "20210101"

        }
    ]
}

def read_xlsx_file(filename):
    # 打开Excel文件
    data = xlrd.open_workbook(filename)
    # 读取第一个工作表
    table = data.sheets()[0]
    # 统计行数
    rows = table.nrows
    data = []  # 存放数据
    for i in range(1, rows):
        values = table.row_values(i)
        data.append(
            (
                {
                    "业务伙伴编码": str(int(values[0])),
                    "流向门店名称": values[1],
                    "原始物料描述": values[2],
                    "原始物料规格": values[3],
                    "数量": values[4],
                    "单位": values[5],
                    "交易日期": str(int(values[6])),
                }
            )

        )
    return data

dataExecel = read_xlsx_file("C:/Users/Zeus/Desktop/网上客户流向3月份数据.xlsx")
# 字典中的数据都是单引号,但是标准的json需要双引号
dataJson = json.dumps(dataExecel, sort_keys=True, ensure_ascii=False, indent=4, separators=(',', ':'))
# 前面的数据只是数组,加上外面的json格式大括号
dataJson = "{" + dataJson + "}"
print(dataJson)

'''
requests.get()                                # GET请求
requests.post()                               # POST请求
requests.put()                                # PUT请求
requests.delete()                             # DELETE请求
requests.head()                               # HEAD请求
requests.options()                            # OPTIONS请求
'''
# r = requests.get('https://github.com/Ranxf')  # 最基本的不带参数的get请求
# r = requests.get(url='http://dict.baidu.com/s', params={'wd': 'python'})  # 带参数的get请求
r = requests.post(url, data=(json.dumps(dataJson, ensure_ascii=False)).encode("utf-8"))
r = requests.post(url, data=json.dumps(dataJson))
'''
r.encoding                                 # 获取当前的编码
r.encoding = 'utf-8'                       # 设置编码
r.text                                     # 以encoding解析返回内容。字符串方式的响应体, 会自动根据响应头部的字符编码进行解码。
r.content                                  # 以字节形式（二进制）返回。字节方式的响应体, 会自动为你解码 gzip 和 deflate 压缩。
r.headers                                  # 以字典对象存储服务器响应头, 但是这个字典比较特殊, 字典键不区分大小写, 若键不存在则返回None
r.status_code                              # 响应状态码
r.raw                                      # 返回原始响应体，也就是urllib的response对象, 使用 r.raw.read()
r.ok                                       # 查看r.ok的布尔值便可以知道是否登陆成功
*特殊方法*
r.json()                                   # Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的, 不然解析出错会抛异常
r.raise_for_status()                       # 失败请求(非200响应)抛出异常
r.headers                                  #返回字典类型,头信息
r.requests.headers                         #返回发送到服务器的头信息
r.cookies                                  #返回cookie
r.history                                  #返回重定向信息,当然可以在请求是加上allow_redirects = false 阻止重定向
'''
print(r.json())

# ======================================================================================
# 正式版本

import requests
import json
import xlrd

url = "http://zycrmqas.zeus.com:8000/ZWEB/DKHLX?sap-client=600"

dataJson = {
    "ZNB": "1000000100",
    "ZDATA": [
        {
            "MATNR_FROM": "党参破壁饮片",
            "MEINS_FROM": "罐 ",
            "MENGE": 1.0,
            "PARTNER": "1100002253",
            "ZDATE_DEAL": "20210301",
            "ZGGE_FROM": "2g×20袋",
            "ZQDCY_FROM": "劳动公园店"
        },
        {
            "MATNR_FROM": "红景天破壁饮片",
            "MEINS_FROM": "罐 ",
            "MENGE": 0.0,
            "PARTNER": "1100002253",
            "ZDATE_DEAL": "20210306",
            "ZGGE_FROM": "1g×20袋",
            "ZQDCY_FROM": "东莱街分店"
        },
        {
            "MATNR_FROM": "红景天破壁饮片",
            "MEINS_FROM": "罐 ",
            "MENGE": 1.0,
            "PARTNER": "1100002253",
            "ZDATE_DEAL": "20210311",
            "ZGGE_FROM": "1g×20袋",
            "ZQDCY_FROM": "劳动公园店"
        }
    ]
}

def read_xlsx_file(filename):
    data = xlrd.open_workbook(filename)
    table = data.sheets()[0]
    rows = table.nrows
    data = []
    for i in range(1, rows):
        values = table.row_values(i)
        data.append(
            (
                {
                    "PARTNER": str(int(values[0])),
                    "ZQDCY_FROM": values[1],
                    "MATNR_FROM": values[2],
                    "ZGGE_FROM": values[3],
                    "MENGE": values[4],
                    "MEINS_FROM": values[5],
                    "ZDATE_DEAL": str(int(values[6])),
                }
            )

        )
    return data

dataExecel = read_xlsx_file("C:/Users/Zeus/Desktop/网上客户流向3月份数据.xlsx")
# 字典中的数据都是单引号,但是标准的json需要双引号
dataJson = json.dumps(dataExecel, sort_keys=True, ensure_ascii=False, indent=4, separators=(',', ':'))
# 前面的数据只是数组,加上外面的json格式大括号
dataJson = """{""" + """\n"ZNB": "100000010",\n"ZDATA":""""" + dataJson + """\n}"""
print(dataJson)

'''
requests.get()                                # GET请求
requests.post()                               # POST请求
requests.put()                                # PUT请求
requests.delete()                             # DELETE请求
requests.head()                               # HEAD请求
requests.options()                            # OPTIONS请求
'''
# r = requests.post(url, data=(json.dumps(dataJson, ensure_ascii=False)).encode("utf-8"))
r = requests.post(url, data=dataJson.encode("utf-8"))
r = requests.post(url, data=json.dumps(dataJson))
'''
r.encoding                                 # 获取当前的编码
r.encoding = 'utf-8'                       # 设置编码
r.text                                     # 以encoding解析返回内容。字符串方式的响应体, 会自动根据响应头部的字符编码进行解码。
r.content                                  # 以字节形式（二进制）返回。字节方式的响应体, 会自动为你解码 gzip 和 deflate 压缩。
r.headers                                  # 以字典对象存储服务器响应头, 但是这个字典比较特殊, 字典键不区分大小写, 若键不存在则返回None
r.status_code                              # 响应状态码
r.raw                                      # 返回原始响应体，也就是urllib的response对象, 使用r.raw.read()
r.ok                                       # 查看r.ok的布尔值便可以知道是否登陆成功
*特殊方法*
r.json()                                   # Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的, 不然解析出错会抛异常
r.raise_for_status()                       # 失败请求(非200响应)抛出异常
r.headers                                  #返回字典类型,头信息
r.requests.headers                         #返回发送到服务器的头信息
r.cookies                                  #返回cookie
r.history                                  #返回重定向信息,当然可以在请求是加上allow_redirects = false 阻止重定向
'''
print(r.json())

# ======================================================================================
# 成功版本

import requests
import json
import xlrd

def excel_to_json(filename, dataId):
    workbook = xlrd.open_workbook(filename)
    sheet = workbook.sheet_by_index(0)
    rows = sheet.nrows
    content = []
    for i in range(1, rows):
        values = sheet.row_values(i)
        content.append(
            (
                {
                    "PARTNER": str(int(values[0])),
                    "ZQDCY_FROM": values[1],
                    "MATNR_FROM": values[2],
                    "ZGGE_FROM": values[3],
                    "MENGE": values[4],
                    "MEINS_FROM": values[5],
                    "ZDATE_DEAL": str(int(values[6])),
                }
            )

        )
    # 字典中的数据都是单引号,但是标准的json需要双引号
    Json = json.dumps(content, sort_keys=True, ensure_ascii=False, indent=4, separators=(',', ':'))
    # 前面的数据只是数组,加上外面的json格式大括号, ZNB:导入SAP的流水单号
    dataJson = """{""" + """\n"ZNB": """"" + str(dataId) + """",\n"ZDATA":""""" + Json + """\n}"""
    return dataJson

dataExecelJson = excel_to_json("C:/Users/Zeus/Desktop/网上客户流向3月份数据.xlsx","1231000001")
print(dataExecelJson)

'''
requests.get()                             # GET请求
requests.post()                            # POST请求
requests.put()                             # PUT请求
requests.delete()                          # DELETE请求
requests.head()                            # HEAD请求
requests.options()                         # OPTIONS请求
r.encoding                                 # 获取当前的编码
r.encoding = 'utf-8'                       # 设置编码
r.text                                     # 以encoding解析返回内容。字符串方式的响应体, 会自动根据响应头部的字符编码进行解码。
r.content                                  # 以字节形式（二进制）返回。字节方式的响应体, 会自动为你解码 gzip 和 deflate 压缩。
r.headers                                  # 以字典对象存储服务器响应头, 但是这个字典比较特殊, 字典键不区分大小写, 若键不存在则返回None
r.status_code                              # 响应状态码
r.raw                                      # 返回原始响应体，也就是urllib的response对象, 使用r.raw.read()
r.ok                                       # 查看r.ok的布尔值便可以知道是否登陆成功
*特殊方法*
r.json()                                   # Requests中内置的JSON解码器,以json形式返回,前提返回的内容确保是json格式的, 不然解析出错会抛异常
r.raise_for_status()                       # 失败请求(非200响应)抛出异常
r.headers                                  #返回字典类型,头信息
r.requests.headers                         #返回发送到服务器的头信息
r.cookies                                  #返回cookie
r.history                                  #返回重定向信息,当然可以在请求是加上allow_redirects = false 阻止重定向
'''
# r = requests.post(url, data=(json.dumps(dataJson, ensure_ascii=False)).encode("utf-8"))
# r = requests.post(url, data=json.dumps(dataJson))
r = requests.post("http://zycrmqas.zeus.com:8000/ZWEB/DKHLX?sap-client=600", data=dataExecelJson.encode("utf-8"))
print(r.json())


# -*- coding: utf-8 -*-
"""
Exercise 5.1

In the task, a dictionary with information about different devices is created.

It is necessary to request the user to enter the name of the device (r1, r2, or sw1).
And display information about the corresponding device on the standard output
(information will be in the form of a dictionary).

Example of script execution:
$ python task_5_1.py
Enter the device name: r1
{'location': '21 New Globe Walk', 'vendor': 'Cisco', 'model': '4451', 'ios': '15.4', 'ip': '10.255.0.1'}

Limitation: you cannot change the london_co dictionary.

All tasks must be performed using only the topics covered. In other words, this task can
be solved without using the 'if' statement.
"""

london_co = {
    "r1": {
        "location": "21 New Globe Walk",
        "vendor": "Cisco",
        "model": "4451",
        "ios": "15.4",
        "ip": "10.255.0.1",
    },
    "r2": {
        "location": "21 New Globe Walk",
        "vendor": "Cisco",
        "model": "4451",
        "ios": "15.4",
        "ip": "10.255.0.2",
    },
    "sw1": {
        "location": "21 New Globe Walk",
        "vendor": "Cisco",
        "model": "3850",
        "ios": "3.6.XE",
        "ip": "10.255.0.101",
        "vlans": "10,20,30",
        "routing": True,
    },
}

device_name = input('Enter the device name: ')
print('\n' + '-' * 30)
print(dict(london_co[device_name]))


from math import atan, exp, log10, pi

from fluids.constants import g
from fluids.core import Boiling, Bond, Prandtl, Weber
from fluids.numerics import secant
from fluids.two_phase_voidage import Lockhart_Martinelli_Xtt

from ht.boiling_nucleic import Cooper, Forster_Zuber
from ht.conv_internal import turbulent_Dittus_Boelter, turbulent_Gnielinski

__all__ = ['Thome', 'Liu_Winterton', 'Chen_Edelstein', 'Chen_Bennett',
           'Lazarek_Black', 'Li_Wu', 'Sun_Mishima', 'Yun_Heo_Kim']

__numba_additional_funcs__ = ('to_solve_q_Thome',)

def Lazarek_Black(m, D, mul, kl, Hvap, q=None, Te=None):
    r'''Calculates heat transfer coefficient for film boiling of saturated
    fluid in vertical tubes for either upward or downward flow. Correlation
    is as shown in [1]_, and also reviewed in [2]_ and [3]_.

    Either the heat flux or excess temperature is required for the calculation
    of heat transfer coefficient.

    Quality independent. Requires no properties of the gas.
    Uses a Reynolds number assuming all the flow is liquid.

    .. math::
        h_{tp} = 30 Re_{lo}^{0.857} Bg^{0.714} \frac{k_l}{D}

    .. math::
        Re_{lo} = \frac{G_{tp}D}{\mu_l}

    Parameters
    ----------
    m : float
        Mass flow rate [kg/s]
    D : float
        Diameter of the channel [m]
    mul : float
        Viscosity of liquid [Pa*s]
    kl : float
        Thermal conductivity of liquid [W/m/K]
    Hvap : float
        Heat of vaporization of liquid [J/kg]
    q : float, optional
        Heat flux to wall [W/m^2]
    Te : float, optional
        Excess temperature of wall, [K]

    Returns
    -------
    h : float
        Heat transfer coefficient [W/m^2/K]

    Notes
    -----
    [1]_ has been reviewed.

    [2]_ claims it was developed for a range of quality 0-0.6,
    Relo 860-5500, mass flux 125-750 kg/m^2/s, q of 1.4-38 W/cm^2, and with a
    pipe diameter of 3.1 mm. Developed with data for R113 only.

    Examples
    --------
    >>> Lazarek_Black(m=10, D=0.3, mul=1E-3, kl=0.6, Hvap=2E6, Te=100)
    9501.932636079293

    References
    ----------
    .. [1] Lazarek, G. M., and S. H. Black. "Evaporative Heat Transfer,
       Pressure Drop and Critical Heat Flux in a Small Vertical Tube with
       R-113." International Journal of Heat and Mass Transfer 25, no. 7 (July
       1982): 945-60. doi:10.1016/0017-9310(82)90070-9.
    .. [2] Fang, Xiande, Zhanru Zhou, and Dingkun Li. "Review of Correlations
       of Flow Boiling Heat Transfer Coefficients for Carbon Dioxide."
       International Journal of Refrigeration 36, no. 8 (December 2013):
       2017-39. doi:10.1016/j.ijrefrig.2013.05.015.
    .. [3] Bertsch, Stefan S., Eckhard A. Groll, and Suresh V. Garimella.
       "Review and Comparative Analysis of Studies on Saturated Flow Boiling in
       Small Channels." Nanoscale and Microscale Thermophysical Engineering 12,
       no. 3 (September 4, 2008): 187-227. doi:10.1080/15567260802317357.
    '''
    G = m/(pi/4*D**2)
    Relo = G*D/mul
    if q is not None:
        Bg = Boiling(G=G, q=q, Hvap=Hvap)
        return 30*Relo**0.857*Bg**0.714*kl/D
    elif Te is not None:
        # Solved with sympy
        return 27000*30**(71/143)*(1./(G*Hvap))**(357/143)*Relo**(857/286)*Te**(357/143)*kl**(500/143)/D**(500/143)
    else:
        raise ValueError('Either q or Te is needed for this correlation')

def Li_Wu(m, x, D, rhol, rhog, mul, kl, Hvap, sigma, q=None, Te=None):
    r'''Calculates heat transfer coefficient for film boiling of saturated
    fluid in any orientation of flow. Correlation
    is as shown in [1]_, and also reviewed in [2]_ and [3]_.

    Either the heat flux or excess temperature is required for the calculation
    of heat transfer coefficient. Uses liquid Reynolds number, Bond number,
    and Boiling number.

    .. math::
        h_{tp} = 334 Bg^{0.3}(Bo\cdot Re_l^{0.36})^{0.4}\frac{k_l}{D}

    .. math::
        Re_{l} = \frac{G(1-x)D}{\mu_l}

    Parameters
    ----------
    m : float
        Mass flow rate [kg/s]
    x : float
        Quality at the specific tube interval []
    D : float
        Diameter of the tube [m]
    rhol : float
        Density of the liquid [kg/m^3]
    rhog : float
        Density of the gas [kg/m^3]
    mul : float
        Viscosity of liquid [Pa*s]
    kl : float
        Thermal conductivity of liquid [W/m/K]
    Hvap : float
        Heat of vaporization of liquid [J/kg]
    sigma : float
        Surface tension of liquid [N/m]
    q : float, optional
        Heat flux to wall [W/m^2]
    Te : float, optional
        Excess temperature of wall, [K]

    Returns
    -------
    h : float
        Heat transfer coefficient [W/m^2/K]

    Notes
    -----
    [1]_ has been reviewed.

    [1]_ used 18 sets of experimental data to derive the results, covering
    hydraulic diameters from 0.19 to 3.1 mm and 12 different fluids.

    Examples
    --------
    >>> Li_Wu(m=1, x=0.2, D=0.3, rhol=567., rhog=18.09, kl=0.086, mul=156E-6, sigma=0.02, Hvap=9E5, q=1E5)
    5345.409399239492

    References
    ----------
    .. [1] Li, Wei, and Zan Wu. "A General Correlation for Evaporative Heat
       Transfer in Micro/mini-Channels." International Journal of Heat and Mass
       Transfer 53, no. 9-10 (April 2010): 1778-87.
       doi:10.1016/j.ijheatmasstransfer.2010.01.012.
    .. [2] Fang, Xiande, Zhanru Zhou, and Dingkun Li. "Review of Correlations
       of Flow Boiling Heat Transfer Coefficients for Carbon Dioxide."
       International Journal of Refrigeration 36, no. 8 (December 2013):
       2017-39. doi:10.1016/j.ijrefrig.2013.05.015.
    .. [3] Kim, Sung-Min, and Issam Mudawar. "Review of Databases and
       Predictive Methods for Pressure Drop in Adiabatic, Condensing and
       Boiling Mini/micro-Channel Flows." International Journal of Heat and
       Mass Transfer 77 (October 2014): 74-97.
       doi:10.1016/j.ijheatmasstransfer.2014.04.035.
    '''
    G = m/(pi/4*D**2)
    Rel = G*D*(1-x)/mul
    Bo = Bond(rhol=rhol, rhog=rhog, sigma=sigma, L=D)
    if q is not None:
        Bg = Boiling(G=G, q=q, Hvap=Hvap)
        return 334*Bg**0.3*(Bo*Rel**0.36)**0.4*kl/D
    elif Te is not None:
        A = 334*(Bo*Rel**0.36)**0.4*kl/D
        return A**(10/7.)*Te**(3/7.)/(G**(3/7.)*Hvap**(3/7.))
    else:
        raise ValueError('Either q or Te is needed for this correlation')

def Sun_Mishima(m, D, rhol, rhog, mul, kl, Hvap, sigma, q=None, Te=None):
    r'''Calculates heat transfer coefficient for film boiling of saturated
    fluid in any orientation of flow. Correlation
    is as shown in [1]_, and also reviewed in [2]_.

    Either the heat flux or excess temperature is required for the calculation
    of heat transfer coefficient. Uses liquid-only Reynolds number, Weber
    number, and Boiling number. Weber number is defined in terms of the velocity
    if all fluid were liquid.

    .. math::
        h_{tp} = \frac{ 6 Re_{lo}^{1.05} Bg^{0.54}}
        {We_l^{0.191}(\rho_l/\rho_g)^{0.142}}\frac{k_l}{D}

    .. math::
        Re_{lo} = \frac{G_{tp}D}{\mu_l}

    Parameters
    ----------
    m : float
        Mass flow rate [kg/s]
    D : float
        Diameter of the tube [m]
    rhol : float
        Density of the liquid [kg/m^3]
    rhog : float
        Density of the gas [kg/m^3]
    mul : float
        Viscosity of liquid [Pa*s]
    kl : float
        Thermal conductivity of liquid [W/m/K]
    Hvap : float
        Heat of vaporization of liquid [J/kg]
    sigma : float
        Surface tension of liquid [N/m]
    q : float, optional
        Heat flux to wall [W/m^2]
    Te : float, optional
        Excess temperature of wall, [K]

    Returns
    -------
    h : float
        Heat transfer coefficient [W/m^2/K]

    Notes
    -----
    [1]_ has been reviewed.

    [1]_ used 2501 data points to derive the results, covering
    hydraulic diameters from 0.21 to 6.05 mm and 11 different fluids.

    Examples
    --------
    >>> Sun_Mishima(m=1, D=0.3, rhol=567., rhog=18.09, kl=0.086, mul=156E-6, sigma=0.02, Hvap=9E5, Te=10)
    507.6709168372167

    References
    ----------
    .. [1] Sun, Licheng, and Kaichiro Mishima. "An Evaluation of Prediction
       Methods for Saturated Flow Boiling Heat Transfer in Mini-Channels."
       International Journal of Heat and Mass Transfer 52, no. 23-24 (November
       2009): 5323-29. doi:10.1016/j.ijheatmasstransfer.2009.06.041.
    .. [2] Fang, Xiande, Zhanru Zhou, and Dingkun Li. "Review of Correlations
       of Flow Boiling Heat Transfer Coefficients for Carbon Dioxide."
       International Journal of Refrigeration 36, no. 8 (December 2013):
       2017-39. doi:10.1016/j.ijrefrig.2013.05.015.
    '''
    G = m/(pi/4*D**2)
    V = G/rhol
    Relo = G*D/mul
    We = Weber(V=V, L=D, rho=rhol, sigma=sigma)
    if q is not None:
        Bg = Boiling(G=G, q=q, Hvap=Hvap)
        return 6*Relo**1.05*Bg**0.54/(We**0.191*(rhol/rhog)**0.142)*kl/D
    elif Te is not None:
        A = 6*Relo**1.05/(We**0.191*(rhol/rhog)**0.142)*kl/D
        return A**(50/23.)*Te**(27/23.)/(G**(27/23.)*Hvap**(27/23.))
    else:
        raise ValueError('Either q or Te is needed for this correlation')

def Thome(m, x, D, rhol, rhog, mul, mug, kl, kg, Cpl, Cpg, Hvap, sigma, Psat,
          Pc, q=None, Te=None):
    r'''Calculates heat transfer coefficient for film boiling of saturated
    fluid in any orientation of flow. Correlation
    is as developed in [1]_ and [2]_, and also reviewed [3]_. This is a
    complicated model, but expected to have more accuracy as a result.

    Either the heat flux or excess temperature is required for the calculation
    of heat transfer coefficient. The solution for a specified excess
    temperature is solved numerically, making it slow.

    .. math::
        h(z) = \frac{t_l}{\tau} h_l(z) +\frac{t_{film}}{\tau} h_{film}(z)
        +  \frac{t_{dry}}{\tau} h_{g}(z)

    .. math::
        h_{l/g}(z) = (Nu_{lam}^4 + Nu_{trans}^4)^{1/4} k/D

    .. math::
        Nu_{laminar} = 0.91 {Pr}^{1/3} \sqrt{ReD/L(z)}

    .. math::
        Nu_{trans} = \frac{ (f/8) (Re-1000)Pr}{1+12.7 (f/8)^{1/2} (Pr^{2/3}-1)}
        \left[ 1 + \left( \frac{D}{L(z)}\right)^{2/3}\right]

    .. math::
        f = (1.82 \log_{10} Re - 1.64 )^{-2}

    .. math::
        L_l = \frac{\tau G_{tp}}{\rho_l}(1-x)

    .. math::
        L_{dry} = v_p t_{dry}

    .. math::
        t_l = \frac{\tau}{1 + \frac{\rho_l}{\rho_g}\frac{x}{1-x}}

    .. math::
        t_v = \frac{\tau}{1 + \frac{\rho_g}{\rho_l}\frac{1-x}{x}}

    .. math::
        \tau = \frac{1}{f_{opt}}

    .. math::
        f_{opt} = \left(\frac{q}{q_{ref}}\right)^{n_f}

    .. math::
        q_{ref} = 3328\left(\frac{P_{sat}}{P_c}\right)^{-0.5}

    .. math::
        t_{dry,film} = \frac{\rho_l \Delta H_{vap}}{q}[\delta_0(z) -
        \delta_{min}]

    .. math::
        \frac{\delta_0}{D} = C_{\delta 0}\left(3\sqrt{\frac{\nu_l}{v_p D}}
        \right)^{0.84}\left[(0.07Bo^{0.41})^{-8} + 0.1^{-8}\right]^{-1/8}

    .. math::
        Bo = \frac{\rho_l D}{\sigma} v_p^2

    .. math::
        v_p = G_{tp} \left[\frac{x}{\rho_g} + \frac{1-x}{\rho_l}\right]

    .. math::
        h_{film}(z) = \frac{2 k_l}{\delta_0(z) + \delta_{min}(z)}

    .. math::
        \delta_{min} = 0.3\cdot 10^{-6} \text{m}

    .. math::
        C_{\delta,0} = 0.29

    .. math::
        n_f = 1.74

    if t dry film > tv:

    .. math::
        \delta_{end}(x) = \delta(z, t_v)

    .. math::
        t_{film} = t_v

    .. math::
        t_{dry} = 0

    Otherwise:

    .. math::
        \delta_{end}(z) = \delta_{min}

    .. math::
        t_{film} = t_{dry,film}

    .. math::
        t_{dry} = t_v - t_{film}

    Parameters
    ----------
    m : float
        Mass flow rate [kg/s]
    x : float
        Quality at the specific tube interval []
    D : float
        Diameter of the tube [m]
    rhol : float
        Density of the liquid [kg/m^3]
    rhog : float
        Density of the gas [kg/m^3]
    mul : float
        Viscosity of liquid [Pa*s]
    mug : float
        Viscosity of gas [Pa*s]
    kl : float
        Thermal conductivity of liquid [W/m/K]
    kg : float
        Thermal conductivity of gas [W/m/K]
    Cpl : float
        Heat capacity of liquid [J/kg/K]
    Cpg : float
        Heat capacity of gas [J/kg/K]
    Hvap : float
        Heat of vaporization of liquid [J/kg]
    sigma : float
        Surface tension of liquid [N/m]
    Psat : float
        Vapor pressure of fluid, [Pa]
    Pc : float
        Critical pressure of fluid, [Pa]
    q : float, optional
        Heat flux to wall [W/m^2]
    Te : float, optional
        Excess temperature of wall, [K]

    Returns
    -------
    h : float
        Heat transfer coefficient [W/m^2/K]

    Notes
    -----
    [1]_ and [2]_ have been reviewed, and are accurately reproduced in [3]_.

    [1]_ used data from 7 studies, covering 7 fluids and Dh from 0.7-3.1 mm,
    heat flux from 0.5-17.8 W/cm^2, x from 0.01-0.99, and G from 50-564
    kg/m^2/s.

    Liquid and/or gas slugs are both considered, and are hydrodynamically
    developing. `Ll` is the calculated length of liquid slugs, and `L_dry`
    is the same for vapor slugs.

    Because of the complexity of the model and that there is some logic in this
    function, `Te` as an input may lead to a different solution that the
    calculated `q` will in return.

    Examples
    --------
    >>> Thome(m=1, x=0.4, D=0.3, rhol=567., rhog=18.09, kl=0.086, kg=0.2,
    ... mul=156E-6, mug=1E-5, Cpl=2300, Cpg=1400, sigma=0.02, Hvap=9E5,
    ... Psat=1E5, Pc=22E6, q=1E5)
    1633.008836502032

    References
    ----------
    .. [1] Thome, J. R., V. Dupont, and A. M. Jacobi. "Heat Transfer Model for
       Evaporation in Microchannels. Part I: Presentation of the Model."
       International Journal of Heat and Mass Transfer 47, no. 14-16 (July
       2004): 3375-85. doi:10.1016/j.ijheatmasstransfer.2004.01.006.
    .. [2] Dupont, V., J. R. Thome, and A. M. Jacobi. "Heat Transfer Model for
       Evaporation in Microchannels. Part II: Comparison with the Database."
       International Journal of Heat and Mass Transfer 47, no. 14-16 (July
       2004): 3387-3401. doi:10.1016/j.ijheatmasstransfer.2004.01.007.
    .. [3] Bertsch, Stefan S., Eckhard A. Groll, and Suresh V. Garimella.
       "Review and Comparative Analysis of Studies on Saturated Flow Boiling in
       Small Channels." Nanoscale and Microscale Thermophysical Engineering 12,
       no. 3 (September 4, 2008): 187-227. doi:10.1080/15567260802317357.
    '''
    if q is None and Te is not None:
        q = secant(to_solve_q_Thome, 1E4, args=( m, x, D, rhol, rhog, kl, kg, mul, mug, Cpl, Cpg, sigma, Hvap, Psat, Pc, Te))
        return Thome(m=m, x=x, D=D, rhol=rhol, rhog=rhog, kl=kl, kg=kg, mul=mul, mug=mug, Cpl=Cpl, Cpg=Cpg, sigma=sigma, Hvap=Hvap, Psat=Psat, Pc=Pc, q=q)
    elif q is None and Te is None:
        raise ValueError('Either q or Te is needed for this correlation')
    C_delta0 = 0.3E-6
    G = m/(pi/4*D**2)
    Rel = G*D*(1-x)/mul
    Reg = G*D*x/mug
    qref = 3328*(Psat/Pc)**-0.5
    if q is None:
        q = 1e4 # Make numba happy, their bug, never gets ran
    fopt = (q/qref)**1.74
    tau = 1./fopt

    vp = G*(x/rhog + (1-x)/rhol)
    Bo = rhol*D/sigma*vp**2 # Not standard definition
    nul = mul/rhol
    delta0 = D*0.29*(3*(nul/vp/D)**0.5)**0.84*((0.07*Bo**0.41)**-8 + 0.1**-8)**(-1/8.)

    tl = tau/(1 + rhol/rhog*(x/(1.-x)))
    tv = tau/(1 + rhog/rhol*((1.-x)/x))

    t_dry_film = rhol*Hvap/q*(delta0 - C_delta0)
    if t_dry_film > tv:
        t_film = tv
        delta_end = delta0 - q/rhol/Hvap*tv # what could time possibly be?
        t_dry = 0
    else:
        t_film = t_dry_film
        delta_end = C_delta0
        t_dry = tv-t_film
    Ll = tau*G/rhol*(1-x)
    Ldry = t_dry*vp

    Prg = Prandtl(Cp=Cpg, k=kg, mu=mug)
    Prl = Prandtl(Cp=Cpl, k=kl, mu=mul)
    fg = (1.82*log10(Reg) - 1.64)**-2
    fl = (1.82*log10(Rel) - 1.64)**-2

    Nu_lam_Zl = 2*0.455*(Prl)**(1/3.)*(D*Rel/Ll)**0.5
    Nu_trans_Zl = turbulent_Gnielinski(Re=Rel, Pr=Prl, fd=fl)*(1 + (D/Ll)**(2/3.))
    if Ldry == 0:
        Nu_lam_Zg, Nu_trans_Zg = 0, 0
    else:
        Nu_lam_Zg = 2*0.455*(Prg)**(1/3.)*(D*Reg/Ldry)**0.5
        Nu_trans_Zg = turbulent_Gnielinski(Re=Reg, Pr=Prg, fd=fg)*(1 + (D/Ldry)**(2/3.))

    h_Zg = kg/D*(Nu_lam_Zg**4 + Nu_trans_Zg**4)**0.25
    h_Zl = kl/D*(Nu_lam_Zl**4 + Nu_trans_Zl**4)**0.25

    h_film = 2*kl/(delta0 + C_delta0)
    return tl/tau*h_Zl + t_film/tau*h_film + t_dry/tau*h_Zg

def to_solve_q_Thome(q, m, x, D, rhol, rhog, kl, kg, mul, mug, Cpl, Cpg, sigma, Hvap, Psat, Pc, Te):
    err = q/Thome(m=m, x=x, D=D, rhol=rhol, rhog=rhog, kl=kl, kg=kg, mul=mul, mug=mug, Cpl=Cpl, Cpg=Cpg, sigma=sigma, Hvap=Hvap, Psat=Psat, Pc=Pc, q=q) - Te
    return err

def Yun_Heo_Kim(m, x, D, rhol, mul, Hvap, sigma, q=None, Te=None):
    r'''Calculates heat transfer coefficient for film boiling of saturated
    fluid in any orientation of flow. Correlation
    is as shown in [1]_ and [2]_, and also reviewed in [3]_.

    Either the heat flux or excess temperature is required for the calculation
    of heat transfer coefficient. Uses liquid Reynolds number, Weber
    number, and Boiling number. Weber number is defined in terms of the velocity
    if all fluid were liquid.

    .. math::
        h_{tp} = 136876(Bg\cdot We_l)^{0.1993} Re_l^{-0.1626}

    .. math::
        Re_l = \frac{G D (1-x)}{\mu_l}

    .. math::
        We_l = \frac{G^2 D}{\rho_l \sigma}

    Parameters
    ----------
    m : float
        Mass flow rate [kg/s]
    x : float
        Quality at the specific tube interval []
    D : float
        Diameter of the tube [m]
    rhol : float
        Density of the liquid [kg/m^3]
    mul : float
        Viscosity of liquid [Pa*s]
    Hvap : float
        Heat of vaporization of liquid [J/kg]
    sigma : float
        Surface tension of liquid [N/m]
    q : float, optional
        Heat flux to wall [W/m^2]
    Te : float, optional
        Excess temperature of wall, [K]

    Returns
    -------
    h : float
        Heat transfer coefficient [W/m^2/K]

    Notes
    -----
    [1]_ has been reviewed.

    Examples
    --------
    >>> Yun_Heo_Kim(m=1, x=0.4, D=0.3, rhol=567., mul=156E-6, sigma=0.02, Hvap=9E5, q=1E4)
    9479.313988550184

    References
    ----------
    .. [1] Yun, Rin, Jae Hyeok Heo, and Yongchan Kim. "Evaporative Heat
       Transfer and Pressure Drop of R410A in Microchannels." International
       Journal of Refrigeration 29, no. 1 (January 2006): 92-100.
       doi:10.1016/j.ijrefrig.2005.08.005.
    .. [2] Yun, Rin, Jae Hyeok Heo, and Yongchan Kim. "Erratum to 'Evaporative
       Heat Transfer and Pressure Drop of R410A in Microchannels; [Int. J.
       Refrigeration 29 (2006) 92-100]." International Journal of Refrigeration
       30, no. 8 (December 2007): 1468. doi:10.1016/j.ijrefrig.2007.08.003.
    .. [3] Bertsch, Stefan S., Eckhard A. Groll, and Suresh V. Garimella.
       "Review and Comparative Analysis of Studies on Saturated Flow Boiling in
       Small Channels." Nanoscale and Microscale Thermophysical Engineering 12,
       no. 3 (September 4, 2008): 187-227. doi:10.1080/15567260802317357.
    '''
    G = m/(pi/4*D**2)
    V = G/rhol
    Rel = G*D*(1-x)/mul
    We = Weber(V=V, L=D, rho=rhol, sigma=sigma)
    if q is not None:
        Bg = Boiling(G=G, q=q, Hvap=Hvap)
        return 136876*(Bg*We)**0.1993*Rel**-0.1626
    elif Te is not None:
        A = 136876*(We)**0.1993*Rel**-0.1626*(Te/G/Hvap)**0.1993
        return A**(10000/8007.)
    else:
        raise ValueError('Either q or Te is needed for this correlation')

def Chen_Edelstein(m, x, D, rhol, rhog, mul, mug, kl, Cpl, Hvap, sigma,
                   dPsat, Te):
    r'''Calculates heat transfer coefficient for film boiling of saturated
    fluid in any orientation of flow. Correlation
    is developed in [1]_ and [2]_, and reviewed in [3]_. This model is one of
    the most often used. It uses the Dittus-Boelter correlation for turbulent
    convection and the Forster-Zuber correlation for pool boiling, and
    combines them with two factors `F` and `S`.

    .. math::
        h_{tp} = S\cdot h_{nb} + F \cdot h_{sp,l}

    .. math::
        h_{sp,l} = 0.023 Re_l^{0.8} Pr_l^{0.4} k_l/D

    .. math::
        Re_l = \frac{DG(1-x)}{\mu_l}

    .. math::
        h_{nb} = 0.00122\left( \frac{\lambda_l^{0.79} c_{p,l}^{0.45}
        \rho_l^{0.49}}{\sigma^{0.5} \mu^{0.29} H_{vap}^{0.24} \rho_g^{0.24}}
        \right)\Delta T_{sat}^{0.24} \Delta p_{sat}^{0.75}

    .. math::
        F = (1 + X_{tt}^{-0.5})^{1.78}

    .. math::
        X_{tt} = \left( \frac{1-x}{x}\right)^{0.9} \left(\frac{\rho_g}{\rho_l}
        \right)^{0.5}\left( \frac{\mu_l}{\mu_g}\right)^{0.1}

    .. math::
        S = 0.9622 - 0.5822\left(\tan^{-1}\left(\frac{Re_L\cdot F^{1.25}}
        {6.18\cdot 10^4}\right)\right)

    Parameters
    ----------
    m : float
        Mass flow rate [kg/s]
    x : float
        Quality at the specific tube interval []
    D : float
        Diameter of the tube [m]
    rhol : float
        Density of the liquid [kg/m^3]
    rhog : float
        Density of the gas [kg/m^3]
    mul : float
        Viscosity of liquid [Pa*s]
    mug : float
        Viscosity of gas [Pa*s]
    kl : float
        Thermal conductivity of liquid [W/m/K]
    Cpl : float
        Heat capacity of liquid [J/kg/K]
    Hvap : float
        Heat of vaporization of liquid [J/kg]
    sigma : float
        Surface tension of liquid [N/m]
    dPsat : float
        Difference in Saturation pressure of fluid at Te and T, [Pa]
    Te : float
        Excess temperature of wall, [K]

    Returns
    -------
    h : float
        Heat transfer coefficient [W/m^2/K]

    Notes
    -----
    [1]_ and [2]_ have been reviewed, but the model is only put together in
    the review of [3]_. Many other forms of this equation exist with different
    functions for `F` and `S`.

    Examples
    --------
    >>> Chen_Edelstein(m=0.106, x=0.2, D=0.0212, rhol=567, rhog=18.09,
    ... mul=156E-6, mug=7.11E-6, kl=0.086, Cpl=2730, Hvap=2E5, sigma=0.02,
    ... dPsat=1E5, Te=3)
    3289.058731974052

    See Also
    --------
    turbulent_Dittus_Boelter
    Forster_Zuber

    References
    ----------
    .. [1] Chen, J. C. "Correlation for Boiling Heat Transfer to Saturated
       Fluids in Convective Flow." Industrial & Engineering Chemistry Process
       Design and Development 5, no. 3 (July 1, 1966): 322-29.
       doi:10.1021/i260019a023.
    .. [2] Edelstein, Sergio, A. J. Pérez, and J. C. Chen. "Analytic
       Representation of Convective Boiling Functions." AIChE Journal 30, no.
       5 (September 1, 1984): 840-41. doi:10.1002/aic.690300528.
    .. [3] Bertsch, Stefan S., Eckhard A. Groll, and Suresh V. Garimella.
       "Review and Comparative Analysis of Studies on Saturated Flow Boiling in
       Small Channels." Nanoscale and Microscale Thermophysical Engineering 12,
       no. 3 (September 4, 2008): 187-227. doi:10.1080/15567260802317357.
    '''
    G = m/(pi/4*D**2)
    Rel = D*G*(1-x)/mul
    Prl = Prandtl(Cp=Cpl, mu=mul, k=kl)
    hl = turbulent_Dittus_Boelter(Re=Rel, Pr=Prl)*kl/D

    Xtt = Lockhart_Martinelli_Xtt(x=x, rhol=rhol, rhog=rhog, mul=mul, mug=mug)
    F = (1 + Xtt**-0.5)**1.78
    Re = Rel*F**1.25
    S = 0.9622 - 0.5822*atan(Re/6.18E4)
    hnb = Forster_Zuber(Te=Te, dPsat=dPsat, Cpl=Cpl, kl=kl, mul=mul, sigma=sigma,
                       Hvap=Hvap, rhol=rhol, rhog=rhog)
    return hnb*S + hl*F

def Chen_Bennett(m, x, D, rhol, rhog, mul, mug, kl, Cpl, Hvap, sigma,
                   dPsat, Te):
    r'''Calculates heat transfer coefficient for film boiling of saturated
    fluid in any orientation of flow. Correlation
    is developed in [1]_ and [2]_, and reviewed in [3]_. This model is one of
    the most often used, and replaces the `Chen_Edelstein` correlation. It uses
    the Dittus-Boelter correlation for turbulent convection and the
    Forster-Zuber correlation for pool boiling, and combines them with two
    factors `F` and `S`.

    .. math::
        h_{tp} = S\cdot h_{nb} + F \cdot h_{sp,l}

    .. math::
       h_{sp,l} = 0.023 Re_l^{0.8} Pr_l^{0.4} k_l/D

    .. math::
       Re_l = \frac{DG(1-x)}{\mu_l}

    .. math::
       h_{nb} = 0.00122\left( \frac{\lambda_l^{0.79} c_{p,l}^{0.45}
        \rho_l^{0.49}}{\sigma^{0.5} \mu^{0.29} H_{vap}^{0.24} \rho_g^{0.24}}
        \right)\Delta T_{sat}^{0.24} \Delta p_{sat}^{0.75}

    .. math::
       F = \left(\frac{Pr_1+1}{2}\right)^{0.444}\cdot (1+X_{tt}^{-0.5})^{1.78}

    .. math::
       S = \frac{1-\exp(-F\cdot h_{conv} \cdot X_0/k_l)}
        {F\cdot h_{conv}\cdot X_0/k_l}

    .. math::
       X_{tt} = \left( \frac{1-x}{x}\right)^{0.9} \left(\frac{\rho_g}{\rho_l}
        \right)^{0.5}\left( \frac{\mu_l}{\mu_g}\right)^{0.1}

    .. math::
       X_0 = 0.041 \left(\frac{\sigma}{g \cdot (\rho_l-\rho_v)}\right)^{0.5}

    Parameters
    ----------
    m : float
        Mass flow rate [kg/s]
    x : float
        Quality at the specific tube interval []
    D : float
        Diameter of the tube [m]
    rhol : float
        Density of the liquid [kg/m^3]
    rhog : float
        Density of the gas [kg/m^3]
    mul : float
        Viscosity of liquid [Pa*s]
    mug : float
        Viscosity of gas [Pa*s]
    kl : float
        Thermal conductivity of liquid [W/m/K]
    Cpl : float
        Heat capacity of liquid [J/kg/K]
    Hvap : float
        Heat of vaporization of liquid [J/kg]
    sigma : float
        Surface tension of liquid [N/m]
    dPsat : float
        Difference in Saturation pressure of fluid at Te and T, [Pa]
    Te : float
        Excess temperature of wall, [K]

    Returns
    -------
    h : float
        Heat transfer coefficient [W/m^2/K]

    Notes
    -----
    [1]_ and [2]_ have been reviewed, but the model is only put together in
    the review of [3]_. Many other forms of this equation exist with different
    functions for `F` and `S`.

    Examples
    --------
    >>> Chen_Bennett(m=0.106, x=0.2, D=0.0212, rhol=567, rhog=18.09,
    ... mul=156E-6, mug=7.11E-6, kl=0.086, Cpl=2730, Hvap=2E5, sigma=0.02,
    ... dPsat=1E5, Te=3)
    4938.275351219369

    See Also
    --------
    Chen_Edelstein
    turbulent_Dittus_Boelter
    Forster_Zuber

    References
    ----------
    .. [1] Bennett, Douglas L., and John C. Chen. "Forced Convective Boiling in
       Vertical Tubes for Saturated Pure Components and Binary Mixtures."
       AIChE Journal 26, no. 3 (May 1, 1980): 454-61. doi:10.1002/aic.690260317.
    .. [2] Bennett, Douglas L., M.W. Davies and B.L. Hertzler, The Suppression
       of Saturated Nucleate Boiling by Forced Convective Flow, American
       Institute of Chemical Engineers Symposium Series, vol. 76, no. 199.
       91-103, 1980.
    .. [3] Bertsch, Stefan S., Eckhard A. Groll, and Suresh V. Garimella.
       "Review and Comparative Analysis of Studies on Saturated Flow Boiling in
       Small Channels." Nanoscale and Microscale Thermophysical Engineering 12,
       no. 3 (September 4, 2008): 187-227. doi:10.1080/15567260802317357.
    '''
    G = m/(pi/4*D**2)
    Rel = D*G*(1-x)/mul
    Prl = Prandtl(Cp=Cpl, mu=mul, k=kl)
    hl = turbulent_Dittus_Boelter(Re=Rel, Pr=Prl)*kl/D
    Xtt = Lockhart_Martinelli_Xtt(x=x, rhol=rhol, rhog=rhog, mul=mul, mug=mug)
    F = ((Prl+1)/2.)**0.444*(1 + Xtt**-0.5)**1.78
    X0 = 0.041*(sigma/(g*(rhol-rhog)))**0.5
    S = (1 - exp(-F*hl*X0/kl))/(F*hl*X0/kl)

    hnb = Forster_Zuber(Te=Te, dPsat=dPsat, Cpl=Cpl, kl=kl, mul=mul, sigma=sigma,
                       Hvap=Hvap, rhol=rhol, rhog=rhog)
    return hnb*S + hl*F

def Liu_Winterton(m, x, D, rhol, rhog, mul, kl, Cpl, MW, P,  Pc, Te):
    r'''Calculates heat transfer coefficient for film boiling of saturated
    fluid in any orientation of flow. Correlation
    is as developed in [1]_, also reviewed in [2]_ and [3]_.

    Excess wall temperature is required to use this correlation.

    .. math::
        h_{tp} = \sqrt{ (F\cdot h_l)^2 + (S\cdot h_{nb})^2}

    .. math::
       S = \left( 1+0.055F^{0.1} Re_{L}^{0.16}\right)^{-1}

    .. math::
       h_{l} = 0.023 Re_L^{0.8} Pr_l^{0.4} k_l/D

    .. math::
       Re_L = \frac{GD}{\mu_l}

    .. math::
       F = \left[ 1+ xPr_{l}(\rho_l/\rho_g-1)\right]^{0.35}

    .. math::
       h_{nb} = \left(55\Delta Te^{0.67} \frac{P}{P_c}^{(0.12 - 0.2\log_{10}
         R_p)}(-\log_{10} \frac{P}{P_c})^{-0.55} MW^{-0.5}\right)^{1/0.33}

    Parameters
    ----------
    m : float
        Mass flow rate [kg/s]
    x : float
        Quality at the specific tube interval []
    D : float
        Diameter of the tube [m]
    rhol : float
        Density of the liquid [kg/m^3]
    rhog : float
        Density of the gas [kg/m^3]
    mul : float
        Viscosity of liquid [Pa*s]
    kl : float
        Thermal conductivity of liquid [W/m/K]
    Cpl : float
        Heat capacity of liquid [J/kg/K]
    MW : float
        Molecular weight of the fluid, [g/mol]
    P : float
        Pressure of fluid, [Pa]
    Pc : float
        Critical pressure of fluid, [Pa]
    Te : float, optional
        Excess temperature of wall, [K]

    Returns
    -------
    h : float
        Heat transfer coefficient [W/m^2/K]

    Notes
    -----
    [1]_ has been reviewed, and is accurately reproduced in [3]_.

    Uses the `Cooper` and `turbulent_Dittus_Boelter` correlations.

    A correction for horizontal flow at low Froude numbers is available in
    [1]_ but has not been implemented and is not recommended in several
    sources.

    Examples
    --------
    >>> Liu_Winterton(m=1, x=0.4, D=0.3, rhol=567., rhog=18.09, kl=0.086,
    ... mul=156E-6, Cpl=2300, P=1E6, Pc=22E6, MW=44.02, Te=7)
    4747.749477190532

    References
    ----------
    .. [1] Liu, Z., and R. H. S. Winterton. "A General Correlation for
       Saturated and Subcooled Flow Boiling in Tubes and Annuli, Based on a
       Nucleate Pool Boiling Equation." International Journal of Heat and Mass
       Transfer 34, no. 11 (November 1991): 2759-66.
       doi:10.1016/0017-9310(91)90234-6.
    .. [2] Fang, Xiande, Zhanru Zhou, and Dingkun Li. "Review of Correlations
       of Flow Boiling Heat Transfer Coefficients for Carbon Dioxide."
       International Journal of Refrigeration 36, no. 8 (December 2013):
       2017-39. doi:10.1016/j.ijrefrig.2013.05.015.
    .. [3] Bertsch, Stefan S., Eckhard A. Groll, and Suresh V. Garimella.
       "Review and Comparative Analysis of Studies on Saturated Flow Boiling in
       Small Channels." Nanoscale and Microscale Thermophysical Engineering 12,
       no. 3 (September 4, 2008): 187-227. doi:10.1080/15567260802317357.
    '''
    G = m/(pi/4*D**2)
    ReL = D*G/mul
    Prl = Prandtl(Cp=Cpl, mu=mul, k=kl)
    hl = turbulent_Dittus_Boelter(Re=ReL, Pr=Prl)*kl/D
    F = (1 + x*Prl*(rhol/rhog - 1))**0.35
    S = (1 + 0.055*F**0.1*ReL**0.16)**-1
    h_nb = Cooper(Te=Te, P=P, Pc=Pc, MW=MW)
    return ((F*hl)**2 + (S*h_nb)**2)**0.5


ALPHABET = 26

class TrieNode:
    def __init__(self):
        self.children = [None] * ALPHABET
        self.isEndOfWord = False

class Trie:
    def __init__(self):
        self.root = TrieNode()
        # declare variables for needed computations
        self.words = []

    def __charToIndex(self, char):
        return ord(char) - ord('a')

    def __indexToChar(self, index):
        return chr(index + ord('a'))

    def __searchNode(self, key):
        pCrawl = self.root
        for level in range(len(key)):
            index = self.__charToIndex(key[level])
            if not pCrawl.children[index]:
                return None
            pCrawl = pCrawl.children[index]
        return pCrawl

    def search(self, key):
        pCrawl = self.__searchNode(key)
        return pCrawl != None and pCrawl.isEndOfWord

    def insert(self, key):
        pCrawl = self.root
        for level in range(len(key)):
            index = self.__charToIndex(key[level])
            if not pCrawl.children[index]:
                pCrawl.children[index] = TrieNode()
            pCrawl = pCrawl.children[index]
        pCrawl.isEndOfWord = True

    def bfs(self, word='', pCrawl=0):
        # print all words in trie starting with word (using BFS)
        if pCrawl == 0:
            self.words = []
            if word == '':
                pCrawl = self.root
            else:
                pCrawl = self.__searchNode(word)
                if pCrawl == None:
                    self.words.append('n/a')
                    return
        for index, child in enumerate(pCrawl.children):
            if child != None:
                w = word + self.__indexToChar(index)
                if child.isEndOfWord:
                    self.words.append(w)
                self.bfs(w, child)

# driver function
def main():
    keys = ["the", "then", "there", "tie", "a", "an", "any", "and"]
    output = ["Not present in trie", "Present in trie"]
    t = Trie()
    for key in keys:
        t.insert(key)
    # search for different keys
    for word in ["the", "these", "their", "thaw"]:
        print("{} ---- {}".format(word, output[t.search(word)]))
    print('print all words in trie:')
    t.bfs()
    print(t.words)
    print('print all words starting with "th" in trie:')
    t.bfs('th')
    print(t.words)
    print('print all words starting with "b" in trie:')
    t.bfs('b')
    print(t.words)

if __name__ == '__main__':
    main()