from datetime import datetime, timedelta

import pandas as pd
import six
import ujson
import validators
from sqlalchemy import JSON, Column, DateTime, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from tornado_sqlalchemy_login.sqla.models import APIKey, Base, User

APIKey = APIKey

class Client(User):
    __mapper_args__ = {"polymorphic_identity": "client"}

    competitions = relationship("Competition", back_populates="user")
    submissions = relationship("Submission", back_populates="user")

class Competition(Base):
    __tablename__ = "competitions"
    competition_id = Column(Integer, primary_key=True)
    title = Column(String(500), nullable=False)
    subtitle = Column(String(500), nullable=False)

    user_id = Column(Integer, ForeignKey("users.id", ondelete="cascade"))
    user = relationship(Client, back_populates="competitions")

    type = Column(String(10), nullable=False)
    expiration = Column(DateTime, nullable=False)
    prize = Column(Integer, nullable=False)
    metric = Column(String(10), nullable=False)

    targets = Column(String(500), nullable=True)

    dataset = Column(JSON, nullable=True)
    dataset_url = Column(String(500), nullable=True)
    dataset_type = Column(String(10), nullable=True)

    dataset_kwargs = Column(JSON, nullable=True)
    dataset_key = Column(String(500), nullable=True)

    num_classes = Column(Integer, nullable=True)
    when = Column(DateTime, nullable=True)

    answer = Column(JSON, nullable=True)
    answer_url = Column(String(500), nullable=True)  # TODO
    answer_type = Column(String(10), nullable=True)
    answer_delay = Column(Integer, nullable=True)  # TODO

    timestamp = Column(DateTime, nullable=False, default=datetime.utcnow)

    submissions = relationship("Submission", back_populates="competition")

    def __repr__(self):
        return "<Competition(id='%s', userId='%s')>" % (self.id, self.userId)

    def to_dict(self, private=False):
        ret = {}
        for item in (
            "competition_id",
            "title",
            "user_id",
            "type",
            "expiration",
            "prize",
            "metric",
            "targets",
            "dataset",
            "dataset_url",
            "dataset_type",
            "dataset_kwargs",
            "num_classes",
            "when",
            "timestamp",
        ):
            ret[item] = getattr(self, item)
        if private:
            for item in (
                "answer",
                "answer_url",
                "answer_type",
            ):
                ret[item] = getattr(self, item)
        return ret

    @staticmethod
    def from_spec(user_id, spec):
        c = Competition(
            user_id=user_id,
            title=spec.title,
            subtitle=spec.subtitle,
            expiration=spec.expiration + timedelta(seconds=spec.answer_delay),
            type=spec.type.value,
            prize=spec.prize,
            metric=spec.metric.value,
            dataset=spec.dataset
            if isinstance(spec.dataset, six.string_types)
            and validators.url(spec.dataset)
            else spec.dataset.to_dict()
            if isinstance(spec.dataset, pd.DataFrame)
            else ""
            if not spec.dataset
            else ujson.loads(spec.dataset),
            dataset_type=spec.dataset_type.value,
            dataset_kwargs=spec.dataset_kwargs,
            dataset_key=spec.dataset_key,
            num_classes=spec.num_classes,
            targets=spec.targets
            if isinstance(spec.targets, six.string_types)
            else ujson.dumps(spec.targets),
            when=spec.when,
            answer=spec.answer
            if isinstance(spec.answer, six.string_types) and validators.url(spec.answer)
            else spec.answer.to_dict()
            if isinstance(spec.answer, pd.DataFrame)
            else ""
            if not spec.answer
            else ujson.loads(spec.answer),
            answer_type=spec.dataset_type.value
            if spec.answer_type.value == "none"
            else spec.answer_type.value,
            answer_delay=spec.answer_delay,
            timestamp=datetime.now(),
        )
        return c

class Submission(Base):
    __tablename__ = "submissions"
    submission_id = Column(Integer, primary_key=True)

    user_id = Column(
        Integer,
        ForeignKey("users.id", ondelete="cascade"),
        nullable=False,
    )
    user = relationship(Client, back_populates="submissions")

    competition_id = Column(
        Integer,
        ForeignKey("competitions.competition_id", ondelete="cascade"),
        nullable=False,
    )
    competition = relationship(Competition, back_populates="submissions")

    score = Column(Integer)

    answer = Column(JSON, nullable=True)
    answer_url = Column(String(500), nullable=True)  # TODO
    answer_type = Column(String(10), nullable=True)

    timestamp = Column(DateTime, nullable=False, default=datetime.utcnow)

    def __repr__(self):
        return "<Submission(id='%s', userId='%s', competitionId='%s')>" % (
            self.id,
            self.userId,
            self.competitionId,
        )

    def to_dict(self, private=False):
        ret = {}
        for item in (
            "submission_id",
            "user_id",
            "competition_id",
            "score",
            "timestamp",
        ):
            ret[item] = getattr(self, item)
        if private:
            for item in (
                "answer",
                "answer_url",
                "answer_type",
            ):
                ret[item] = getattr(self, item)
        return ret

    @staticmethod
    def from_spec(user_id, competition_id, competition, spec):
        c = Submission(
            user_id=user_id,
            competition_id=competition_id,
            score=-1,
            competition=competition,
            answer=spec.answer
            if isinstance(spec.answer, six.string_types) and validators.url(spec.answer)
            else spec.answer.to_json()
            if isinstance(spec.answer, pd.DataFrame)
            else ""
            if not spec.answer
            else ujson.loads(spec.answer),
            answer_type=spec.answer_type.value,
            timestamp=datetime.now(),
        )
        return c


# IMDB 긍부정 분류해보기

import numpy as np
import tensorflow as tf
from tensorflow import keras

tf.random.set_seed(777)

# imdb dataset load
# 빈도수가 높은 상위 10000개의 word vector를 사용
imdb = keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
print("training entries: {}, labels: {}".format(len(train_data), len(train_labels)))
print(train_data[0])

# word vector to real word
word_index = imdb.get_word_index()

word_index = {k:(v+3) for k,v in word_index.items()}
word_index["<PAD>"] = 0
word_index["<START>"] = 1
word_index["<UNK>"] = 2
word_index["<UNUSED>"] = 3

reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])

def decode_review(test):
    return ' '.join([reverse_word_index.get(i, '?') for i in test])

# 4번째 데이터에 대한 test/label 출력
print(decode_review(train_data[4]))
print(train_labels[4])

# train/test data preprocessing(word embedding)
train_data = keras.preprocessing.sequence.pad_sequences(train_data,
                                                        value=word_index["<PAD>"],
                                                        padding='post',
                                                        maxlen=256)
test_data = keras.preprocessing.sequence.pad_sequences(test_data,
                                                       value=word_index["<PAD>"],
                                                       padding='post',
                                                       maxlen=256)
print(len(train_data[0]), len(test_data[0]))
print(train_data[0])
print(decode_review(train_data[0]))

# Tensorflow keras로 모델 정의
vocab_size = 10000

model = keras.Sequential()
model.add(keras.layers.Embedding(vocab_size, 16))
model.add(keras.layers.GlobalAveragePooling1D())
model.add(keras.layers.Dense(16, activation=tf.nn.relu))
model.add(keras.layers.Dense(1, activation=tf.nn.sigmoid))

# model summary
model.summary()

# optimizer로 ADAM 사용
# Epoch은 40
model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy']
              )
x_val = train_data[:10000]
partial_x_train = train_data[10000:]

y_val = train_labels[:10000]
partial_y_train = train_labels[10000:]

# verbose=2: 막대바X
model.fit(partial_x_train,
          partial_y_train,
          epochs=40,
          batch_size=512,
          validation_data=(x_val, y_val),
          verbose=2)

# verbose=2: 막대바X
test_loss, test_acc = model.evaluate(test_data, test_labels, verbose=2)
print('Test accuracy:', test_acc)
print('Test loss', test_loss)


# 剑指 Offer 42. 连续子数组的最大和
# 输入一个整型数组，数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
# 要求时间复杂度为O(n)。
def maxSubArray(nums: [int]) -> int:
    maxResult, pre = nums[0], 0
    for num in nums:
        pre = max(pre + num, num)
        maxResult = max(maxResult, pre)
    return maxResult

maxSubArray([-2,1,-3,4,-1,2,1,-5,4])

剑指 Offer 42. 连续子数组的最大和.py


import logging
import re
from django.db import models

logger = logging.getLogger('app')

class Videos(models.Model):
    CATEGORY = [
        ('tutorials', 'Lunar Magic Tutorials'),
        ('speedruns', 'Robfather Speedruns'),
    ]
    HELP_TEXT = {
        'category': 'Which section the video will appear in.',
        'title': 'Title of the video.',
        'description': 'Description text about the video.',
        'video_id': 'Video URL or ID from the YouTube share button.',
    }

    category = models.CharField(max_length=255, choices=CATEGORY, default='tutorials', help_text=HELP_TEXT['category'])
    title = models.CharField(max_length=255, help_text=HELP_TEXT['title'])
    description = models.TextField(help_text=HELP_TEXT['description'])
    video_id = models.CharField(max_length=255, help_text=HELP_TEXT['video_id'])
    updated_at = models.DateTimeField(auto_now=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def save(self, *args, **kwargs):
        m = re.search('[a-zA-Z0-9\-\_]{8,20}', self.video_id)
        logger.info(m)
        self.video_id = m.group(0)
        logger.info(self.video_id)
        super(Videos, self).save()

    class Meta:
        verbose_name = 'Videos'
        verbose_name_plural = 'Videos'


seen = []

def exist(board, word):
    global seen
    for r in range(len(board)):
        for c in range(len(board[0])):
            if visit(0, word, board, r, c):
                return True
            else:
                seen = []

    return False

def visit(c, word, board, row, col):
    ans = False
    if (row, col) in seen:
        seen.append((row, col))
        return ans
    seen.append((row, col))

    if word[c] == board[row][col]:
        ans = True
        if c + 1 < len(word):
            ans = False
            if row + 1 < len(board):
                if visit(c + 1, word, board, row + 1, col):
                    ans = True
                else:
                    seen.remove((row + 1, col))

            if row - 1 >= 0:
                if visit(c + 1, word, board, row - 1, col):
                    ans = True
                else:
                    seen.remove((row - 1, col))

            if col + 1 < len(board[0]):
                if visit(c + 1, word, board, row, col + 1):
                    ans = True
                else:
                    seen.remove((row, col + 1))

            if col - 1 >= 0:
                if visit(c + 1, word, board, row, col - 1):
                    ans = True
                else:
                    seen.remove((row, col - 1))

    return ans

if __name__ == '__main__':
    board = [
        ['A', 'B', 'C', 'E'],
        ['S', 'F', 'C', 'S'],
        ['A', 'D', 'E', 'E']
    ]
    assert exist(board, "ABCCED") is True
    assert exist(board, "ABCB") is False


class Country:

    def __init__(self, name, population, language, capitol):
        self.name = name
        self.population = population
        self.language = language
        self.capitol = capitol

    def __repr__(self):
        # return str(self) - nie wiem czemu nie dziala :C
        return self.name + " has capitol: " + self.capitol

Poland = Country("Poland", 37.98, "Polish", "Warsaw")
Germany = Country("Germany", 82.79, "German", "Berlin")
Nibylandia = Country("Nibylandia", 0, "None", "Doesn't exist")

list = [Poland, Germany, Nibylandia]
print(list)
print(Country.__repr__(Poland)) # wyświetlanie __repr__ dla pojedynczego \o/ zostawiam, bo tak!
print(list)


from typing import List

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        def BinarySearch(nums: List[list], target) ->bool:
            left, right = -1, len(nums)
            while right - left > 1:
                mid = left + (right - left) //2
                if nums[mid] > target:
                    right = mid
                else:
                    left = mid
            return left

        n = len(matrix)
        for i in range(n):
            index = BinarySearch(nums=matrix[i], target=target)
            pur = matrix[i][index]
            if pur == target:
                return True
        return False


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" Pygame basics

See https://inventwithpython.com/pygame/chapter2.html

Usage:
    python3 file.py <PARAM>
"""
import pygame
from pygame.locals import *
import sys

pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Hello World')
while True:
    for event in pygame.event.get():
        if event.type == 'QUIT':
            pygame.quit()
            sys.exit()
    pygame.display.update()


import numpy as np
from scipy import ndimage
from skimage import measure
from ..tools._data import np_drop_duplicates_from_column

from ._patch import BootstrapPatch

def compute_bootstrap_patches(state,
                              final_states,
                              land,
                              lul_initial,
                              lul_final,
                              mask=None,
                              neighbors_structure='rook'):
    """Compute bootstrap patches

    Parameters
    ----------
    state : State
        The initial state of this land.

    final_states : [State]
        The final states list.

    land : Land
        The studied land object.

    lul_initial : LandUseLayer
        The initial land use.

    lul_final : LandUseLayer
        The final land use.

    mask : MaskLayer, default = None
        The region mask layer. If ``None``, the whole area is studied.

    neighbors_structure : {'rook', 'queen'}, default='rook'
        The neighbors structure.

    Returns
    -------
    patches : dict(State:Patch)
        Dict of patches with states as keys.
    """
    if neighbors_structure == 'queen':
        structure = np.ones((3, 3))
    elif neighbors_structure == 'rook':
        structure = np.array([[0, 1, 0],
                              [1, 1, 1],
                              [0, 1, 0]])
    else:
        raise (ValueError('ERROR : unexpected neighbors_structure value'))

    M_shape = lul_initial.get_data().shape

    patches = {}

    u = state.value

    J, V = land.get_values(lul_initial=lul_initial,
                           lul_final=lul_final,
                           mask=mask,
                           explanatory_variables=False)

    for state_v in final_states:
        if state_v != state:
            # print(str(u) + ' -> ' + str(v))
            M = np.zeros(M_shape)
            M.flat[J[V == state_v.value]] = 1

            lw, _ = ndimage.measurements.label(M, structure=structure)
            patch_id = lw.flat[J]

            # unique pixel for a patch
            one_pixel_from_patch = np.column_stack((J, patch_id))
            one_pixel_from_patch = np_drop_duplicates_from_column(one_pixel_from_patch, 1)

            one_pixel_from_patch = one_pixel_from_patch[1:, :]
            one_pixel_from_patch[:, 1] -= 1

            rpt = measure.regionprops_table(lw, properties=['area',
                                                            'inertia_tensor_eigvals'])

            areas = np.array(rpt['area'])

            # return(patches, rpt)
            l1_patch = np.array(rpt['inertia_tensor_eigvals-0'])
            l2_patch = np.array(rpt['inertia_tensor_eigvals-1'])

            eccentricities = np.zeros(areas.shape)
            id_none_mono_pixel_patches = areas > 1

            eccentricities[id_none_mono_pixel_patches] = 1 - np.sqrt(
                l2_patch[id_none_mono_pixel_patches] / l1_patch[id_none_mono_pixel_patches])

            # mono pixel patches are removed
            areas = areas[id_none_mono_pixel_patches]
            eccentricities = eccentricities[id_none_mono_pixel_patches]

            patches[state_v] = BootstrapPatch().set(areas=areas,
                                                    eccentricities=eccentricities)

    return (patches)


"""utils.py -- helper functions for MFDn runs

    - 02/20/17 (pjf): Created, extracted from mfdn.py.
    - 09/05/19 (pjf): Add Nv_for_nuclide.
    - 06/03/20 (pjf): Add check_natorb_base_state.
    - 11/13/20 (pjf): Move physical constants to separate module.
    - 11/14/20 (pjf):
        + Add nuclide_string function.
        + Add N0_for_nuclide function (copied from mfdnres).
    - 12/02/20 (pjf): Allow J<M natorb base states.
    - 07/08/21 (pjf): Check that J of natorb base state matches nuclide.
    - 04/27/22 (pjf): Add hw_from_oscillator_length().
    - 01/03/23 (mac): Add J_sqr_coefficient_for_energy_shift().
"""

import math

import mcscript

from . import constants

################################################################
# strings for descriptors/filenames
################################################################

def nuclide_string(nuclide, **kwargs):
    """Convert (Z,N) to "ZXX-NXX" string.

    Note: This function can be called directly on a task dict. For example:
    >>> nuclide_string(**task)
        "Z02-N02"

    Arguments:
        nuclide (tuple of int): (Z,N) of nuclide
    """
    return "Z{:02d}-N{:02d}".format(*nuclide)

def weight_max_string(truncation):
    """Convert (rank,cutoff) to "wp wn wpp wnn wpn" string.

    Valid truncations:
        ("ob",w1b)
        ("tb",w2b)
        (w1b,w2b)
        (wp,wn,wpp,wnn,wpn) -- TODO

    >>> weight_max_string(("ob",4))
        "4 4 8 8 8"
    >>> weight_max_string(("tb",4))
        "4 4 4 4 4"
    """
    if (truncation[0] == "ob"):
        (code, N) = truncation
        cutoffs = (N, N, 2*N, 2*N, 2*N)
    elif (truncation[0] == "tb"):
        (code, N) = truncation
        cutoffs = (N, N, N, N, N)
    elif (len(truncation) == 2):
        (w1, w2) = truncation
        cutoffs = (w1, w1, w2, w2, w2)
    elif (len(truncation) == 5):
        cutoffs = truncation

    return "{0[0]} {0[1]} {0[2]} {0[3]} {0[4]}".format(cutoffs)

def natural_orbital_indicator(natural_orbital_iteration):
    """Construct natural orbital indicator string."""
    if (natural_orbital_iteration is None):
        indicator = ""
    else:
        indicator = "-no{:1d}".format(natural_orbital_iteration)
    return indicator

################################################################
# oscillator length calculations
################################################################

def oscillator_length(hw):
    """Calculate oscillator length for given oscillator frequency.

    b(hw) = (hbar c)/[(m_N c^2) (hbar omega)]^(1/2)

    Arguments:
        hw (numeric): hbar omega in MeV

    Returns:
        (float): b in fm
    """
    return constants.k_hbar_c/math.sqrt(constants.k_mN_csqr*hw)

def hw_from_oscillator_length(b):
    """Calculate oscillator frequency for given oscillator length.

    hw(b) = (hbar c)^2/[(m_N c^2) (b^2)]

    Arguments:
        b (numeric): oscillator length in fm

    Returns:
        (float): hbar omega in MeV
    """
    return constants.k_hbar_c**2/(constants.k_mN_csqr*b**2)

################################################################
# J^2 term calculation
################################################################

def J_sqr_coefficient_for_energy_shift(M, energy_shift, delta_J=1):
    """Determine coefficient needed on J^2 operator for given energy shift.

    In a J-filtered run of given M, we generally want to shift the J=M+1 states
    upward by at least a given amount relative to the J=M states.  This function
    calculates the coefficient on |J|^2-M*(M+1) needed to accomplish such a
    shift.

    Argument:

        M (float): M for run

        energy_shift (float): desired energy shift

        delta_J (int, optional): difference to next higher angular momentum of interest

    Returns:

        a_J2 (float): coefficient for J^2 operator

    """

    J = M
    Jp = M + delta_J
    a_J2 = energy_shift/(Jp*(Jp+1) - J*(J+1))
    return a_J2

################################################################
# shell model Nv
################################################################

def Nv_for_nuclide(nuclide):
    """Calculate oscillator quantum number of valence shell for given nuclide.

    Arguments:
        nuclide (tuple): (Z,N) for nuclide

    Returns:
        Nv (int): oscilllator quantum number for valence shell
    """

    # each major shell eta=2*n+l (for a spin-1/2 fermion) contains (eta+1)*(eta+2) substates

    Nv = 0
    for species_index in (0,1):
        num_particles = nuclide[species_index]
        eta=0
        while(num_particles>0):
            # discard particles in shell
            shell_degeneracy = (eta+1)*(eta+2)
            num_particles_in_shell = min(num_particles,shell_degeneracy)
            num_particles -= num_particles_in_shell

            # update Nv
            Nv = max(Nv, eta)

            # move to next shell
            eta += 1

    return Nv

################################################################
# shell model N0
################################################################

def N0_for_nuclide(nuclide):
    """Calculate quanta in lowest oscillator configuration for given nuclide.

    Natural parity grade can then be obtained as N0_for_nuclide(nuclide)%2.

    Inspired by spncci lgi::Nsigma0ForNuclide.

    Arguments:
        nuclide (tuple): (Z,N) for nuclide

    Returns:
        N0 (int): number of quanta
    """

    # each major shell eta=2*n+l (for a spin-1/2 fermion) contains (eta+1)*(eta+2) substates

    N0 = 0;
    for species_index in (0,1):
        num_particles = nuclide[species_index]
        eta=0
        while(num_particles>0):
            # add contribution from particles in shell
            shell_degeneracy = (eta+1)*(eta+2)
            num_particles_in_shell = min(num_particles,shell_degeneracy)
            N0 += num_particles_in_shell*eta

            # discard particles in shell
            num_particles -= num_particles_in_shell

            # move to next shell
            eta += 1

    return N0

################################################################
# consistency checks
################################################################

def check_natorb_base_state(task):
    """Perform sanity checks on natural orbital base state quantum numbers."""
    nuclide = task["nuclide"]
    natorb_base_state = task.get("natorb_base_state")
    try:
        (J, g, n) = natorb_base_state
    except TypeError:
        raise mcscript.exception.ScriptError(
            "invalid natorb_base_state: {}".format(natorb_base_state))
    if round(2*J)%2 != sum(nuclide)%2:
        raise mcscript.exception.ScriptError(
            "invalid natorb base state J={:3.1f}".format(J)
        )
    if g not in (0,1):
        raise mcscript.exception.ScriptError(
            "invalid natorb base state g={}".format(g)
        )


def main():
    s = sorted([list(map(int, input().split())) for _ in range(int(input()))], key= lambda x: x[1])
    s1 = [s[0][1]]
    for i in s:
        if i[0] >= s1[-1]:
            s1.append(i[1])
    print(len(s1), ' '.join([str(i) for i in s1]), sep= '\n')

if __name__ == '__main__':
    main()

Жадный_алгоритм_1.py

Жадный_алгоритм_1.py


# -*- coding: utf-8 -*-
import scrapy
from scrapy_splash import SplashRequest

script = """
function main(splash)
    local url = splash.args.url
    assert(splash:go(url))
    assert(splash:wait(5))

    splash:set_viewport_full()

    return {
        png=splash:png(),
        cookies = splash:get_cookies(),
        html = splash:html()
    }
end
"""

script2 = """
function main(splash)
    splash:init_cookies(splash.args.cookies)
    local url = splash.args.url
    assert(splash:go(url))
    assert(splash:wait(0.5))
    return {
        cookies = splash:get_cookies(),
        html = splash:html()
    }
end
"""

class FahasaSpider(scrapy.Spider):
    name = 'fahasa'
    allowed_domains = ['fahasa.com']
    start_urls = [
        "https://www.fahasa.com/sach-trong-nuoc/van-hoc-trong-nuoc.html"
    ]

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(url, self.parse, endpoint='execute',
                                args={'lua_source': script})

    def parse(self, response):
        # Get the next page and yield Request
        next_selector = response.xpath('//*[@title="Next"]/@href')
        # print('------------------------------------------------1')
        # print(next_selector.extract())
        for url in next_selector.extract():
            yield SplashRequest(url, endpoint='execute',
                                args={'lua_source': script2})

        # Get URL in page and yield Request
        url_selector = response.xpath(
            '//*[@class="product-name p-name-list"]/a/@href')
        # print('------------------------------------------------2')
        # print(url_selector.extract())
        for url in url_selector.extract():
            yield SplashRequest(url, callback=self.parse_item,
                                endpoint='execute',
                                args={'lua_source': script2})

    def parse_item(self, response):
        """
        Handle crawl logic here
        """
        print('------------------------------------------------')
        print('Title', response.xpath('//h1').extract()[0])


import logging
from datetime import date, timedelta
from fints.client import FinTS3PinTanClient
import requests
import json
import schedule
import time
import os
import sys

### Bank data
blz = os.environ['BANK_BLZ'] # Your bank's BLZ
username = os.environ['BANK_USERNAME'] # Your login name
pin = os.environ['BANK_PIN'] # Your banking PIN
bank_url = os.environ['BANK_URL'] # your banks fints url
product_id = os.environ['BANK_PRODUCT_ID'] # your fints product id

### Firefly data
token = os.environ['FIREFLY_TOKEN']
firefly_url = os.environ['FIREFLY_URL']
headers = {'Authorization' : 'Bearer ' + token, 'Accept' : 'application/json', 'Content-Type' : 'application/json'}

req = requests.get(firefly_url + '/api/v1/accounts', headers=headers)

if(req.status_code != 200):
    logging.error("Could not get accounts from Firefly. Aborting.")
    sys.exit()

account_ids = {} # a map of IBAN to Firefly account id

resp = json.loads(req.text)

for a in resp["data"]:
    if a["type"] == "accounts" and a["attributes"]["iban"] is not None:
        account_ids[a["attributes"]["iban"]] = int(a["id"])

logging.info("Retrieved accounts from firefly")

# Establish connection
logging.basicConfig(level=logging.INFO)
f = FinTS3PinTanClient(
    blz,
    username,
    pin,
    bank_url,
    product_id=product_id
)

def create_transactions(account, transactions):
    for transaction in transactions:
        t = {
            "amount": abs(transaction.data['amount'].amount).to_eng_string(),
            "currency_code": transaction.data['amount'].currency,
            "date": transaction.data['date'].strftime('%Y-%m-%dT08:00+02:00'),
            "reconciled": False,
            "description": transaction.data['purpose'],
            "external_id": transaction.data['id']
        }

        if transaction.data['status'] == "C": # a deposit
            t["type"] = "deposit"
            t["source_name"] = transaction.data["applicant_name"]
            t["destination_id"] = account_ids[account.iban]
        else:
            t["type"] = "withdrawal"
            t["source_id"] = account_ids[account.iban]
            t["destination_name"] = transaction.data["applicant_name"]

        data = {
            "error_if_duplicate_hash": True,
            "apply_rules": True,
            "group_title": transaction.data['posting_text'],
            "transactions": [t]
        }
        r = requests.post(firefly_url + '/api/v1/transactions', data=json.dumps(data), headers=headers)

        if(r.status_code != 200 and "Duplicate of transaction" not in r.text):
            logging.error('Failed posting transaction to api with error code: ' + str(r.status_code) + '.')
            logging.error('Error message is: ' + r.text)
            logging.error(json.dumps(data))

def get_transactions():
    with f:
        # Since PSD2, a TAN might be needed for dialog initialization. Let's check if there is one required
        if f.init_tan_response:
            logging.error('Bank access requires TAN which is not supported.')

        # Fetch accounts
        accounts = f.get_sepa_accounts()

        logging.info('Retrieved ' + str(len(accounts)) + ' accounts from bank.')

        # get the transactions for each account
        for account in accounts:
            transactions = f.get_transactions(account, date.today() - timedelta(days=7), date.today())
            logging.info('Retrieved ' + str(len(transactions)) + ' for account ' + account.iban + ' that took place in the last 7 days.')
            create_transactions(account, transactions)

schedule.every().day.at("10:00").do(get_transactions)

logging.info("Started scheduled job")

while True:
    schedule.run_pending()
    time.sleep(1)


# -*- coding: utf-8 -*-
"""
Django settings for DC Traffic Tickets project.

For more information on this file, see
https://docs.djangoproject.com/en/dev/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/dev/ref/settings/
"""
from __future__ import absolute_import, unicode_literals

import environ

ROOT_DIR = environ.Path(__file__) - 3  # (dc_traffic_tickets/config/settings/common.py - 3 = dc_traffic_tickets/)
APPS_DIR = ROOT_DIR.path('dc_traffic_tickets')

env = environ.Env()

# APP CONFIGURATION
# ------------------------------------------------------------------------------
DJANGO_APPS = (
    # Default Django apps:
    'blog',
    'wagtail.wagtailforms',
    'wagtail.wagtailredirects',
    'wagtail.wagtailembeds',
    'wagtail.wagtailsites',
    'wagtail.wagtailusers',
    'wagtail.wagtailsnippets',
    'wagtail.wagtaildocs',
    'wagtail.wagtailimages',
    'wagtail.wagtailsearch',
    'wagtail.wagtailadmin',
    'wagtail.wagtailcore',

    'taggit',
    'modelcluster',

    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Useful template tags:
    'django.contrib.humanize',
    'django.contrib.gis',
    # Admin
    'django.contrib.admin',
)
THIRD_PARTY_APPS = (
    'crispy_forms',  # Form layouts
    'allauth',  # registration
    'allauth.account',  # registration
    'allauth.socialaccount',  # registration
    'cachalot', # caching plug in
    'leaflet',
    'corsheaders',
    'raven.contrib.django.raven_compat',
    'pygmentify',
)

# Apps specific for this project go here.
LOCAL_APPS = (
    # custom users app
    'dc_traffic_tickets.users.apps.UsersConfig',
    # Your stuff: custom apps go here
    'django_filters',
    'rest_framework',
    'rest_framework_gis',
    'rest_framework.authtoken',
    'api',
    'dataviz',
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS

# MIDDLEWARE CONFIGURATION
# ------------------------------------------------------------------------------
MIDDLEWARE_CLASSES = (
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

    'wagtail.wagtailcore.middleware.SiteMiddleware',
    'wagtail.wagtailredirects.middleware.RedirectMiddleware',
)

# MIGRATIONS CONFIGURATION
# ------------------------------------------------------------------------------
MIGRATION_MODULES = {
    'sites': 'dc_traffic_tickets.contrib.sites.migrations'
}

# DEBUG
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
DEBUG = env.bool('DJANGO_DEBUG', False)

# FIXTURE CONFIGURATION
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS
FIXTURE_DIRS = (
    str(APPS_DIR.path('fixtures')),
)

# EMAIL CONFIGURATION
# ------------------------------------------------------------------------------
EMAIL_BACKEND = env('DJANGO_EMAIL_BACKEND', default='django.core.mail.backends.smtp.EmailBackend')

# MANAGER CONFIGURATION
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
ADMINS = (
    ("""Nathan""", 'nathan.danielsen@gmail.com'),
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#managers
MANAGERS = ADMINS

# GENERAL CONFIGURATION
# ------------------------------------------------------------------------------
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'UTC'

# See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code
LANGUAGE_CODE = 'en-us'

# See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id
SITE_ID = 1

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
USE_I18N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n
USE_L10N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
USE_TZ = True

# TEMPLATE CONFIGURATION
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#templates
TEMPLATES = [
    {
        # See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
        'DIRS': [
            str(APPS_DIR.path('templates')),
        ],
        'OPTIONS': {
            # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
            'debug': DEBUG,
            # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
            # https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types
            'loaders': [
                'django.template.loaders.filesystem.Loader',
                'django.template.loaders.app_directories.Loader',
            ],
            # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.template.context_processors.i18n',
                'django.template.context_processors.media',
                'django.template.context_processors.static',
                'django.template.context_processors.tz',
                'django.contrib.messages.context_processors.messages',
                # Your stuff: custom template context processors go here
            ],
        },
    },
]

# See: http://django-crispy-forms.readthedocs.io/en/latest/install.html#template-packs
CRISPY_TEMPLATE_PACK = 'bootstrap3'

# STATIC FILE CONFIGURATION
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = str(ROOT_DIR('staticfiles'))

# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = '/static/'

# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = (
    str(APPS_DIR.path('static')),
)

# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

# MEDIA CONFIGURATION
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = str(APPS_DIR('media'))

# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = '/media/'

# URL Configuration
# ------------------------------------------------------------------------------
ROOT_URLCONF = 'config.urls'

# See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application
WSGI_APPLICATION = 'config.wsgi.application'

# AUTHENTICATION CONFIGURATION
# ------------------------------------------------------------------------------
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',
)

# Some really nice defaults
ACCOUNT_AUTHENTICATION_METHOD = 'username'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'

ACCOUNT_ALLOW_REGISTRATION = env.bool('DJANGO_ACCOUNT_ALLOW_REGISTRATION', True)
ACCOUNT_ADAPTER = 'dc_traffic_tickets.users.adapters.AccountAdapter'
SOCIALACCOUNT_ADAPTER = 'dc_traffic_tickets.users.adapters.SocialAccountAdapter'

# Custom user app defaults
# Select the correct user model
AUTH_USER_MODEL = 'users.User'
LOGIN_REDIRECT_URL = 'users:redirect'
LOGIN_URL = 'account_login'

# SLUGLIFIER
AUTOSLUG_SLUGIFY_FUNCTION = 'slugify.slugify'

# django-compressor
# ------------------------------------------------------------------------------

# Location of root django.contrib.admin URL, use {% url 'admin:index' %}
ADMIN_URL = r'^admin/'

# # WEBPACK
# # ------------------------------------------------------------------------------
# INSTALLED_APPS += ('webpack_loader',)
# # Webpack Local Stats file
# STATS_FILE = ROOT_DIR('webpack-stats.json')
# # Webpack config
# WEBPACK_LOADER = {
#     'DEFAULT': {
#         'STATS_FILE': STATS_FILE
#     }
# }

# Your common stuff: Below this line define 3rd party library settings

REST_FRAMEWORK = {
    'PAGE_SIZE': 500
}

REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = (
    'rest_framework.authentication.TokenAuthentication',
    'rest_framework.authentication.SessionAuthentication',
    )

REST_FRAMEWORK['DEFAULT_PERMISSION_CLASSES'] = (
        'rest_framework.permissions.IsAuthenticated',
    )

LEAFLET_CONFIG = {
    # conf here
    'TILES': 'https://stamen-tiles.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png',
    # 'TILES': 'https://a.tile.openstreetmap.org/{z}/{x}/{y}.png',
    'ATTRIBUTION_PREFIX': 'Powered by django-leaflet and DC Open Data Portal',
    'SCALE': 'both',
    'SPATIAL_EXTENT': (-77.193339, 38.783691, -76.83306, 39.016687),
    'DEFAULT_CENTER': (38.9046, -77.0238),
    'DEFAULT_ZOOM': 8,
    'MIN_ZOOM': 10,
    'MAX_ZOOM': 18,
    # 'MINIMAP': True,
    # 'FORCE_IMAGE_PATH': True,
    # 'PLUGINS': {
    #     'name-of-plugin': {
    #         'css': ['relative/path/to/stylesheet.css', '/root/path/to/stylesheet.css'],
    #         'js': 'http://absolute-url.example.com/path/to/script.js',
    #         'auto-include': True,
    #     },
    #     . . .
    # }
}

CORS_ORIGIN_ALLOW_ALL = False

##### SQL Explorer
# EXPLORER_SCHEMA_INCLUDE_APPS = ('api.ParkingViolation',' api.ParkingViolationDataFiles',)
EXPLORER_SCHEMA_EXCLUDE_APPS = ('allauth.account', 'allauth.socialaccount', 'rest_framework.authtoken',  'corsheaders', 'django.contrib.sites', 'explorer', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.admin', 'dc_traffic_tickets.users', 'django.contrib.gis',)
EXPLORER_TOKEN_AUTH_ENABLED = True
EXPLORER_TOKEN = 'DEMO_TOKEN'

########### PYGMENTS Config
PYGMENTIFY_CSSCLASS = 'code-highlight'
PYGMENTIFY_STYLE = 'xcode'

########### WAGTAIL CONFIG
WAGTAIL_SITE_NAME = 'DC Traffic Data Project'
WAGTAIL_APPEND_SLASH = False

# Override the search results template for wagtailsearch
WAGTAILSEARCH_RESULTS_TEMPLATE = 'cms/search_results.html'
WAGTAILSEARCH_RESULTS_TEMPLATE_AJAX = 'cms/includes/search_listing.html'

# # Replace the search backend
# WAGTAILSEARCH_BACKENDS = {
#     'default': {
#         'BACKEND': 'wagtail.wagtailsearch.backends.elasticsearch',
#         'INDEX': 'cms'
#     }
# }

WAGTAIL_ADMIN_URL = env('WAGTAIL_ADMIN_URL')
WAGTAILEMBEDS_EMBEDLY_KEY = env('WAGTAILEMBEDS_EMBEDLY_KEY')

WAGTAILIMAGES_MAX_UPLOAD_SIZE = 20 * 1024 * 1024  # i.e. 20MB
WAGTAIL_PASSWORD_MANAGEMENT_ENABLED = True
WAGTAILADMIN_NOTIFICATION_FROM_EMAIL = 'noreply@m.dctraffictickets.net'

WAGTAILADMIN_NOTIFICATION_USE_HTML = True
WAGTAIL_ENABLE_UPDATE_CHECK = True
PASSWORD_REQUIRED_TEMPLATE = 'cms/password_required.html'
TAGGIT_CASE_INSENSITIVE = True
WAGTAIL_ALLOW_UNICODE_SLUGS = True


import matplotlib
import matplotlib.pyplot as plt
import textwrap

import plotting_util as u

def pdplot(pddata, kind='bar', title=None, xlabel=None, ylabel=None, legend=[],
    xrot=-45, xtick_labels=None, label_length=15, label_clip=-1,
    xbound=[None, None], ybound=[None, None],  **kwargs):
    kwargs['rot'] = xrot
    #if type(data) is tuple or type(data) is list:
    #    pass
    #else:
    ax = pddata.plot(kind=kind, **kwargs)
    #plt.axhline(0, color='k')
    if xbound:
        if xbound[0]:
            ax.set_xbound(lower=xbound[0])
        if xbound[1]:
            ax.set_xbound(upper=xbound[1])
    if ybound:
        if ybound[0]:
            ax.set_ybound(lower=ybound[0])
        if ybound[1]:
            ax.set_ybound(upper=ybound[1])
    if xlabel:
        ax.set_xlabel(xlabel)
    if ylabel:
        ax.set_ylabel(ylabel)
    if title:
        ax.set_title(title, fontsize="xx-large", y=1.04)

    if xtick_labels:
        names = xtick_labels
    else:
        names = pddata.index
    labels_clipped = [u.label_clipper(text,label_clip) for text in names]
    labels = [textwrap.fill(text,label_length) for text in labels_clipped]
    ax.set_xticklabels(labels)

    if legend:
        ax.legend(legend, loc='best')
    return ax

def nars_graphby_mc(nars, nars_s1, nars_s2, nars_s3, question, **kwargs):
    na = nars.associate_mc(nars_s1, nars_s2, nars_s3, [question])
    nam = nars.associate_mc_mean(na, question)
    na_means = nam.loc[['nars_s1_mean','nars_s2_mean','nars_s3_mean']]
    na_err = nam.loc[['nars_s1_std','nars_s2_std','nars_s3_std']]
    na_means.index = ["NARS S1", "NARS S2", "NARS S3"]
    na_err.index = ["NARS S1", "NARS S2", "NARS S3"]
    ax = pdplot(na_means, **kwargs, yerr=na_err)
    return ax
def nars_graphby_ma(nars, nars_s1, nars_s2, nars_s3, question, **kwargs):
    na = nars.associate_ma(nars_s1, nars_s2, nars_s3, [question])
    nam = nars.associate_ma_mean(na, question)
    na_means = nam.loc[['nars_s1_mean','nars_s2_mean','nars_s3_mean']]
    na_err = nam.loc[['nars_s1_std','nars_s2_std','nars_s3_std']]
    na_means.index = ["NARS S1", "NARS S2", "NARS S3"]
    na_err.index = ["NARS S1", "NARS S2", "NARS S3"]
    ax = pdplot(na_means, **kwargs, yerr=na_err)
    return ax
def nars_graphby_info(nars, nars_assoc, info_labels, **kwargs):
    nam = nars.associate_byinfo_mean(nars_assoc, info_labels)
    na_means = nam.loc[['nars_s1_mean','nars_s2_mean','nars_s3_mean']]
    na_err = nam.loc[['nars_s1_std','nars_s2_std','nars_s3_std']]
    na_means.index = ["NARS S1", "NARS S2", "NARS S3"]
    na_err.index = ["NARS S1", "NARS S2", "NARS S3"]
    ax = pdplot(na_means, **kwargs, yerr=na_err)
    return ax


import json
import requests
import xlrd
from web3 import Web3
from eth_abi import encode_single, encode_abi

headers = {"Connection": "close", "Cache-Control": "max-age=0", "sec-ch-ua": "\" Not;A Brand\";v=\"99\", \"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"", "sec-ch-ua-mobile": "?0", "DNT": "1", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Sec-Fetch-Site": "none", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-User": "?1", "Sec-Fetch-Dest": "document", "Accept-Encoding": "gzip, deflate", "Accept-Language": "en,zh-CN;q=0.9,zh;q=0.8"}

w3 = Web3(Web3.HTTPProvider('https://bsc-dataseed1.binance.org'))
abi = json.loads('[{"constant": true,"inputs": [{"name": "who", "type": "address"}],"name": "balanceOf","outputs": [{"name": "", "type": "uint256"}],"payable": false,"stateMutability": "view","type": "function"}, {"inputs": [{"internalType": "uint256", "name": "cumulativePayout", "type": "uint256"},{"internalType": "bytes", "name": "issuerSig", "type": "bytes"}],"name": "cashCheque","outputs": [],"stateMutability": "nonpayable","type": "function"}]')
GPS_ADDRESS = w3.toChecksumAddress('0x5e772acf0f20b0315391021e0884cb1f1aa4545c')
GPS_CONTRACT = w3.eth.contract(address=GPS_ADDRESS, abi=abi)

#表格第一列放钱包地址，第二列放私钥
file_name = "62ABI.xlsx"

## 获取钱包地址
def get_addresses():
    xls = xlrd.open_workbook(file_name)
    addresses = xls.sheets()[0].col_values(0)
    private_secret = xls.sheets()[0].col_values(1)
    #print("一共有 " + str(len(addresses)) + " 地址")
    return addresses,private_secret

## 获取拥有的gps
def get_gps(address):
    address = Web3.toChecksumAddress(address)
    return GPS_CONTRACT.functions.balanceOf(address).call()

## 获取交易所需参数
def get_api(address,private_secret):
    private_secret = private_secret
    url = 'https://api.gpfs.xyz/v1/cheque?address=' + address
    res = requests.get(url, headers=headers)
    text = json.loads(res.text)
    amount = text['data']['amount']
    paid_out = text['data']['paid_out']
    signature = text['data']['signature']
    sedsendSigned(address,amount,signature,private_secret)

def get_count(address):
    nonce = w3.toHex(w3.eth.get_transaction_count(address))
    return nonce

def sedsendSigned(address,amount,signature,private_secret):
    amount_16 = w3.toInt(encode_single('uint256', amount))
    signature_16 = w3.toBytes(hexstr=signature)
    data = GPS_CONTRACT.encodeABI(fn_name="cashCheque", args=[amount_16,signature_16])
    rawTx = {
        'from': address,
        'to': GPS_ADDRESS,
        'value': w3.toHex(w3.toWei('0', 'ether')),
        'nonce': get_count(address),
        'gas': w3.toHex(100000),
        'gasPrice': w3.toHex(w3.toWei('5', 'gwei')),
        'data': data
    }
    signed_txn = w3.eth.account.sign_transaction(rawTx,private_secret)
    txn_hash = w3.toHex(w3.eth.send_raw_transaction(signed_txn.rawTransaction))
    print("地址:{0}\t交易hash:{1}".format(address,txn_hash))
    try:
        status = w3.eth.wait_for_transaction_receipt(txn_hash,timeout=20)['status']
        if status:
            print("交易成功")
    except:
        print("报错")

if __name__ == '__main__':
    key = get_addresses()
    for i in range(len(key[0])):
        address = key[0][i]
        private_secret = key[1][i]
        get_api(w3.toChecksumAddress(address),private_secret)


import matplotlib.pyplot as plt
import pandas as pd

d = pd.read_csv('Data/276城_3source_by_ct_V3.csv')

df = d.groupby('age_feb20').mean()['locked_down']
plt.bar(x=df.index, height= df)

df = d.groupby('age_feb20').mean()['xc_lockdown']
plt.bar(x=df.index, height= df)

plt.show()

import seaborn as sns
sns.set(style="whitegrid")

# penguins = sns.load_dataset("penguins")

# Draw a nested barplot by species and sex
g = sns.catplot(
    data=d, kind="bar",
    x="age_feb20", y="locked_down",alpha=.6, height=6
)
g.despine(left=True)
g.set_axis_labels("", "Body mass (g)")
# g.legend.set_title("")
plt.show()


import AppInfo

# Based on the work of Lena "Teekeks" <info@teawork.de>
import urllib.parse
import uuid
from typing import Union
from json import JSONDecodeError
from aiohttp.web import Request
import webbrowser
from aiohttp import web
import asyncio
from threading import Thread
from time import sleep
from os import path
import requests
from concurrent.futures._base import CancelledError
from logging import getLogger, Logger

class TwitchOauth:
    port: int = 17563
    host: str = "0.0.0.0"
    __state: str = ""

    __server_running: bool = False
    __loop: Union["asyncio.AbstractEventLoop", None] = None
    __runner: Union["web.AppRunner", None] = None
    __thread: Union["threading.Thread", None] = None

    __user_token: Union[str, None] = None

    __can_close: bool = False

    def __build_runner(self):
        app = web.Application()
        app.add_routes([web.get("/", self.__handle_callbackGet)])
        app.add_routes([web.post("/", self.__handle_callbackPost)])
        return web.AppRunner(app)

    async def __run_check(self):
        while not self.__can_close:
            try:
                await asyncio.sleep(1)
            except:
                self.__server_running = False
                pass
        for task in asyncio.all_tasks(self.__loop):
            task.cancel()
            self.__server_running = False

    def __run(self, runner: "web.AppRunner"):
        try:
            self.__runner = runner
            self.__loop = asyncio.new_event_loop()
            asyncio.set_event_loop(self.__loop)
            self.__loop.run_until_complete(runner.setup())
            site = web.TCPSite(runner, self.host, self.port)
            self.__loop.run_until_complete(site.start())
            self.__server_running = True
            self.__loop.run_until_complete(self.__run_check())
        except:
            self.__server_running = False
            pass

    def __start(self):
        self.__thread = Thread(target=self.__run, args=(self.__build_runner(),))
        self.__thread.start()

    def stop(self):
        """Manually stop the flow
        :rtype: None
        """
        self.__can_close = True
        self.__server_running = False

    async def __handle_callbackGet(self, request: "web.Request"):
        fn = path.join(path.dirname(__file__), "Failed.html")
        val = str(request.message)
        if not str.__contains__(val, "access_denied"):
            # Assume that everything else is fine and verify in the post.
            fn = path.join(path.dirname(__file__), "Success.html")
        fd = ""
        with open(fn, "r") as f:
            fd = f.read()

        return web.Response(text=fd, content_type="text/html")

    async def __handle_callbackPost(self, request: "web.Request"):
        val = str(request.content._buffer)
        fn = path.join(path.dirname(__file__), "Failed.html")
        if not str.__contains__(val, "access_denied"):
            val = val.split("#")[1].split("\\r\\n")[0].split("&")

            # invalid state!
            if val[2].split("=")[1] != self.__state:
                self.__server_running = False
                return web.Response(status=401)

            self.__user_token = val[0].split("=")[1]
            if self.__user_token is None:
                # must provide code
                self.__server_running = False
                return web.Response(status=400)

            fn = path.join(path.dirname(__file__), "Success.html")
        else:
            self.__user_token = "  "

        fd = ""
        with open(fn, "r") as f:
            fd = f.read()

        return web.Response(text=fd, content_type="text/html")

    def authenticate(self):
        self.__start()
        # wait for the server to start up
        while not self.__server_running:
            sleep(0.01)

        self.__state = str(uuid.uuid4())
        url = (
            "https://id.twitch.tv/oauth2/authorize?"
            + "response_type=token"
            + "&client_id="
            + AppInfo.ClientId
            + "&redirect_uri="
            + AppInfo.RedirectUri
            + "&scope=chat:read chat:edit"
            + "&force_verify=true"
            + "&state="
            + self.__state
        )
        # open in browser

        webbrowser.open(url, new=2)
        while self.__user_token is None and self.__server_running:
            sleep(0.1)
        self.stop()
        self.__state = ""
        return self.__user_token


import plotly.express as px
import pandas as pd

df = pd.read_csv("https://raw.githubusercontent.com/Tymiec/Formula_1_Visualized/master/testing/heatmap_nationalities/nationalities_counted.csv")

fig = px.pie(df,
    values="value",
    names="country_code",
    hole=.3,
    title="Narodowości Formuły 1",
    labels="country_code")
fig.update_traces(textposition='inside', textinfo='percent+label')

fig.show()


# recreating the whole single linkedlist concepts
# - instantiate the node and linkedlist(make iterable)
# - inserting a linkedlist functionality
# - traversing a linkedlist functionality by location
# - search a linkedlist by nodevalue
# - delete a node by location
# - delete all nodes

class Node:
    def __init__(self, value) -> None:
        self.value = value
        self.next = None

class SLinkedList:
    def __init__(self) -> None:
        self.head = None
        self.tail = None

    def __iter__(self):
        node = self.head
        while node:
            yield node
            node = node.next

    def insertSLL(self,value,location):
        new_node = Node(value)
        if self.head is None:
            self.head = new_node
            self.tail = new_node
        else:
            if location == 0:
                new_node.next = self.head
                self.head = new_node
            elif location == 1:
                new_node.next = None
                self.tail.next = new_node
                self.tail = new_node
            else:
                i = 0
                node = self.head
                while i < location - 1:
                    node = self.head.next
                    i += 1
                new_node.next = node.next
                node.next = new_node

    def traverseSLL(self,location):
        if self.head is None:
            return "The singly linkedlist does not exist"
        else:
            i  = 0
            node = self.head
            while i < location - 1:
                node = node.next
                i += 1
            return f"The node value {node.value} is here located at index location {location}"

    def searchSLL(self, nodeValue):
        if self.head is None:
            return "The singly linkedlist does not exist"
        else:
            node = self.head

            while node:
                if node.value == nodeValue:
                    break
                node = node.next
            return f"The nodeValue has been found. {node.value}"

    def deleteNode(self, location):
        if self.head == self.tail:
            self.head = None
            self.tail = None
        else:
            if location == 0:
                self.head = self.head.next
            elif location == 1:
                i = 0
                node = self.head
                while node:
                    node = node.next
                    i += 1

                node.next = None
                self.tail = node
            else:
                i = 0
                node = self.head
                while i < location - 1 :
                    node = node.next
                    i += 1
                next_node = node.next
                node.next = next_node.next

    def reverseSLL(self):
        previous = None
        current = self.head
        next = None

        while current:
            next = current.next
            current.next = previous
            previous = current
            current = next
        self.head = previous

sLL = SLinkedList()
sLL.insertSLL(1,0)
sLL.insertSLL(2,0)
sLL.insertSLL(3,0)
sLL.insertSLL(8,1)
sLL.insertSLL(9,1)
sLL.insertSLL(8,2)
print([each.value for each in sLL])
# sLL.deleteNode(0)
sLL.deleteNode(4)
print(sLL.traverseSLL(3))
print(sLL.searchSLL(9))
print([each.value for each in sLL])

sLL.reverseSLL()
print("Reversed LinkedList ",[each.value for each in sLL])


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/

# The content of this file comes orginally from automationutils.py
# and *should* be revised.

import re
from operator import itemgetter

RE_DOCSHELL = re.compile("I\/DocShellAndDOMWindowLeak ([+\-]{2})DOCSHELL")
RE_DOMWINDOW = re.compile("I\/DocShellAndDOMWindowLeak ([+\-]{2})DOMWINDOW")

class ShutdownLeaks(object):

    """
    Parses the mochitest run log when running a debug build, assigns all leaked
    DOM windows (that are still around after test suite shutdown, despite running
    the GC) to the tests that created them and prints leak statistics.
    """

    def __init__(self, logger):
        self.logger = logger
        self.tests = []
        self.leakedWindows = {}
        self.hiddenWindowsCount = 0
        self.leakedDocShells = set()
        self.hiddenDocShellsCount = 0
        self.numDocShellCreatedLogsSeen = 0
        self.numDocShellDestroyedLogsSeen = 0
        self.numDomWindowCreatedLogsSeen = 0
        self.numDomWindowDestroyedLogsSeen = 0
        self.currentTest = None
        self.seenShutdown = set()

    def log(self, message):
        action = message["action"]

        # Remove 'log' when clipboard is gone and/or structured.
        if action in ("log", "process_output"):
            line = message["message"] if action == "log" else message["data"]

            m = RE_DOMWINDOW.search(line)
            if m:
                self._logWindow(line, m.group(1) == "++")
                return

            m = RE_DOCSHELL.search(line)
            if m:
                self._logDocShell(line, m.group(1) == "++")
                return

            if line.startswith("Completed ShutdownLeaks collections in process"):
                pid = int(line.split()[-1])
                self.seenShutdown.add(pid)
        elif action == "test_start":
            fileName = message["test"].replace(
                "chrome://mochitests/content/browser/", ""
            )
            self.currentTest = {
                "fileName": fileName,
                "windows": set(),
                "docShells": set(),
            }
        elif action == "test_end":
            # don't track a test if no windows or docShells leaked
            if self.currentTest and (
                self.currentTest["windows"] or self.currentTest["docShells"]
            ):
                self.tests.append(self.currentTest)
            self.currentTest = None

    def process(self):
        failures = 0

        if not self.seenShutdown:
            self.logger.error(
                "TEST-UNEXPECTED-FAIL | ShutdownLeaks | process() called before end of test suite"
            )
            failures += 1

        if (
            self.numDocShellCreatedLogsSeen == 0
            or self.numDocShellDestroyedLogsSeen == 0
        ):
            self.logger.error(
                "TEST-UNEXPECTED-FAIL | did not see DOCSHELL log strings."
                " this occurs if the DOCSHELL logging gets disabled by"
                " something. %d created seen %d destroyed seen"
                % (self.numDocShellCreatedLogsSeen, self.numDocShellDestroyedLogsSeen)
            )
            failures += 1
        else:
            self.logger.info(
                "TEST-INFO | Confirming we saw %d DOCSHELL created and %d destroyed log"
                " strings."
                % (self.numDocShellCreatedLogsSeen, self.numDocShellDestroyedLogsSeen)
            )

        if (
            self.numDomWindowCreatedLogsSeen == 0
            or self.numDomWindowDestroyedLogsSeen == 0
        ):
            self.logger.error(
                "TEST-UNEXPECTED-FAIL | did not see DOMWINDOW log strings."
                " this occurs if the DOMWINDOW logging gets disabled by"
                " something%d created seen %d destroyed seen"
                % (self.numDomWindowCreatedLogsSeen, self.numDomWindowDestroyedLogsSeen)
            )
            failures += 1
        else:
            self.logger.info(
                "TEST-INFO | Confirming we saw %d DOMWINDOW created and %d destroyed log"
                " strings."
                % (self.numDomWindowCreatedLogsSeen, self.numDomWindowDestroyedLogsSeen)
            )

        for test in self._parseLeakingTests():
            for url, count in self._zipLeakedWindows(test["leakedWindows"]):
                self.logger.error(
                    "TEST-UNEXPECTED-FAIL | %s | leaked %d window(s) until shutdown "
                    "[url = %s]" % (test["fileName"], count, url)
                )
                failures += 1

            if test["leakedWindowsString"]:
                self.logger.info(
                    "TEST-INFO | %s | windows(s) leaked: %s"
                    % (test["fileName"], test["leakedWindowsString"])
                )

            if test["leakedDocShells"]:
                self.logger.error(
                    "TEST-UNEXPECTED-FAIL | %s | leaked %d docShell(s) until "
                    "shutdown" % (test["fileName"], len(test["leakedDocShells"]))
                )
                failures += 1
                self.logger.info(
                    "TEST-INFO | %s | docShell(s) leaked: %s"
                    % (
                        test["fileName"],
                        ", ".join(
                            [
                                "[pid = %s] [id = %s]" % x
                                for x in test["leakedDocShells"]
                            ]
                        ),
                    )
                )

            if test["hiddenWindowsCount"] > 0:
                # Note: to figure out how many hidden windows were created, we divide
                # this number by 2, because 1 hidden window creation implies in
                # 1 outer window + 1 inner window.
                # pylint --py3k W1619
                self.logger.info(
                    "TEST-INFO | %s | This test created %d hidden window(s)"
                    % (test["fileName"], test["hiddenWindowsCount"] / 2)
                )

            if test["hiddenDocShellsCount"] > 0:
                self.logger.info(
                    "TEST-INFO | %s | This test created %d hidden docshell(s)"
                    % (test["fileName"], test["hiddenDocShellsCount"])
                )

        return failures

    def _logWindow(self, line, created):
        pid = self._parseValue(line, "pid")
        serial = self._parseValue(line, "serial")
        self.numDomWindowCreatedLogsSeen += 1 if created else 0
        self.numDomWindowDestroyedLogsSeen += 0 if created else 1

        # log line has invalid format
        if not pid or not serial:
            self.logger.error(
                "TEST-UNEXPECTED-FAIL | ShutdownLeaks | failed to parse line"
            )
            self.logger.error("TEST-INFO | ShutdownLeaks | Unparsable line <%s>" % line)
            return

        key = (pid, serial)

        if self.currentTest:
            windows = self.currentTest["windows"]
            if created:
                windows.add(key)
            else:
                windows.discard(key)
        elif int(pid) in self.seenShutdown and not created:
            url = self._parseValue(line, "url")
            if not self._isHiddenWindowURL(url):
                self.leakedWindows[key] = url
            else:
                self.hiddenWindowsCount += 1

    def _logDocShell(self, line, created):
        pid = self._parseValue(line, "pid")
        id = self._parseValue(line, "id")
        self.numDocShellCreatedLogsSeen += 1 if created else 0
        self.numDocShellDestroyedLogsSeen += 0 if created else 1

        # log line has invalid format
        if not pid or not id:
            self.logger.error(
                "TEST-UNEXPECTED-FAIL | ShutdownLeaks | failed to parse line"
            )
            self.logger.error("TEST-INFO | ShutdownLeaks | Unparsable line <%s>" % line)
            return

        key = (pid, id)

        if self.currentTest:
            docShells = self.currentTest["docShells"]
            if created:
                docShells.add(key)
            else:
                docShells.discard(key)
        elif int(pid) in self.seenShutdown and not created:
            url = self._parseValue(line, "url")
            if not self._isHiddenWindowURL(url):
                self.leakedDocShells.add(key)
            else:
                self.hiddenDocShellsCount += 1

    def _parseValue(self, line, name):
        match = re.search("\[%s = (.+?)\]" % name, line)
        if match:
            return match.group(1)
        return None

    def _parseLeakingTests(self):
        leakingTests = []

        for test in self.tests:
            leakedWindows = [id for id in test["windows"] if id in self.leakedWindows]
            test["leakedWindows"] = [self.leakedWindows[id] for id in leakedWindows]
            test["hiddenWindowsCount"] = self.hiddenWindowsCount
            test["leakedWindowsString"] = ", ".join(
                ["[pid = %s] [serial = %s]" % x for x in leakedWindows]
            )
            test["leakedDocShells"] = [
                id for id in test["docShells"] if id in self.leakedDocShells
            ]
            test["hiddenDocShellsCount"] = self.hiddenDocShellsCount
            test["leakCount"] = len(test["leakedWindows"]) + len(
                test["leakedDocShells"]
            )

            if (
                test["leakCount"]
                or test["hiddenWindowsCount"]
                or test["hiddenDocShellsCount"]
            ):
                leakingTests.append(test)

        return sorted(leakingTests, key=itemgetter("leakCount"), reverse=True)

    def _zipLeakedWindows(self, leakedWindows):
        counts = []
        counted = set()

        for url in leakedWindows:
            if url not in counted:
                counts.append((url, leakedWindows.count(url)))
                counted.add(url)

        return sorted(counts, key=itemgetter(1), reverse=True)

    def _isHiddenWindowURL(self, url):
        return (
            url == "resource://gre-resources/hiddenWindow.html"
            or url == "chrome://browser/content/hiddenWindowMac.xhtml"  # Win / Linux
        )  # Mac

class LSANLeaks(object):

    """
    Parses the log when running an LSAN build, looking for interesting stack frames
    in allocation stacks, and prints out reports.
    """

    def __init__(self, logger):
        self.logger = logger
        self.inReport = False
        self.fatalError = False
        self.symbolizerError = False
        self.foundFrames = set([])
        self.recordMoreFrames = None
        self.currStack = None
        self.maxNumRecordedFrames = 4

        # Don't various allocation-related stack frames, as they do not help much to
        # distinguish different leaks.
        unescapedSkipList = [
            "malloc",
            "js_malloc",
            "js_arena_malloc",
            "malloc_",
            "__interceptor_malloc",
            "moz_xmalloc",
            "calloc",
            "js_calloc",
            "js_arena_calloc",
            "calloc_",
            "__interceptor_calloc",
            "moz_xcalloc",
            "realloc",
            "js_realloc",
            "js_arena_realloc",
            "realloc_",
            "__interceptor_realloc",
            "moz_xrealloc",
            "new",
            "js::MallocProvider",
        ]
        self.skipListRegExp = re.compile(
            "^" + "|".join([re.escape(f) for f in unescapedSkipList]) + "$"
        )

        self.startRegExp = re.compile(
            "==\d+==ERROR: LeakSanitizer: detected memory leaks"
        )
        self.fatalErrorRegExp = re.compile(
            "==\d+==LeakSanitizer has encountered a fatal error."
        )
        self.symbolizerOomRegExp = re.compile(
            "LLVMSymbolizer: error reading file: Cannot allocate memory"
        )
        self.stackFrameRegExp = re.compile("    #\d+ 0x[0-9a-f]+ in ([^(</]+)")
        self.sysLibStackFrameRegExp = re.compile(
            "    #\d+ 0x[0-9a-f]+ \(([^+]+)\+0x[0-9a-f]+\)"
        )

    def log(self, line):
        if re.match(self.startRegExp, line):
            self.inReport = True
            return

        if re.match(self.fatalErrorRegExp, line):
            self.fatalError = True
            return

        if re.match(self.symbolizerOomRegExp, line):
            self.symbolizerError = True
            return

        if not self.inReport:
            return

        if line.startswith("Direct leak") or line.startswith("Indirect leak"):
            self._finishStack()
            self.recordMoreFrames = True
            self.currStack = []
            return

        if line.startswith("SUMMARY: AddressSanitizer"):
            self._finishStack()
            self.inReport = False
            return

        if not self.recordMoreFrames:
            return

        stackFrame = re.match(self.stackFrameRegExp, line)
        if stackFrame:
            # Split the frame to remove any return types.
            frame = stackFrame.group(1).split()[-1]
            if not re.match(self.skipListRegExp, frame):
                self._recordFrame(frame)
            return

        sysLibStackFrame = re.match(self.sysLibStackFrameRegExp, line)
        if sysLibStackFrame:
            # System library stack frames will never match the skip list,
            # so don't bother checking if they do.
            self._recordFrame(sysLibStackFrame.group(1))

        # If we don't match either of these, just ignore the frame.
        # We'll end up with "unknown stack" if everything is ignored.

    def process(self):
        failures = 0

        if self.fatalError:
            self.logger.error(
                "TEST-UNEXPECTED-FAIL | LeakSanitizer | LeakSanitizer "
                "has encountered a fatal error."
            )
            failures += 1

        if self.symbolizerError:
            self.logger.error(
                "TEST-UNEXPECTED-FAIL | LeakSanitizer | LLVMSymbolizer "
                "was unable to allocate memory."
            )
            failures += 1
            self.logger.info(
                "TEST-INFO | LeakSanitizer | This will cause leaks that "
                "should be ignored to instead be reported as an error"
            )

        if self.foundFrames:
            self.logger.info(
                "TEST-INFO | LeakSanitizer | To show the "
                "addresses of leaked objects add report_objects=1 to LSAN_OPTIONS"
            )
            self.logger.info(
                "TEST-INFO | LeakSanitizer | This can be done "
                "in testing/mozbase/mozrunner/mozrunner/utils.py"
            )

        for f in self.foundFrames:
            self.logger.error("TEST-UNEXPECTED-FAIL | LeakSanitizer | leak at " + f)
            failures += 1

        return failures

    def _finishStack(self):
        if self.recordMoreFrames and len(self.currStack) == 0:
            self.currStack = ["unknown stack"]
        if self.currStack:
            self.foundFrames.add(", ".join(self.currStack))
            self.currStack = None
        self.recordMoreFrames = False
        self.numRecordedFrames = 0

    def _recordFrame(self, frame):
        self.currStack.append(frame)
        self.numRecordedFrames += 1
        if self.numRecordedFrames >= self.maxNumRecordedFrames:
            self.recordMoreFrames = False


# -*- coding:utf-8 -*-
"""
序列化二叉树
Q: 请实现两个函数，分别用来序列化和反序列化二叉树

A: 二叉树的序列化，通过前序遍历二叉树输出节点，然后碰到左子节点和右子节点为None的时候，输出一个特殊字符。
对于反序列化，就是通过输入的序列构建二叉树，针对前序遍历，可以先设置一个指针，
先指向序列的开头，然后把指针位置的数字转化成节点，当遇到特殊字符时或者超出序列长度时，对应节点为none。然后继续遍历。
"""

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def __init__(self):
        self.flag = -1

    def Serialize(self, root):
        # write code here
        # 树转换成序列
        if not root:
            return '#,'
        # 前序遍历的顺序，根先同级左至右
        return str(root.val) + ',' + self.Serialize(root.left) + self.Serialize(root.right)

    def Deserialize(self, s):
        # write code here
        # v序列转换成树
        self.flag += 1
        l = s.split(',')

        if self.flag >= len(s): # 超过序列长度，len(s)？应该是len(l)？
            return None
        root = None

        if l[self.flag] != '#': # 遇到非法字符，同样输出None
            root = TreeNode(int(l[self.flag]))
            root.left = self.Deserialize(s)
            root.right = self.Deserialize(s)
        return root


# -*- coding: utf-8 -*-
# author:           inspurer(月小水长)
# pc_type           lenovo
# create_time:      2019/12/1 23:07
# file_name:        history_stock_quotes_scrapy.py
# github            https://github.com/inspurer
# qq邮箱            2391527690@qq.com
# 微信公众号         月小水长(ID: inspurer)

import requests

from lxml import etree

from stock_analysis.utils import myDict

import pymongo

client = pymongo.MongoClient(host="localhost",port=27017)
db = client['stock']
table_basic = db['basic']

basis = table_basic.find()
print(basis.count())
stock_basis = myDict.AllowKeyRepeatDict()
for basic in basis:
    stock_basis.add(key=basic['name'],value=basic['code'])

stock_name = '中信证券'
stock_code = stock_basis.query(key=stock_name)[0]
table_quotes = db[stock_name+'_'+stock_code]

headers = {
    'Referer': 'http://quotes.money.163.com/trade/lsjysj_600030.html?year=2019&season=4',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
}

base_url = 'http://quotes.money.163.com/trade/lsjysj_{code}.html'
# 2019 年
year = 2019
season = 1
# 四季度
for season in range(1,5):
    params = {
        'year':year,
        'season':season
    }
    response = requests.get(url=base_url.format(code=stock_code),headers=headers,params=params)

    html = etree.HTML(response.text)
    for tr in html.xpath('//table[@class="table_bg001 border_box limit_sale"]/tr'):
        tds = tr.xpath('.//td/text()')
        date = tds[0].replace('-','')
        open,high,low,close = tds[1],tds[2],tds[3],tds[4]
        change,change_pencentage = tds[5],tds[6]
        deal_amount,deal_money = tds[7].replace(',',''),tds[8].replace(',','') # 成交量，成交金额（万元）
        print(date,open,high,low,close,change,change_pencentage,deal_amount,deal_money)
        data = {
            'date': int(date),
            'open': open,
            'high': high,
            'low': low,
            'close': close,
            'change': change,
            'change_pencentage': change_pencentage,
            'deal_amount': deal_amount,
            'deal_money': deal_money
        }
        # 上海和深圳可能有两个同名的股票
        # 上海股市也可能有同名股票，但是code不一样
        table_quotes.update_one({'date': date}, {'$set': data}, True)


from tensorflow.python.eager.context import num_gpus
import tensorflow_datasets as tfds
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from denseNet import DenseNet
from resblockmodel import MyResModel
import datetime
import argparse

def prepare_cifar(cifar10):
    # convert data from uint8 to float32
    cifar10 = cifar10.map(lambda img, target: (tf.cast(img, tf.float32), target))
    # sloppy input normalization, just bringing image values from range [0, 255] to [-1, 1]
    cifar10 = cifar10.map(lambda img, target: (tf.image.per_image_standardization(img), target))
    # create one-hot targets
    cifar10 = cifar10.map(lambda img, target: (img, tf.one_hot(target, depth=10)))
    # cache this progress in memory, as there is no need to redo it; it is deterministic after all
    cifar10 = cifar10.cache()
    # shuffle, batch, prefetch
    cifar10 = cifar10.shuffle(1000)
    cifar10 = cifar10.batch(64)
    cifar10 = cifar10.prefetch(32)
    # return preprocessed dataset
    return cifar10

@tf.function
def train_step(model, input, target, loss_function, optimizer):
    """
    This function executes a training step on the given network.
    Using gradient descend
    :param model: the network model
    :param input: the given input tensors
    :param target: the given target tensors
    :param loss_function: the given loss function
    :param optimizer: the given optimizer
    :return: the loss during this trainin step
    """
    # loss_object and optimizer_object are instances of respective tensorflow classes
    with tf.GradientTape() as tape:
        prediction = model(input, training=True)
        loss = loss_function(target, prediction)
    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    return loss

def test(model, test_data, loss_function):
    """
    # Tests over complete test data
    :param model: the network model
    :param test_data: the given input tensors
    :param loss_function: the given loss function
    :return: the test loss and test accuracy
    """
    test_accuracy_aggregator = []
    test_loss_aggregator = []
    for (input, target) in test_data:
        prediction = model(input, training=False)
        sample_test_loss = loss_function(target, prediction)
        sample_test_accuracy =  np.argmax(target, axis=1) == np.argmax(prediction, axis=1)
        sample_test_accuracy = np.mean(sample_test_accuracy)
        test_accuracy_aggregator.append(sample_test_accuracy)
        test_loss_aggregator.append(sample_test_loss.numpy())

    test_loss = tf.reduce_mean(test_loss_aggregator)
    test_accuracy = tf.reduce_mean(test_accuracy_aggregator)
    return test_loss, test_accuracy

if __name__ == "__main__":
    #parse arguments to determine which model should be used
    parser = argparse.ArgumentParser(description='ResNet or DenseNet')
    parser.add_argument('--model', type=str, help='ResNet of DenseNet', required=True)
    args = parser.parse_args()

    tf.keras.backend.clear_session()

    # loading the data set
    train_ds, test_ds = tfds.load('cifar10', split=['train', 'test'], as_supervised=True)
    train_ds = train_ds.apply(prepare_cifar)
    test_ds = test_ds.apply(prepare_cifar)
    #print(train_ds.take(1))
    # test preprocessing
    #for elem in train_ds:
    #    print(elem)
    #    break
    ### Hyperparameters
    num_epochs = 30
    learning_rate = tf.constant(0.001, dtype=tf.float32)
    # Initialize the loss: categorical cross entropy.
    cross_entropy_loss = tf.keras.losses.CategoricalCrossentropy()
    # Initialize the optimizer: SGD with default parameters.
    optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
    # Initialize lists for later visualization.
    train_losses = []
    test_losses = []
    test_accuracies = []

    #create the model
    if args.model == 'ResNet':
        model = MyResModel()
    elif args.model == 'DenseNet':
        model = DenseNet()
    else:
        raise ValueError("Invalid model passed in as argument. Should be either ResNet or DenseNet!")

    # testing once before we begin
    test_loss, test_accuracy = test(model, test_ds, cross_entropy_loss)
    test_losses.append(test_loss)
    test_accuracies.append(test_accuracy)
    # check how model performs on train data once before we begin
    train_loss, _ = test(model, train_ds, cross_entropy_loss)
    train_losses.append(train_loss)
    #   We train for num_epochs epochs.
    for epoch in range(num_epochs):
        start_time = datetime.datetime.now()
        print(f'Epoch: {str(epoch)} starting with accuracy {test_accuracies[-1]}')
        # training (and checking in with training)
        epoch_loss_agg = []
        for input, target in train_ds:
            train_loss = train_step(model, input, target, cross_entropy_loss, optimizer)
            epoch_loss_agg.append(train_loss)
        # track training loss
        train_losses.append(tf.reduce_mean(epoch_loss_agg))
        # testing, so we can track accuracy and test loss
        test_loss, test_accuracy = test(model, test_ds, cross_entropy_loss)
        test_losses.append(test_loss)
        test_accuracies.append(test_accuracy)
        diff_time = datetime.datetime.now() - start_time
        print(f"Epoch {epoch} took {diff_time} to complete.")

    print(model.summary())
    # Visualize accuracy and loss for training and test data.
    plt.subplot(1, 1, 1)
    line1, = plt.plot(train_losses, '-x')
    line2, = plt.plot(test_losses, '-+')
    line3, = plt.plot(test_accuracies, '-o')
    plt.xlabel("Training steps")
    plt.ylabel("Loss/Accuracy")
    plt.legend((line1, line2, line3), ("training loss", "test loss", "test accuracy"))
    plt.show()


import logging
from typing import Any, Callable

from tabulate import tabulate
from telegram import Bot, ParseMode, ReplyKeyboardMarkup, Update
from telegram.error import NetworkError, TelegramError
from telegram.ext import CommandHandler, Updater

from freqtrade.rpc.__init__ import (rpc_status_table,
                                    rpc_trade_status,
                                    rpc_daily_profit,
                                    rpc_trade_statistics,
                                    rpc_balance,
                                    rpc_start,
                                    rpc_stop,
                                    rpc_forcesell,
                                    rpc_performance,
                                    rpc_count,
                                    )

from freqtrade import __version__

# Remove noisy log messages
logging.getLogger('requests.packages.urllib3').setLevel(logging.INFO)
logging.getLogger('telegram').setLevel(logging.INFO)
logger = logging.getLogger(__name__)

_UPDATER: Updater = None
_CONF = {}

def init(config: dict) -> None:
    """
    Initializes this module with the given config,
    registers all known command handlers
    and starts polling for message updates
    :param config: config to use
    :return: None
    """
    global _UPDATER

    _CONF.update(config)
    if not is_enabled():
        return

    _UPDATER = Updater(token=config['telegram']['token'], workers=0)

    # Register command handler and start telegram message polling
    handles = [
        CommandHandler('status', _status),
        CommandHandler('profit', _profit),
        CommandHandler('balance', _balance),
        CommandHandler('start', _start),
        CommandHandler('stop', _stop),
        CommandHandler('forcesell', _forcesell),
        CommandHandler('performance', _performance),
        CommandHandler('daily', _daily),
        CommandHandler('count', _count),
        CommandHandler('help', _help),
        CommandHandler('version', _version),
    ]
    for handle in handles:
        _UPDATER.dispatcher.add_handler(handle)
    _UPDATER.start_polling(
        clean=True,
        bootstrap_retries=-1,
        timeout=30,
        read_latency=60,
    )
    logger.info(
        'rpc.telegram is listening for following commands: %s',
        [h.command for h in handles]
    )

def cleanup() -> None:
    """
    Stops all running telegram threads.
    :return: None
    """
    if not is_enabled():
        return
    _UPDATER.stop()

def is_enabled() -> bool:
    """
    Returns True if the telegram module is activated, False otherwise
    """
    return bool(_CONF['telegram'].get('enabled', False))

def authorized_only(command_handler: Callable[[Bot, Update], None]) -> Callable[..., Any]:
    """
    Decorator to check if the message comes from the correct chat_id
    :param command_handler: Telegram CommandHandler
    :return: decorated function
    """
    def wrapper(*args, **kwargs):
        update = kwargs.get('update') or args[1]

        # Reject unauthorized messages
        chat_id = int(_CONF['telegram']['chat_id'])
        if int(update.message.chat_id) != chat_id:
            logger.info('Rejected unauthorized message from: %s', update.message.chat_id)
            return wrapper

        logger.info('Executing handler: %s for chat_id: %s', command_handler.__name__, chat_id)
        try:
            return command_handler(*args, **kwargs)
        except BaseException:
            logger.exception('Exception occurred within Telegram module')
    return wrapper

@authorized_only
def _status(bot: Bot, update: Update) -> None:
    """
    Handler for /status.
    Returns the current TradeThread status
    :param bot: telegram bot
    :param update: message update
    :return: None
    """

    # Check if additional parameters are passed
    params = update.message.text.replace('/status', '').split(' ') \
        if update.message.text else []
    if 'table' in params:
        _status_table(bot, update)
        return

    # Fetch open trade
    (error, trades) = rpc_trade_status()
    if error:
        send_msg(trades, bot=bot)
    else:
        for trademsg in trades:
            send_msg(trademsg, bot=bot)

@authorized_only
def _status_table(bot: Bot, update: Update) -> None:
    """
    Handler for /status table.
    Returns the current TradeThread status in table format
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    # Fetch open trade
    (err, df_statuses) = rpc_status_table()
    if err:
        send_msg(df_statuses, bot=bot)
    else:
        message = tabulate(df_statuses, headers='keys', tablefmt='simple')
        message = "
{}
".format(message)

        send_msg(message, parse_mode=ParseMode.HTML)

@authorized_only
def _daily(bot: Bot, update: Update) -> None:
    """
    Handler for /daily <n>
    Returns a daily profit (in BTC) over the last n days.
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    try:
        timescale = int(update.message.text.replace('/daily', '').strip())
    except (TypeError, ValueError):
        timescale = 7
    (error, stats) = rpc_daily_profit(timescale,
                                      _CONF['stake_currency'],
                                      _CONF['fiat_display_currency'])
    if error:
        send_msg(stats, bot=bot)
    else:
        stats = tabulate(stats,
                         headers=[
                             'Day',
                             'Profit {}'.format(_CONF['stake_currency']),
                             'Profit {}'.format(_CONF['fiat_display_currency'])
                         ],
                         tablefmt='simple')
        message = 'Daily Profit over the last {} days:\n
{}
'.format(
                  timescale, stats)
        send_msg(message, bot=bot, parse_mode=ParseMode.HTML)

@authorized_only
def _profit(bot: Bot, update: Update) -> None:
    """
    Handler for /profit.
    Returns a cumulative profit statistics.
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    (error, stats) = rpc_trade_statistics(_CONF['stake_currency'],
                                          _CONF['fiat_display_currency'])
    if error:
        send_msg(stats, bot=bot)
        return

    # Message to display
    markdown_msg = """
*ROI:* Close trades
  ∙ `{profit_closed_coin:.8f} {coin} ({profit_closed_percent:.2f}%)`
  ∙ `{profit_closed_fiat:.3f} {fiat}`
*ROI:* All trades
  ∙ `{profit_all_coin:.8f} {coin} ({profit_all_percent:.2f}%)`
  ∙ `{profit_all_fiat:.3f} {fiat}`

*Total Trade Count:* `{trade_count}`
*First Trade opened:* `{first_trade_date}`
*Latest Trade opened:* `{latest_trade_date}`
*Avg. Duration:* `{avg_duration}`
*Best Performing:* `{best_pair}: {best_rate:.2f}%`
    """.format(
        coin=_CONF['stake_currency'],
        fiat=_CONF['fiat_display_currency'],
        profit_closed_coin=stats['profit_closed_coin'],
        profit_closed_percent=stats['profit_closed_percent'],
        profit_closed_fiat=stats['profit_closed_fiat'],
        profit_all_coin=stats['profit_all_coin'],
        profit_all_percent=stats['profit_all_percent'],
        profit_all_fiat=stats['profit_all_fiat'],
        trade_count=stats['trade_count'],
        first_trade_date=stats['first_trade_date'],
        latest_trade_date=stats['latest_trade_date'],
        avg_duration=stats['avg_duration'],
        best_pair=stats['best_pair'],
        best_rate=stats['best_rate']
    )
    send_msg(markdown_msg, bot=bot)

@authorized_only
def _balance(bot: Bot, update: Update) -> None:
    """
    Handler for /balance
    """
    (error, result) = rpc_balance(_CONF['fiat_display_currency'])
    if error:
        send_msg('`All balances are zero.`')
        return

    (currencys, total, symbol, value) = result
    output = ''
    for currency in currencys:
        output += """*Currency*: {currency}
*Available*: {available}
*Balance*: {balance}
*Pending*: {pending}
*Est. BTC*: {est_btc: .8f}
""".format(**currency)

    output += """*Estimated Value*:
*BTC*: {0: .8f}
*{1}*: {2: .2f}
""".format(total, symbol, value)
    send_msg(output)

@authorized_only
def _start(bot: Bot, update: Update) -> None:
    """
    Handler for /start.
    Starts TradeThread
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    (error, msg) = rpc_start()
    if error:
        send_msg(msg, bot=bot)

@authorized_only
def _stop(bot: Bot, update: Update) -> None:
    """
    Handler for /stop.
    Stops TradeThread
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    (error, msg) = rpc_stop()
    send_msg(msg, bot=bot)

# FIX: no test for this!!!!
@authorized_only
def _forcesell(bot: Bot, update: Update) -> None:
    """
    Handler for /forcesell <id>.
    Sells the given trade at current price
    :param bot: telegram bot
    :param update: message update
    :return: None
    """

    trade_id = update.message.text.replace('/forcesell', '').strip()
    (error, message) = rpc_forcesell(trade_id)
    if error:
        send_msg(message, bot=bot)
        return

@authorized_only
def _performance(bot: Bot, update: Update) -> None:
    """
    Handler for /performance.
    Shows a performance statistic from finished trades
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    (error, trades) = rpc_performance()
    if error:
        send_msg(trades, bot=bot)
        return

    stats = '\n'.join('{index}.\t{pair}\t{profit:.2f}% ({count})'.format(
        index=i + 1,
        pair=trade['pair'],
        profit=trade['profit'],
        count=trade['count']
    ) for i, trade in enumerate(trades))
    message = 'Performance:\n{}'.format(stats)
    send_msg(message, parse_mode=ParseMode.HTML)

@authorized_only
def _count(bot: Bot, update: Update) -> None:
    """
    Handler for /count.
    Returns the number of trades running
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    (error, trades) = rpc_count()
    if error:
        send_msg(trades, bot=bot)
        return

    message = tabulate({
        'current': [len(trades)],
        'max': [_CONF['max_open_trades']]
    }, headers=['current', 'max'], tablefmt='simple')
    message = "
{}
".format(message)
    logger.debug(message)
    send_msg(message, parse_mode=ParseMode.HTML)

@authorized_only
def _help(bot: Bot, update: Update) -> None:
    """
    Handler for /help.
    Show commands of the bot
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    message = """
*/start:* `Starts the trader`
*/stop:* `Stops the trader`
*/status [table]:* `Lists all open trades`
            *table :* `will display trades in a table`
*/profit:* `Lists cumulative profit from all finished trades`
*/forcesell <trade_id>|all:* `Instantly sells the given trade or all trades, regardless of profit`
*/performance:* `Show performance of each finished trade grouped by pair`
*/daily <n>:* `Shows profit or loss per day, over the last n days`
*/count:* `Show number of trades running compared to allowed number of trades`
*/balance:* `Show account balance per currency`
*/help:* `This help message`
*/version:* `Show version`
    """
    send_msg(message, bot=bot)

@authorized_only
def _version(bot: Bot, update: Update) -> None:
    """
    Handler for /version.
    Show version information
    :param bot: telegram bot
    :param update: message update
    :return: None
    """
    send_msg('*Version:* `{}`'.format(__version__), bot=bot)

def send_msg(msg: str, bot: Bot = None, parse_mode: ParseMode = ParseMode.MARKDOWN) -> None:
    """
    Send given markdown message
    :param msg: message
    :param bot: alternative bot
    :param parse_mode: telegram parse mode
    :return: None
    """
    if not is_enabled():
        return

    bot = bot or _UPDATER.bot

    keyboard = [['/daily', '/profit', '/balance'],
                ['/status', '/status table', '/performance'],
                ['/count', '/start', '/stop', '/help']]

    reply_markup = ReplyKeyboardMarkup(keyboard)

    try:
        try:
            bot.send_message(
                _CONF['telegram']['chat_id'], msg,
                parse_mode=parse_mode, reply_markup=reply_markup
            )
        except NetworkError as network_err:
            # Sometimes the telegram server resets the current connection,
            # if this is the case we send the message again.
            logger.warning(
                'Telegram NetworkError: %s! Trying one more time.',
                network_err.message
            )
            bot.send_message(
                _CONF['telegram']['chat_id'], msg,
                parse_mode=parse_mode, reply_markup=reply_markup
            )
    except TelegramError as telegram_err:
        logger.warning('TelegramError: %s! Giving up on that message.', telegram_err.message)


# ---------------------------------------------------
# Author    :  Benjamin Kataliko Viranga
# Community :  Stunt Business
# Community website : www.stuntbusiness.com
#
# 30 Days - Q&A Python Basic
# Day 3 : 24-05-2020
# Day 3 | IG : https://www.instagram.com/benjivrik/
# Subject :  Challenge I - Input and user functions
#----------------------------------------------------
# what would be the output of this program ?

'''

    Request the user to enter a number.

    Use the integer entered by the user in the function that you are creating.

    This function return the double of the parameter.

'''

def double_parameter( value ):
    '''

        value here is your parameter - type int

        How to return the value from the function ?

        use 'return' as shown below.

        Mathematical operators can be applied in programming as well.

    '''
    return value * 2

#main program

user_input  = input("Enter a number : ")  #line1

user_input  = int(user_input)             #line2

print("The double is ", double_parameter(user_input))       #line3

print("End of program")