import sys
import os
import argparse
import urllib
import urllib2
import json
import re
import time

### Argument parser ###
parser = argparse.ArgumentParser(description="Get Wikipedia articles for a given category")
parser.add_argument("category", help="the Wikipedia category")
parser.add_argument("-l", "--language", default="en", help="the Wikipedia language (default: %(default)s)")
parser.add_argument("-d", "--days", choices=["30", "60", "90"], default="30", help="time range for stats (days) (default: %(default)s)")
parser.add_argument("-o", "--output_folder", default="output", help="the output folder (default: %(default)s)")
parser.add_argument("--no-stats", dest="no_stats", action="store_true", help="no stats queries are sent")

args = parser.parse_args()

# check if output folder exists
if not os.path.isdir(args.output_folder):
  print("")
  print("ERROR: Missing output folder")
  print("")
  sys.exit(1)

### Query to Wikipedia API ###
api_url = "http://" + args.language + ".wikipedia.org/w/api.php"
api_params = { "action" : "query",
               "list" : "categorymembers",
               "continue" : "",
               "cmtitle" : "Category:" + args.category,
               "cmlimit" : 500,
               "cmprop": "title",
               "format" : "json"
             }
try:
  params = urllib.urlencode(api_params)
  req = urllib2.Request(api_url, params)
  req.add_header("User-Agent", "python-wikipedia_stats")
  print("")
  sys.stdout.write("Querying " + args.language + ".wikipedia.org... ")
  response = urllib2.urlopen(req)
  response_content = response.read()
except Exception:
  print("")
  print("")
  print("Error querying Wikipedia API for category \"" + args.category + "\"")
  print("")
  sys.exit(1)
print("done.")

parsed_response = json.loads(response_content)

### Get stats ###
articles = parsed_response["query"]["categorymembers"]
num_articles = len(articles)
print("")
# exit if no articles have been found
if num_articles == 0:
  print("No articles found for category \"" + args.category + "\"")
  print("")
  sys.exit(1)
print(str(num_articles) + " articles found for category \"" + args.category + "\":")
print("")
# print the list of articles found
counter = 1
for article in articles:
  print(str(counter) + " | " + article["title"])
  counter += 1
print("")
print("")

if args.no_stats:
  sys.exit(1)

# query the stats url for each article, save the values in a dictionary
all_hits = {}
stats_url_base = "http://stats.grok.se/" + args.language + "/latest" + args.days + "/"
for article in articles:
  title = article["title"].encode("utf-8")
  urltitle = urllib.quote(title).replace("%20", "_").replace("%2F", "/")
  stats_url = stats_url_base + urltitle
  try:
    req = urllib2.Request(stats_url)
    req.add_header("User-Agent", "python-wikipedia_stats")
    print("Querying stats.grok.se for " + title)
    response = urllib2.urlopen(req)
    response_content = response.read()
  except Exception:
    print("EXCEPTION getting stats for: " + title)
    continue
  # find the number of hits for the given article
  regex_sentence = re.compile("has been viewed (\d+)")
  match_sentence = regex_sentence.search(response_content)
  num_hits = int(match_sentence.group(1))
  if num_hits not in all_hits:
    all_hits[num_hits] = []
  all_hits[num_hits].append([title, urltitle])
  time.sleep(2)

### Print output file sorted by the number of hits ###
category_file = urllib.quote(args.category).replace("%20", "_").replace("%2F", "/")
output_file_name = category_file + "_" + args.language + "_" + args.days + "_" + time.strftime("%Y%m%d%H%M%S") + ".csv"
output_file_path = os.path.join(args.output_folder, output_file_name)
try:
  output_file = open(output_file_path, "w")
  output_file.write("Title|URL|Hits_" + args.days + "\n")
  for key in sorted(all_hits, reverse=True):
    for article in all_hits[key]:
      output_file.write(article[0] + "|" + "http://" + args.language + ".wikipedia.org/wiki/" + article[1] + "|" + str(key) + "\n")
except Exception:
  print("")
  print("EXCEPTION writing output file for article: " + article[0])
  print("")
finally:
  output_file.close()
print("")
print("Output file: " + output_file_path)
print("")


# -*- coding: utf-8 -*-
from flask import Flask, render_template
from flask_wtf.csrf import CsrfProtect
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
sys.path.append('..')
from views import account, admin, user, setting
from extend import db
import config

DEFAULT_MODULES = (
    (account.account, ""),
    (admin.admin, "/admin"),
    (user.user, "/user"),
    (setting.setting, "/setting"),
)

def create_app():
    "main"
    app = Flask(__name__)
    # config
    app.config.from_object(config.Config)

    configure_extensions(app)
    configure_errorhandlers(app)
    configure_before_handlers(app)
    configure_template_filters(app)
    # register module

    configure_blueprint(app, DEFAULT_MODULES)
    return app

def configure_extensions(app):
    # configure extensions
    db.init_app(app)
    CsrfProtect(app)

def configure_errorhandlers(app):
    @app.errorhandler(404)
    def not_found(error):
        return render_template('404.html'), 404

def configure_before_handlers(app):
    pass

def configure_template_filters(app):
    @app.template_filter('members')
    def members_filter(s):
        s_new = ' , '.join([i[0] for i in s])
        return s_new

    @app.template_filter('week')
    def week_filter(s):
        a = [u'周一', u'周二', u'周三', u'周四', u'周五', u'周六', u'周日']
        return a[s]

def configure_blueprint(app, modules):
    for module, url_prefix in modules:
        # print module, url_prefix
        app.register_blueprint(module, url_prefix=url_prefix)


# -*- coding: utf-8 -*-
"""
Created on Sat Jun 10 12:15:18 2017

@author: mechd
"""

def grid(theta, d_theta, n, tol):
    """"theta = pi/2 - d_theta*n*tol"""
#    grid(0.942478, 2.51327, 25, 0.01)
    import numpy as np
    import math
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    import random
    a = np.zeros((n*n*n, 3))
    b = np.zeros((n*n*n, 3))
    c = np.zeros((2*n*n*n, 3))
    kc = 0
    kd = 0
    kt1 = 0
    kt2 = 0
    for k in range(n):
        for j in range(n):
            m = 0
            for i in range(n):
                m = m + tol
#            print(m)
                a[kc, 0] = (i-1) + (j-1)/np.tan((np.pi/2)-m*d_theta)
                a[kc, 1] = j
                a[kc, 2] = k
                kc = kc+1
    for k in range(n):
        for j in range(n):
            m = 0
            for i in range(n):
                m = m + tol
#            print(m)
                b[kd, 0] = (i+n-1) + (j-1)/np.tan(theta+m*d_theta)
                b[kd, 1] = j
                b[kd, 2] = k
                kd = kd+1
    for k in range(n):
        for j in range(n):
            for i in range(n):
                c[kt1, 0] = a[kt2, 0]
                c[kt1, 1] = a[kt2, 1]
                c[kt1, 2] = a[kt2, 2]
                c[kt1+n, 0] = b[kt2, 0]
                c[kt1+n, 1] = b[kt2, 1]
                c[kt1+n, 2] = b[kt2, 2]
                kt2 = kt2+1
                kt1 = kt1+1
            kt1 = kt1+n
#    print(a)
#    plt.plot(a,b,'ro')
#    plt.plot(c,d,'bo')
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(a[0:n**3-1, 0], a[0:n**3-1, 1], a[0:n**3-1, 2], c='r')
    ax.scatter(b[0:n**3-1, 0], b[0:n**3-1, 1], b[0:n**3-1, 2], c='b')
    ax.set_xlabel('X Label')
    ax.set_ylabel('Y Label')
    ax.set_zlabel('Z Label')
    np.savetxt('griddata.o', c/10000)

    return


"""
    ----------------------------------------
    PyPlastimatch

    Viz tools for notebook testing
    ----------------------------------------

    ----------------------------------------
    Author: Dennis Bontempi
    Email:  dbontempi@bwh.harvard.edu
    ----------------------------------------

"""

import numpy as np
import ipywidgets as ipyw
import matplotlib.pyplot as plt

from matplotlib.colors import ListedColormap
from matplotlib.patches import Patch

class AxialSliceFigure:
  """
  Base class for the interactive slice-wise visualisation widgets

  Init of all the figure parameters that are always set.

  @Params:
    ct_cmap - required : colormap for the CT viz.
    figsize - required : size of the figure (in inches).
    dpi     - required : DPI of the figure.
    min_hu  - required : minimum HU to be visualised
    max_hu  - required : maximum HU to be visualised
  """

  def __init__(self, ct_cmap, figsize, dpi, min_hu, max_hu):

    self.ct_cmap = ct_cmap
    self.figsize = figsize
    self.dpi = dpi

    self.min_hu = min_hu
    self.max_hu = max_hu

  def views(self):
    """
    method description goes here

    """

    ipyw.interact(self.plot_slice,
                  axial_idx = ipyw.IntSlider(min = 0, max = self.max_axial,
                                             step = 1, continuous_update = True,
                                             description = 'Axial slice:'))

## ----------------------------------------
## ----------------------------------------

class AxialSliceComparison(AxialSliceFigure):
  """
  class description goes here

  """

  def __init__(self, ct_volume_left, ct_volume_right,
               title_left = "", title_right = "",
               ct_cmap = "gray", figsize = (12, 12), dpi = 100,
               min_hu = -1024, max_hu = 3072):

    super().__init__(ct_cmap, figsize, dpi, min_hu, max_hu)

    # the only constraint should be on the number of axial slice of the volumes to visualise
    assert ct_volume_left.shape[0] == ct_volume_right.shape[0]

    self.ct_volume_left = ct_volume_left
    self.ct_volume_right = ct_volume_right
    self.max_axial = self.ct_volume_left.shape[0] - 1

    self.title_left = title_left
    self.title_right = title_right

    ipyw.interact(self.views)

  def plot_slice(self, axial_idx):
    """
    method description goes here

    """

    fig, (ax_left, ax_right) = plt.subplots(1, 2, figsize = self.figsize, dpi = self.dpi)

    # plot CT axial slices
    ax_left.set_title(self.title_left)
    ax_left.imshow(self.ct_volume_left[axial_idx, :, :], cmap = self.ct_cmap,
                   vmin = self.min_hu, vmax = self.max_hu)

    ax_right.set_title(self.title_right)
    ax_right.imshow(self.ct_volume_right[axial_idx, :, :], cmap = self.ct_cmap,
                    vmin = self.min_hu, vmax = self.max_hu)

    plt.subplots_adjust(hspace = 0.2)
    plt.show()

## ----------------------------------------
## ----------------------------------------

class AxialSliceSegmaskComparison(AxialSliceFigure):
  """
  class description goes here

  """

  def __init__(self, ct_volume, segmask_ai_dict, segmask_manual_dict,
               segmask_cmap_dict, segmask_alpha = 0.6, title_left = "", title_right = "",
               ct_cmap = "gray", figsize = (12, 12), dpi = 100,
               min_hu = -1024, max_hu = 3072):

    super().__init__(ct_cmap, figsize, dpi, min_hu, max_hu)

    self.ct_volume = ct_volume
    self.max_axial = self.ct_volume.shape[0] - 1

    self.segmask_ai_dict = segmask_ai_dict
    self.segmask_manual_dict = segmask_manual_dict

    self.segmask_cmap_dict = segmask_cmap_dict
    self.segmask_alpha = segmask_alpha

    self.title_left = title_left
    self.title_right = title_right

    ipyw.interact(self.views)

  def plot_slice(self, axial_idx):
    """
    method description goes here

    """

    fig, (ax_ai, ax_manual) = plt.subplots(1, 2, figsize = self.figsize, dpi = self.dpi)

    # plot CT axial slices
    ax_ai.set_title(self.title_left)
    ax_ai.imshow(self.ct_volume[axial_idx, :, :], cmap = self.ct_cmap,
                 vmin = self.min_hu, vmax = self.max_hu)

    ax_manual.set_title(self.title_right)
    ax_manual.imshow(self.ct_volume[axial_idx, :, :], cmap = self.ct_cmap,
                     vmin = self.min_hu, vmax = self.max_hu)

    # check the lenght of cmaps is enough to colour all the structures
    assert len(self.segmask_cmap_dict) == np.max([len(self.segmask_ai_dict),
                                                  len(self.segmask_manual_dict)])

    # plot overlaying masks
    for key in self.segmask_ai_dict:
      segmask_ai = self.segmask_ai_dict[key]
      segmask_cmap = self.segmask_cmap_dict[key]
      ax_ai.imshow(segmask_ai[axial_idx, :, :], label = key,
                   cmap = segmask_cmap, alpha = self.segmask_alpha)

    for key in self.segmask_manual_dict:
      segmask_manual = self.segmask_manual_dict[key]
      segmask_cmap = self.segmask_cmap_dict[key]
      ax_manual.imshow(segmask_manual[axial_idx, :, :], label = key,
                       cmap = segmask_cmap, alpha = self.segmask_alpha)

    plt.subplots_adjust(hspace = 0.2)
    plt.show()

## ----------------------------------------
## ----------------------------------------

class AxialSliceSegmaskViz(AxialSliceFigure):
  """
  class description goes here

  """

  def __init__(self, ct_volume, segmask_dict, segmask_cmap_dict,
               segmask_alpha = 0.4,
               random_cmap = False, # FIXME - legend in the figure is wrong
               fig_title = "",
               ct_cmap = "gray", figsize = (6, 6), dpi = 100,
               min_hu = -1024, max_hu = 3072):

    """
    constructor description goes here

    """

    super().__init__(ct_cmap, figsize, dpi, min_hu, max_hu)

    self.ct_volume = ct_volume
    self.max_axial = self.ct_volume.shape[0] - 1

    self.segmask_dict = segmask_dict

    self.fig_title = fig_title

    if random_cmap:
      self.segmask_cmap_dict = self.get_random_cmap_dict(segmask_dict.keys())
    else:
      self.segmask_cmap_dict = segmask_cmap_dict

    self.segmask_alpha = segmask_alpha

    ipyw.interact(self.views)

  def get_random_cmap_dict(self, dict_keys):
    """
    method description goes here

    """

    segmask_cmap_dict = dict()

    for idx, key in enumerate(dict_keys):
      # dummy random colormap creation
      vals = np.linspace(0, 1, 256)
      np.random.shuffle(vals)

      # color map to sample from
      my_cmap = plt.cm.jet(vals)
      my_cmap[:, -1] = np.linspace(0, 1, 256)

      segmask_cmap_dict[key] = ListedColormap(my_cmap)

    return segmask_cmap_dict

  def plot_slice(self, axial_idx):
    """
    method description goes here

    """

    fig, ax = plt.subplots(1, 1, figsize = self.figsize, dpi = self.dpi)

    try:
      len(legend_elements)
    except:
      legend_elements = list()

    # plot CT axial slices
    ax.set_title(self.fig_title)
    ax.imshow(self.ct_volume[axial_idx, :, :], cmap = self.ct_cmap,
              vmin = self.min_hu, vmax = self.max_hu)

    # check the lenght of cmaps is enough to colour all the structures
    assert len(self.segmask_cmap_dict) == len(self.segmask_dict)

    # plot overlaying masks
    for key in self.segmask_dict:
      segmask = self.segmask_dict[key]
      segmask_cmap = self.segmask_cmap_dict[key]

      ax.imshow(segmask[axial_idx, :, :], label = key,
                cmap = segmask_cmap, alpha = self.segmask_alpha)

      if not len(legend_elements) == len(self.segmask_dict):
        legend_elements.append(Patch(facecolor = segmask_cmap(0.7),
                                     edgecolor = 'k',
                                     label = key))

    plt.subplots_adjust(hspace = 0.2)
    plt.show()

    ax.legend(handles = legend_elements,
              loc = 'upper left',
              bbox_to_anchor = (1, 1))


"""
demo01_k.py  k线图
"""
import numpy as np
import matplotlib.pyplot as mp
import datetime as dt
import matplotlib.dates as md

# 当numpy解析文本时,将会把第一列中的每个字符串
# 都传给函数进行处理, 将处理完毕后的返回值
# 转成需要的M8[D]类型
def dmy2ymd(dmy):
	dmy = str(dmy, encoding='utf-8')
	# 把dmy转成日期对象
	d = dt.datetime.strptime(dmy, '%d-%m-%Y')
	t = d.date()
	s = t.strftime('%Y-%m-%d')
	return s

# 加载文件
dates, opening_prices, highest_prices, \
	lowest_prices, closing_prices = np.loadtxt(
	'../da_data/aapl.csv', delimiter=',',
	usecols=(1,3,4,5,6), unpack=True,
	dtype='M8[D], f8, f8, f8, f8',
	converters={1:dmy2ymd})

# 绘制收盘价
mp.figure('AAPL', facecolor='lightgray')
mp.title('AAPL', fontsize=18)
mp.xlabel('Date', fontsize=14)
mp.ylabel('Price', fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
# 设置主刻度定位器为每周一
ax = mp.gca()
ax.xaxis.set_major_locator(
	md.WeekdayLocator(byweekday=md.MO))
ax.xaxis.set_major_formatter(
	md.DateFormatter('%Y/%m/%d'))

# 把M8[D]转为matplotlib识别的date类型
dates = dates.astype(md.datetime.datetime)
mp.plot(dates, closing_prices, alpha=0.3,
	color='dodgerblue', linewidth=2,
	linestyle='--', label='closing_prices')

# 绘制K线图
# 研究颜色的设置
rise = closing_prices >= opening_prices
# 填充色:
color = np.array([('white' if x else 'green') \
		for x in rise])
# 边缘色:
ecolor = np.array([('red' if x else 'green') \
		for x in rise])

# 绘制影线
# mp.bar(dates, highest_prices-lowest_prices,
# 	0.1, lowest_prices, color=ecolor)
mp.vlines(dates, lowest_prices, highest_prices,
	color=ecolor, linewidth=0.8)
# 绘制实体
mp.bar(dates, closing_prices-opening_prices,
	0.8, opening_prices, color=color,
	edgecolor=ecolor, zorder=3)

mp.legend()
# 自动格式化x轴的日期输出
mp.gcf().autofmt_xdate()
mp.show()


import glob
import os
import shutil
import re
import tkinter as tk
import tkinter.messagebox
from datetime import date
from os import rename
from pathlib import Path
from tkinter import filedialog

font_size = 15

def match_iban(search_str: str):
    m = re.search("AT[0-9]+", search_str)

    if m is None:
        return None

    return m.group(0)

def change_font_size(increase, root, frame):
    global font_size
    if increase:
        font_size += 1
    else:
        if font_size < 10:
            tkinter.messagebox.showerror(title="Fehler", message="Schriftgröße kann nicht weiter reduziert werden.")
            return
        font_size -= 1

    frame.destroy()

    # root.iconbitmap("example/path/file.ico")
    root.option_add("*Font", ('Arial', font_size))

    MainWindow(root)

class MainWindow:
    def __init__(self, master):
        self.log_messages = ""
        self.error_messages = ""
        self.folder_path = ""
        self.target_folder_path = ""

        self.master = master

        self.master.columnconfigure(0, weight=1)
        self.master.rowconfigure(0, weight=1)

        self.frame = tk.Frame(self.master)
        self.frame.grid(row=0, column=0, padx=50, pady=50, sticky="NSEW")

        self.frame.columnconfigure((0, 1, 2, 3), weight=1)
        self.frame.rowconfigure((0, 1, 2, 3, 4), weight=1)

        # directory input field
        self.dLabel = tk.Label(self.frame, text="Verzeichnis:  ").grid(column=0, row=0, sticky="NSEW")
        self.directoryEntry = tk.Entry(self.frame, width=80)
        self.directoryEntry.grid(column=1, row=0, sticky="")
        self.dirSelectButton = tk.Button(self.frame, text="...", command=self.select_directory)
        self.dirSelectButton.grid(column=2, row=0, sticky="")

        # output directory input field for move mode
        self.move_directory_label = tk.Label(self.frame, text="Zielverzeichnis:  ").grid(column=0, row=1, sticky="")
        self.move_directory_entry = tk.Entry(self.frame, width=80)
        self.move_directory_entry.grid(column=1, row=1, sticky="")
        self.move_dir_select_button = tk.Button(self.frame, text="...", command=self.select_move_directory)
        self.move_dir_select_button.grid(column=2, row=1, sticky="")

        # checkbox for rename mode
        self.rename_var = tk.IntVar(self.master)
        self.rename_var.set(0)
        self.rename_box = tk.Checkbutton(self.frame, text="Umbenennen", variable=self.rename_var, command=self.rename_button_action)
        self.rename_box.grid(column=0, row=2, sticky="")

        # checkbox for move mode
        self.move_var = tk.IntVar(self.master)
        self.move_var.set(1)
        self.move_box = tk.Checkbutton(self.frame, text="Kopieren", variable=self.move_var, command=self.move_button_action)
        self.move_box.grid(column=1, row=2, sticky="")

        self.move_button_action()

        # confirm button
        self.confirm = tk.Button(self.frame, text="Bestätigen", command=self.submit)
        self.confirm.grid(column=1, row=3, sticky="NSEW")

        # close button
        self.close = tk.Button(self.frame, text="Schließen", command=self.master.destroy)
        self.close.grid(column=2, row=3, sticky="")

        # increase font size
        self.increase_size_button = tk.Button(self.frame, text="+", command=lambda: change_font_size(True, self.master, self.frame))
        self.increase_size_button.grid(column=2, row=4, sticky="NSEW", padx=50, pady=10)

        # reduce font size
        self.reduce_size_button = tk.Button(self.frame, text="-", command=lambda: change_font_size(False, self.master, self.frame))
        self.reduce_size_button.grid(column=1, row=4, sticky="NSEW", padx=50, pady=10)

    def rename_button_action(self):
        self.move_var.set(0)

        self.rename_box.config(state="disabled")
        self.move_box.config(state="normal")

        self.move_directory_entry.config(state="disabled")
        self.move_dir_select_button.config(state="disabled")

        self.master.update()

    def move_button_action(self):
        self.rename_var.set(0)

        self.rename_box.config(state="normal")
        self.move_box.config(state="disabled")

        self.move_directory_entry.config(state="normal")
        self.move_dir_select_button.config(state="normal")

        self.master.update()

    def select_directory(self):
        self.folder_path = filedialog.askdirectory()
        self.directoryEntry.delete(0, "end")
        self.directoryEntry.insert(0, self.folder_path)

    def select_move_directory(self):
        self.target_folder_path = filedialog.askdirectory()
        self.move_directory_entry.delete(0, "end")
        self.move_directory_entry.insert(0, self.target_folder_path)

    def show_result_window(self):
        self.log_messages = self.log_messages.replace("/", "\\")
        self.error_messages = self.error_messages.replace("/", "\\")

        result_window = tk.Tk()
        result_window.option_add("*Font", ('Arial', font_size))
        ResultWindow(result_window, self.log_messages, self.error_messages)

        self.master.destroy()

        result_window.mainloop()

    def submit(self):
        if self.folder_path == "" or self.folder_path is None:
            tkinter.messagebox.showerror(title="Fehler", message="Verzeichnis kann nicht leer sein.")
            return

        if self.rename_var.get() == 1:

            self.iterate_rename_files(".pdf")
            self.iterate_rename_files(".xml")

        else:
            if self.target_folder_path == "" or self.target_folder_path is None:
                tkinter.messagebox.showerror(title="Fehler", message="Zielverzeichnis kann nicht leer sein.")
                return

            self.copy_files()

        self.show_result_window()

    def iterate_rename_files(self, file_ending: str):

        all_files = glob.glob(self.folder_path + "/*" + file_ending)

        if not all_files:
            self.error_messages += "No files with the ending " + file_ending + " found in the selected folder.\n"

        for file_ in all_files:
            self.rename_file(file_, file_ending)

    def rename_file(self, file_name: str, file_ending: str):
        today = date.today()
        datestamp = today.strftime("%Y%m%d")
        file_name = re.sub(pattern=".*\\\\", repl="", string=file_name)

        iban = match_iban(file_name)

        if iban is None:
            self.error_messages += "Die Datei '" + file_name + "' enthält keinen IBAN und wird nicht umbenannt.\n"

        else:
            new_name = iban + "_" + datestamp + file_ending
            try:
                rename(self.folder_path + "/" + file_name, self.folder_path + "/" + new_name)
                self.log_messages += "Die Datei '" + file_name + "' wurde in '" + new_name + "' umbenannt.\n"
            except FileExistsError:
                self.error_messages += "Die Datei '" + self.folder_path + "\\" + file_name + "' kann nicht umbenannt werden. Der resultierende Dateiname existiert bereits.\n"

    def copy_files(self):
        all_files = glob.glob(self.folder_path + "/*.pdf")

        for file in all_files:
            iban = match_iban(file)
            if iban is None:
                self.error_messages += str(file) + " wurde übersprungen.\n"
                continue
            else:
                folder_name = self.target_folder_path + "/" + iban
                if not Path(folder_name).is_dir():
                    os.mkdir(folder_name)
                shutil.copy2(file, folder_name)
                self.log_messages += str(file) + " wurde kopiert nach " + folder_name + "\n"

class ResultWindow:
    def __init__(self, master, log_messages, error_messages):
        # window definitions
        self.master = master
        self.res = tk.Frame(self.master)
        self.master.title("Nachrichten")
        self.res.pack()

        # label for error entry
        self.error_label = tk.Label(self.master, text="Fehler")
        self.error_label.pack()

        # entry to show errors and warnings
        self.error_text = tk.Text(self.master, width=200, height=10)
        self.error_text.pack()
        self.error_text.insert("end", error_messages)
        # read-only
        self.error_text.bind("<Key>", lambda e: "break")

        # label for log entry
        self.log_label = tk.Label(self.master, text="Log")
        self.log_label.pack()

        # entry to show logs
        self.log_text = tk.Text(self.master, width=200, height=10)
        self.log_text.pack()
        self.log_text.insert("end", log_messages)
        # read-only
        self.log_text.bind("<Key>", lambda e: "break")

        # close button
        self.close = tk.Button(self.master, text="Schließen", command=self.master.destroy)
        self.close.pack()

if __name__ == '__main__':
    root = tk.Tk()
    root.title("File Renamer")

    # root.iconbitmap("example/path/file.ico")
    root.option_add("*Font", ('Arial', font_size))

    main_page = MainWindow(root)

    root.mainloop()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Project      : iWork.
# @File         : DateTimeFeat
# @Time         : 2019-06-13 23:16
# @Author       : yuanjie
# @Email        : yuanjie@xiaomi.com
# @Software     : PyCharm
# @Description  : todo: 增加 lag

from meutils.pipe import *
from pandas.tseries.holiday import USFederalHolidayCalendar

class DateTimeFeats(object):
    """
    pandas_utils 时间/日期特征工程
    常见格式：
        1. 时间戳
        2. 时间字符串

    # 很强大: 解析不出为空
    pd.to_datetime(ts, 'coerce', unit='s', infer_datetime_format=True)
    """

    def __init__(self, feats=None):
        """利用python获取某年中每个月的第一天和最后一天

        :param feats: {
                "year", "quarter", "month", "day", "hour", "minute", "second",
                "week", "weekday",  # week==weekofyear== .dt.isocalendar().week
                "day_of_year",
                "days_in_month",  # 月的天数

                # bool
                'is_month_end',
                'is_month_start',
                'is_quarter_end',
                'is_quarter_start',
                'is_year_end',
                'is_year_start',
                'is_leap_year',

                # 自定义
                "monthweek",  # 获取指定的某天是某个月的第几周

            }
        """

        self.feats = feats
        if feats is None:
            self.feats = (
                'timestamp',  # 获取时间戳
                "year", "quarter", "month", "day", "hour", "minute", "second",
                "week", "weekday",  # week==weekofyear== .dt.isocalendar().week
                "day_of_year",

                # 自定义
                "monthweek",  # 获取指定的某天是某个月的第几周
                'day_part',  # 拆分为早中晚

                'holiday_name',  #
                'solar_terms',  # 节气

                # bool
                'is_month_end',
                'is_month_start',
                'is_quarter_end',
                'is_quarter_start',
                'is_year_end',
                'is_year_start',
                'is_weekend',  #
                'is_holiday',  #
                'is_holiday4us',
                'is_in_lieu',  #
                'is_special_day',  #
                'is_solar_terms',  #

                # 'is_leap_year',
                # "days_in_month",  # 月的天数

            )

    def transform(self, s: pd.Series):
        assert s.dtypes == 'datetime64[ns]'

        df = s.to_frame()
        for feat in tqdm(self.feats, "🕛"):
            if hasattr(s.dt, feat):
                _ = s.dt.__getattribute__(feat)
            else:
                _ = self.__getattribute__(feat)(s)

            if _.dtype == 'bool':
                _ = _.astype(int)

            df[f"{s.name}_{feat}"] = _  # lag

        return df

    def timestamp2date(self, ts):
        return pd.to_datetime(ts, 'coerce', unit='s', infer_datetime_format=True)

    def datestr2date(self, ts):
        try:
            _ = ts.astype('datetime64[ns]')
        except Exception as e:
            print(f"astype('datetime64[ns]'): {e}")
            _ = pd.to_datetime(ts, 'coerce', infer_datetime_format=True)
        return _

    @staticmethod
    def monthweek(ts: pd.Series):
        """
        获取指定的某天是某个月的第几周
        周一为一周的开始
        实现思路：就是计算当天在本年的第y周，本月一1号在本年的第x周，然后求差即可。
        """
        e = ts.dt.strftime("%W").astype(int)
        b = (ts - pd.to_timedelta(ts.dt.day - 1, 'day')).dt.strftime("%W").astype(int)
        return e - b + 1

    @staticmethod
    def is_weekend(s: pd.Series):
        return s.dt.dayofweek >= 5

    @staticmethod
    def is_holiday(s: pd.Series):  # 法定节假日
        from chinese_calendar import is_holiday, is_workday, is_in_lieu, get_holiday_detail, get_solar_terms

        return s.map(is_holiday)

    @staticmethod
    def is_holiday4us(s: pd.Series):
        us_holidays = USFederalHolidayCalendar().holidays(start=s.dt.date.min(), end=s.dt.date.max())
        return s.isin(us_holidays)

    @staticmethod
    def is_in_lieu(s: pd.Series):  # 调休日
        from chinese_calendar import is_holiday, is_workday, is_in_lieu, get_holiday_detail, get_solar_terms

        return s.map(is_in_lieu)

    def is_solar_terms(self, s: pd.Series):  # 节气
        return self.solar_terms(s).map(lambda x: 0 if x is np.nan else 1)

    @staticmethod
    def solar_terms(s: pd.Series):  # 节气
        from chinese_calendar import is_holiday, is_workday, is_in_lieu, get_holiday_detail, get_solar_terms

        _ = lru_cache(256)(lambda x: get_solar_terms(x, x))

        return s.map(_).str[-1]

    @staticmethod
    def holiday_name(s: pd.Series):
        from chinese_calendar import is_holiday, is_workday, is_in_lieu, get_holiday_detail, get_solar_terms

        # 或者在判断的同时，获取节日名
        _ = lru_cache(256)(lambda x: get_holiday_detail(x)[1])  # on_holiday, holiday_name

        return s.map(_)

    @staticmethod
    def is_special_day(s: pd.Series):
        """双十一等等"""  # todo
        special_days = {
            '06-18', '08-18', '11-11'
        }
        pattern = "|".join(special_days)
        return s.astype(str).str.contains(pattern)

    @staticmethod
    def day_part(s: pd.Series):
        @lru_cache(32)
        def f(hour):
            hour += 1
            if hour in [4, 5]:
                return 0  # "dawn"
            elif hour in [6, 7]:
                return 1  # "early morning"
            elif hour in [8, 9, 10]:
                return 2  # "late morning"
            elif hour in [11, 12, 13]:
                return 3  # "noon"
            elif hour in [14, 15, 16]:
                return 4  # "afternoon"
            elif hour in [17, 18, 19]:
                return 5  # "evening"
            elif hour in [20, 21, 22]:
                return 6  # "night"
            elif hour in [23, 24, 1, 2, 3]:
                return 7  # "midnight"
            else:
                return np.nan

        return s.dt.hour.map(f)

    @staticmethod
    def timestamp(s: pd.Series):
        return pd.DatetimeIndex(s).asi8 // 10 ** 9  # s.astype(np.int64) // 10**9

if __name__ == '__main__':
    import pandas as pd

    ts = pd.date_range('2022-10-01', '2022-10-30', freq='h').to_series()
    print(DateTimeFeats(['is_solar_terms']).transform(ts))

    from tqdm import tqdm

    tqdm()

{'is_holiday': 'chinese_calendar.is_holiday', 'is_workday': 'chinese_calendar.is_workday', 'is_in_lieu': 'chinese_calendar.is_in_lieu', 'get_holiday_detail': 'chinese_calendar.get_holiday_detail', 'get_solar_terms': 'chinese_calendar.get_solar_terms'}


from django.core.management import BaseCommand
from icoprocessing.models import ICOModel
import random
import string
from datetime import date

class Command(BaseCommand):

    def add_arguments(self, parser):
        parser.add_argument('number', type=int)

    def handle(self, *args, **options):

        my_int_argument = options['number']

        for i in range (my_int_argument) :

            ico_start_date , ico_end_date = self.random_dates()
            min_cap_in_eth = random.choice(range(1000000))
            max_cap_in_eth = random.choice(range(min_cap_in_eth +10, 1000000000))
            tokens_per_eth = random.choice(range(500))
            discount = random.choice(range(50))
            max_token_supply = random.choice(range(1000000000))
            for_sale = random.choice(range(1000000))
            white_label_address = self.random_trash()
            admin_email = self.random_trash() + '@gmail.com'

            model = ICOModel()

            model.ico_start_date = ico_start_date
            model.ico_end_date = ico_end_date
            model.min_cap_in_eth = min_cap_in_eth
            model.max_cap_in_eth = max_cap_in_eth
            model.tokens_per_eth = tokens_per_eth
            model.discount = discount
            model.max_token_supply = max_token_supply
            model.for_sale = for_sale
            model.white_label_address = white_label_address
            model.admin_email = admin_email

            model.save()

    def random_trash(self):
        random_chunk = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(random.choice(range(6, 15)))])
        return random_chunk

    def random_dates (self):
        year = random.choice(range(2018, 2030))
        month = random.choice(range(1, 12))
        day = random.choice(range(1, 28))

        start_date = date(year, month, day)

        year = random.choice(range(year+1, 2040))
        month = random.choice(range(1, 12))
        day = random.choice(range(1, 28))

        end_date = date(year, month, day)

        return (start_date, end_date)


"""
Plot explaining the principle of a Kernel-Density-Estimation (KDE).

"""

# author: Thomas Haslwanter, date: May-2015

# Import standard packages
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# additional packages
import mystyle

# Generate dummy data
x = np.array([-2.1, -1.3, -0.4, 1.9, 5.1, 6.2])

# Prepare cumulative arrays
xcum = np.arange(-6, 11, 0.1)
ycum = np.zeros_like(xcum)

# Left plot: histogram ------------------------
plt.subplot(121)

plt.hist(x, bins=6, range=[-4, 8], normed=True)

plt.xlim(-6, 11)
plt.ylim(-0.005, 0.18)
plt.xlabel('x')
plt.ylabel('Density Function')
plt.hold(True)

# Add rugplot
for ii in range(len(x)):
    plt.plot([x,x], [0, -0.005], 'b')

# Explanation of KDE --------------------

# Width of the individual Gaussians
var = 2.25
sd = np.sqrt(var)

# Plot individual Gaussians
def plotNorm(pos, sd, xcum, ycum):
    # Individual curve
    x = np.arange(pos-3*sd, pos+3*sd, 0.1)
    nd = stats.norm(pos, sd)
    y = nd.pdf(x)
    plt.plot(x,y/10, 'r--')

    # Cumulative curve
    xcr = np.round(xcum*10)
    xir = np.round(x*10)
    for ii in range(len(xir)):
        ycum[xcr==xir[ii]] += y[ii]
    return ycum

# Right plot
plt.subplot(122)

# Format
plt.hold(True)
plt.xlim(-6, 11)
plt.ylim(-0.005, 0.18)
plt.xlabel('x')
plt.axhline(0)

# Rugplot & individual Gaussians
for ii in range(len(x)):
    plt.plot([x,x], [0, -0.005], 'b')
    ycum = plotNorm(x[ii], sd, xcum, ycum)

# Plot cumulative curve
ycum /= np.sum(ycum)/10
plt.plot(xcum, ycum)

mystyle.printout_plain('KDEexplained.png')
plt.show()


import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import copy
import math

import utils
import hydra
import kornia
import wandb

from replay_buffer import PrioritizedReplayBuffer

# from
# https://github.com/mlperf/inference/blob/master/others/edge/object_detection/ssd_mobilenet/pytorch/utils.py#L40
class Conv2d_tf(nn.Conv2d):
    """
    Conv2d with the padding behavior from TF
    """
    def __init__(self, *args, **kwargs):
        kwargs_minus_padding = dict(kwargs)
        if "padding" in kwargs_minus_padding:
            del kwargs_minus_padding["padding"]
        super(Conv2d_tf, self).__init__(*args, **kwargs_minus_padding)
        self.padding = kwargs.get("padding", "SAME")

    def _compute_padding(self, input, dim):
        input_size = input.size(dim + 2)
        filter_size = self.weight.size(dim + 2)
        effective_filter_size = (filter_size - 1) * self.dilation[dim] + 1
        out_size = (input_size + self.stride[dim] - 1) // self.stride[dim]
        total_padding = max(0, (out_size - 1) * self.stride[dim] +
                            effective_filter_size - input_size)
        additional_padding = int(total_padding % 2 != 0)

        return additional_padding, total_padding

    def forward(self, input):
        if self.padding == "VALID":
            return F.conv2d(
                input,
                self.weight,
                self.bias,
                self.stride,
                padding=0,
                dilation=self.dilation,
                groups=self.groups,
            )
        rows_odd, padding_rows = self._compute_padding(input, dim=0)
        cols_odd, padding_cols = self._compute_padding(input, dim=1)
        if rows_odd or cols_odd:
            input = F.pad(input, [0, cols_odd, 0, rows_odd])

        return F.conv2d(
            input,
            self.weight,
            self.bias,
            self.stride,
            padding=(padding_rows // 2, padding_cols // 2),
            dilation=self.dilation,
            groups=self.groups,
        )

class SEEncoder(nn.Module):
    """Convolutional encoder of pixels observations."""
    def __init__(self, obs_shape):
        super().__init__()

        self.feature_dim = 64 * 4 * 4

        self.conv1 = Conv2d_tf(obs_shape[0], 32, 5, stride=5, padding='SAME')
        self.conv2 = Conv2d_tf(32, 64, 5, stride=5, padding='SAME')

        self.outputs = dict()

    def forward(self, obs):
        obs = obs / 255.
        self.outputs['obs'] = obs

        h = torch.relu(self.conv1(obs))
        self.outputs['conv1'] = h

        h = torch.relu(self.conv2(h))
        self.outputs['conv2'] = h

        out = h.view(h.size(0), -1)
        self.outputs['out'] = out

        assert out.shape[1] == self.feature_dim

        return out

    def log(self, logger, step):
        for k, v in self.outputs.items():
            logger.log_histogram(f'train_encoder/{k}_hist', v, step)
            if len(v.shape) > 2:
                logger.log_image(f'train_encoder/{k}_img', v[0], step)

        logger.log_param(f'train_encoder/conv1', self.conv1, step)
        logger.log_param(f'train_encoder/conv2', self.conv2, step)

class Encoder(nn.Module):
    """Convolutional encoder of pixels observations."""
    def __init__(self, obs_shape):
        super().__init__()

        self.feature_dim = 64 * 11 * 11

        self.conv1 = Conv2d_tf(obs_shape[0], 32, 8, stride=4, padding='SAME')
        self.conv2 = Conv2d_tf(32, 64, 4, stride=2, padding='SAME')
        self.conv3 = Conv2d_tf(64, 64, 3, stride=1, padding='SAME')

        self.outputs = dict()

    def forward(self, obs):
        obs = obs / 255.
        self.outputs['obs'] = obs

        h = torch.relu(self.conv1(obs))
        self.outputs['conv1'] = h

        h = torch.relu(self.conv2(h))
        self.outputs['conv2'] = h

        h = torch.relu(self.conv3(h))
        self.outputs['conv3'] = h

        out = h.view(h.size(0), -1)
        self.outputs['out'] = out

        assert out.shape[1] == self.feature_dim

        return out

    def log(self, logger, step):
        for k, v in self.outputs.items():
            logger.log_histogram(f'train_encoder/{k}_hist', v, step)
            if len(v.shape) > 2:
                logger.log_image(f'train_encoder/{k}_img', v[0], step)

        logger.log_param(f'train_encoder/conv1', self.conv1, step)
        logger.log_param(f'train_encoder/conv2', self.conv2, step)
        logger.log_param(f'train_encoder/conv3', self.conv3, step)

class Intensity(nn.Module):
    def __init__(self, scale=0.1):
        super().__init__()
        self.scale = scale

    def forward(self, x):
        noise = 1.0 + (self.scale * torch.randn(
            (x.size(0), 1, 1, 1), device=x.device).clamp_(-2.0, 2.0))
        return x * noise

class Critic(nn.Module):
    """Critic network, employes double Q-learning."""
    def __init__(self, encoder_cfg, num_actions, hidden_dim, hidden_depth,
                 dueling, aug_type, image_pad, intensity_scale):
        super().__init__()

        AUGMENTATIONS = {
            'intensity':
            Intensity(scale=intensity_scale),
            'reflect_crop':
            nn.Sequential(nn.ReplicationPad2d(image_pad),
                          kornia.augmentation.RandomCrop((84, 84))),
            'crop_intensity':
            nn.Sequential(nn.ReplicationPad2d(image_pad),
                          kornia.augmentation.RandomCrop((84, 84)),
                          Intensity(scale=intensity_scale)),
            'zero_crop':
            nn.Sequential(nn.ZeroPad2d(image_pad),
                          kornia.augmentation.RandomCrop((84, 84))),
            'rotate':
            kornia.augmentation.RandomRotation(degrees=5.0),
            'h_flip':
            kornia.augmentation.RandomHorizontalFlip(p=0.5),
            'v_flip':
            kornia.augmentation.RandomVerticalFlip(p=0.5),
            'none':
            nn.Identity(),
            'all':
            nn.Sequential(nn.ReplicationPad2d(image_pad),
                          kornia.augmentation.RandomCrop((84, 84)),
                          Intensity(scale=intensity_scale),
                          kornia.augmentation.RandomRotation(degrees=5.0),
                          kornia.augmentation.RandomHorizontalFlip(p=0.5),
                          kornia.augmentation.RandomVerticalFlip(p=0.5),
                          kornia.augmentation.RandomHorizontalFlip(p=0.5),), # TODO DrQ fix this line.
        }

        assert aug_type in AUGMENTATIONS.keys()

        self.aug_trans = AUGMENTATIONS.get(aug_type)

        self.encoder = hydra.utils.instantiate(encoder_cfg)

        self.dueling = dueling
        self.num_actions = num_actions

        if dueling:
            # TODO dueling DQN, define the value and the advantage network
            self.V = utils.mlp(self.encoder.feature_dim, hidden_dim,1, hidden_depth)
            self.A = utils.mlp(self.encoder.feature_dim, hidden_dim,num_actions, hidden_depth)
            # END TODO
        else:
            self.Q = utils.mlp(self.encoder.feature_dim, hidden_dim,
                               num_actions, hidden_depth)

        self.outputs = dict()
        self.apply(utils.weight_init)

    def forward(self, obs, use_aug=False):
        if use_aug:
            obs = self.aug_trans(obs)

        obs = self.encoder(obs)

        if self.dueling:
            # TODO dueling DQN, compute the q value from the value and advantage network
            v = self.V(obs)
            a = self.A(obs)
            q = v + (a - a.mean())
            # END TODO
        else:
            q = self.Q(obs)

        self.outputs['q'] = q

        return q

    def log(self, logger, step):
        self.encoder.log(logger, step)

        for k, v in self.outputs.items():
            logger.log_histogram(f'train_critic/{k}_hist', v, step)

        M = self.A if self.dueling else self.Q
        for i, m in enumerate(M):
            if type(m) is nn.Linear:
                logger.log_param(f'train_critic/q_fc{i}', m, step)

class DRQLAgent(object):
    """Data regularized Q-learning: Deep Q-learning."""
    def __init__(self, obs_shape, num_actions, device, encoder_cfg, critic_cfg,
                 discount, lr, beta_1, beta_2, weight_decay, adam_eps,
                 max_grad_norm, critic_tau, critic_target_update_frequency,
                 batch_size, multistep_return, eval_eps, double_q,
                 prioritized_replay_beta0, prioritized_replay_beta_steps):
        self.device = device
        self.discount = discount
        self.critic_tau = critic_tau
        self.num_actions = num_actions
        self.critic_target_update_frequency = critic_target_update_frequency
        self.batch_size = batch_size
        self.eval_eps = eval_eps
        self.max_grad_norm = max_grad_norm
        self.multistep_return = multistep_return
        self.double_q = double_q
        assert prioritized_replay_beta0 <= 1.0
        self.prioritized_replay_beta0 = prioritized_replay_beta0
        self.prioritized_replay_beta_steps = prioritized_replay_beta_steps
        self.eps = 0

        self.critic = hydra.utils.instantiate(critic_cfg).to(self.device)
        self.critic_target = hydra.utils.instantiate(critic_cfg).to(
            self.device)
        self.critic_target.load_state_dict(self.critic.state_dict())

        self.critic_optimizer = torch.optim.Adam(self.critic.parameters(),
                                                 lr=lr,
                                                 betas=(beta_1, beta_2),
                                                 weight_decay=weight_decay,
                                                 eps=adam_eps)

        self.train()
        self.critic_target.train()

    def train(self, training=True):
        self.training = training
        self.critic.train(training)

    def act(self, obs):
        with torch.no_grad():
            obs = torch.FloatTensor(obs).to(self.device)
            obs = obs.unsqueeze(0).contiguous()
            q = self.critic(obs)
            action = q.max(dim=1)[1].item()
        return action

    def update_critic(self, obs, action, reward, next_obs, not_done, weights,
                      logger, step):

        with torch.no_grad():
            discount = self.discount**self.multistep_return
            if self.double_q:
                # TODO double Q learning
                # Find the target Q value based on the critic
                # and the critic target networks to find the right
                # value of target_Q
                next_Q = self.critic(next_obs, use_aug=True)
                next_action = next_Q.argmax(dim=1).unsqueeze(1)
                next_Q_target = self.critic_target(next_obs, use_aug=True)
                next_Q_target = torch.gather(next_Q_target,1,next_action)
                target_Q = reward + (not_done * discount * next_Q_target)
                # End TODO
            else:
                next_Q = self.critic_target(next_obs, use_aug=True)
                next_Q = next_Q.max(dim=1)[0].unsqueeze(1)
                target_Q = reward + (not_done * discount * next_Q)

        # get current Q estimates
        current_Q = self.critic(obs, use_aug=True)
        current_Q = current_Q.gather(1, action)

        td_errors = current_Q - target_Q
        critic_losses = F.smooth_l1_loss(current_Q, target_Q, reduction='none')
        if weights is not None:
            critic_losses *= weights

        critic_loss = critic_losses.mean()

        logger.log('train_critic/loss', critic_loss, step)
        wandb.log({"train_critic_loss":critic_loss})

        # Optimize the critic
        self.critic_optimizer.zero_grad()
        critic_loss.backward()
        if self.max_grad_norm > 0.0:
            nn.utils.clip_grad_norm_(self.critic.parameters(),
                                     self.max_grad_norm)
        self.critic_optimizer.step()

        self.critic.log(logger, step)

        return td_errors.squeeze(dim=1).detach().cpu().numpy()

    def update(self, replay_buffer, logger, step):

        prioritized_replay = type(replay_buffer) == PrioritizedReplayBuffer

        if prioritized_replay:
            fraction = min(step / self.prioritized_replay_beta_steps, 1.0)
            beta = self.prioritized_replay_beta0 + fraction * (
                1.0 - self.prioritized_replay_beta0)
            obs, action, reward, next_obs, not_done, weights, idxs = replay_buffer.sample_multistep(
                self.batch_size, beta, self.discount, self.multistep_return)
        else:
            obs, action, reward, next_obs, not_done = replay_buffer.sample_multistep(
                self.batch_size, self.discount, self.multistep_return)
            weights = None

        logger.log('train/batch_reward', reward.mean(), step)
        wandb.log({"avg_bath_reward":reward.mean()})

        td_errors = self.update_critic(obs, action, reward, next_obs, not_done,
                                       weights, logger, step)
        if prioritized_replay:
            # TODO prioritized replay buffer: update the priorities in the replay buffer using td_errors
            replay_buffer.update_priorities(idxs,abs(td_errors))
            # End TODO

        if step % self.critic_target_update_frequency == 0:
            utils.soft_update_params(self.critic, self.critic_target,
                                     self.critic_tau)


import pytest
from black_jack.blackjack_model import Card, BlackjackModel #, # calculate_black_jack_sum

# example test without parametrization
# def test_calculate_black_jack_sum():
#     result = calculate_black_jack_sum([Card('3', 'C'), Card('3', 'C')])
#     expected_result = 6
#     assert result == expected_result

# working test with parametrization (allows you to run the same test with multiple inputs) note that 'test_input,
# expected_output' is a SINGLE string!
# also note the class must be instantiated first. pytest methods do not take the 'self' keyword, you must *always*
# instantiate your test class.
@pytest.mark.parametrize('test_input, expected_output', (
                                                         ([], 0),
                                                         ([Card('10', 'C')], 10),
                                                         ([Card('3', 'C'), Card('3', 'C')], 6),
                                                         ([Card('5', 'C'), Card('K', 'C'), Card('Q', 'C')], 25),
                                                         ([Card('A', 'C'), Card('A', 'D')], 12),
                                                         ([Card('A', 'C'), Card('A', 'D'), Card('A', 'D')], 13),
                                                         ([Card('A', 'C'), Card('J', 'D')], 21),
                                                         ([Card('A', 'C'), Card('A', 'D'), Card('Q', 'D')], 12)))
def test_calculate_black_jack_sum(test_input, expected_output):
    model = BlackjackModel()
    result = model.calculate_black_jack_sum(test_input)
    assert result == expected_output


import sqlite3
from sqlite3 import Error

db_file = "NaizDB.db"
conn = sqlite3.connect(db_file)

cur = conn.cursor()
cur.execute("SELECT * FROM CameraList")
rows = cur.fetchall()
iTotal = len(rows)
iCount = 0
isAlive = 0

for row in rows :
    if (row[2].startswith("10.")) == True :
        if (row[5]==1) : isAlive = isAlive + 1
        iCount = iCount + 1
        print( row )

print("Total    = " + str(iTotal))
print("4 Campus = " + str(iCount))
print("Alive    = " + str(isAlive))
#for row in rows :  print( row )


#
# @file <common.py>
#
# @author Fernando Mendiburu - <fernando.mendiburu@ee.ufcg.edu.br>
#

import os
import random

from selenium.webdriver.common.by import By

global_var_delay = 3

class Path:
    PATH = os.path.expanduser('~') + '/maps_calculator/'
    CHROMEDRIVER_FILE = 'chromedriver/chromedriver'

class Unit:
    HOUR_UNIT = 'hr'
    MINUTS_UNIT = 'min'
    KILOMETER_UNIT = 'km'
    SPEED_UNIT = 'km/h'
    METER_UNIT = 'm'
    SECOND_UNIT = 's'

class Misc:
    SEPARATOR = "-" * 70
    URL_MAPS = 'https://www.google.com/maps/'
    LANGUAGE = 'English'
    TRANSPORT = 'Car'
    DELTA_SPEED = 0.5
    LONG_TRIP_HR = 8

class Speed:
    VERY_SLOW = range(0, 20)
    SLOW = range(20, 40)
    MEDIUM = range(40, 80)
    FAST = range(80, 150)
    VERY_FAST = range(150, 400)

class Transport:
    REVERSE = ['turtle', 'tricycle']
    VERY_SLOW = ['walk', 'horse', 'bicycle', 'skate', 'rollers']
    SLOW = ['motorbike', 'electric bike']
    MEDIUM = ['Honda e', 'Fiat 500', 'Dodge Caravan']
    FAST = ['Toyota Camry', 'Audi TT', 'Renault Sandero']
    VERY_FAST = ['Bugatti Veyron', 'Ford GT90', 'Tesla Roadster', 'Audi R8']
    NON_SENSE = ['rocket', 'missile']

class Locators:
    POPUP_BUTTON = (By.XPATH, '//*[@id="introAgreeButton"]/span/span')
    BOX_CURRENT_PLACE = (By.XPATH, '//*[@id="sb_ifc51"]/input')
    BOX_DESTINATION_PLACE = (By.XPATH, '//*[@id="sb_ifc52"]/input')
    SEARCH_BUTTON = (By.XPATH, '//*[@id="searchbox-searchbutton"]')
    SEARCH_DIRECTIONS_ICON = (By.ID, 'searchbox-directions')
    SUGGESTIONS_PLACES = (By.CLASS_NAME, 'sbsb_c')
    TRIP_DESCRIPTION = (By.XPATH, '//*[@id="section-directions-trip-0"]/div/div[1]')
    NO_POSSIBLE_TRIP = (By.XPATH, '//*[@id="pane"]/div/div[1]/div/div/div[6]/div/jsl')
    HAMBURGUER_BUTTON = (By.XPATH, '//*[@id="omnibox-singlebox"]/div[1]/div[1]/button')
    LANGUAGE_BUTTON = (By.XPATH, '//*[@id="settings"]/div/div[2]/ul/ul[2]/li[2]/button')

    TRANSPORT = (By.XPATH, '//*[@id="omnibox-directions"]/div/div[2]/div/div/div[1]/div[2]/button/img')
    ENGLISH_LANGUAGE = (By.XPATH, '//*[@id="languages"]/div/div[2]/div[2]/ul[1]/li[11]/a')

class Functions:
    @staticmethod
    def credits():
        print(Misc.SEPARATOR)
        print('maps_calculator: Bot to calculate normal and custom trip conditions.')
        print('Fernando Mendiburu - 2021')
        print(Misc.SEPARATOR)

    @staticmethod
    def get_option(web_elements):
        option = None
        b_correct_option = False
        container_w_e = web_elements
        while not b_correct_option:
            print('\nOptions:')
            for i, web_element in enumerate(container_w_e, 1):
                text = web_element.text.split("\n")[0]
                print(f'{i}. {text}')
            option = input('\nChoose the option: ')
            b_correct_option = Functions.verify(option, container_w_e)
        return int(option)

    @staticmethod
    def verify(option, elements):
        try:
            if 0 < int(option) <= len(elements):
                return True
            else:
                print('Invalid option!')
                return False
        except:
            print('Invalid option!')
            return False

    @staticmethod
    def get_string_to_hours(string):
        list_duration = string.split(' ')
        if len(list_duration) == 4 and list_duration[1] == Unit.HOUR_UNIT and \
                list_duration[3] == Unit.MINUTS_UNIT:
            return round(float(list_duration[0]) + float(list_duration[2])/60, 2)
        elif len(list_duration) == 2 and list_duration[1] == Unit.MINUTS_UNIT:
            return round(float(list_duration[0])/60, 2)
        elif len(list_duration) == 2 and list_duration[1] == Unit.HOUR_UNIT:
            return round(float(list_duration[0]), 2)
        print('Problem to get the duration format!')
        return None

    @staticmethod
    def get_string_to_kilometers(string):
        if string.find(Unit.KILOMETER_UNIT):
            dist_str = string.split(' ')[0]
            dist_str = dist_str.replace(',', '')
            return round(float(dist_str), 2)
        else:
            print('Problem to get the distance format!')

    @staticmethod
    def get_duration_hours(web_element):
        try:
            return Functions.get_string_to_hours(web_element.text.split("\n")[0])
        except:
            print('Problem to get the duration of this trip!')

    @staticmethod
    def get_distance_km(web_element):
        try:
            return Functions.get_string_to_kilometers(web_element.text.split("\n")[1])
        except:
            print('Problem to get the distance of this trip!')

    @staticmethod
    def increase_time_step(delta_t):
        global global_var_delay
        global_var_delay += delta_t
        print(f'Set new time step: {global_var_delay}{Unit.SECOND_UNIT}!')

    @staticmethod
    def get_time_step():
        global global_var_delay
        return global_var_delay

    @staticmethod
    def is_not_valid_arg(arg):
        if arg is None or arg is '' or arg == 0:
            print('Invalid value. Insert the correct one!')
            return True
        else:
            return False

    @staticmethod
    def get_valid_arg(type, prompt):
        is_invalid_arg = True
        arg = None
        while is_invalid_arg:
            try:
                if type == 'place':
                    arg = str(input(f'{prompt}: '))
                if type == 'duration':
                    arg = Functions.get_string_to_hours(input(f'{prompt}: '))
                is_invalid_arg = Functions.is_not_valid_arg(arg)
            except ValueError:
                pass
        return arg

    @staticmethod
    def get_mean_speed(distance, duration):
        return round(distance/duration, 2)

    @staticmethod
    def is_faster_than_normal(speed, reference):
        reference_augmented = reference + reference * Misc.DELTA_SPEED
        return speed > reference_augmented

    @staticmethod
    def is_slower_than_normal(speed, reference):
        reference_augmented = reference - reference * Misc.DELTA_SPEED
        return speed < reference_augmented

    @staticmethod
    def get_mean_transport(speed):
        speed = int(speed)
        if speed < 0:
            return random.choice(Transport().REVERSE)
        elif speed in Speed.VERY_SLOW:
            return random.choice(Transport().VERY_SLOW)
        elif speed in Speed.SLOW:
            return random.choice(Transport().SLOW)
        elif speed in Speed.MEDIUM:
            return random.choice(Transport().MEDIUM)
        elif speed in Speed.FAST:
            return random.choice(Transport().FAST)
        elif speed in Speed.VERY_FAST:
            return random.choice(Transport().VERY_FAST)
        else:
            return random.choice(Transport().NON_SENSE)

    @staticmethod
    def is_long_trip(time):
        return time >= Misc.LONG_TRIP_HR

    @staticmethod
    def print_duration_beauty(duration):
        if duration < 1:
            return f'{int(duration * 60)} {Unit.MINUTS_UNIT}'
        else:
            return f'{round(duration, 2)} {Unit.HOUR_UNIT}'

    @staticmethod
    def print_distance_beauty(distance):
        if distance < 1:
            return f'{int(distance * 1000)} {Unit.METER_UNIT}'
        else:
            return f'{round(distance, 2)} {Unit.KILOMETER_UNIT}'

    @staticmethod
    def print_fast_slow(speed, reference):
        if Functions.is_faster_than_normal(speed, reference):
            print('You should go faster (dangerously?) than normal trip.')
            print(f'A suggested transport could be: {Functions.get_mean_transport(speed)}!')
        elif Functions.is_slower_than_normal(speed, reference):
            print('You can go slower than normal trip!')
        else:
            print('Enjoy the trip and be careful!')

    @staticmethod
    def print_is_long_trip(time, conditions):
        if Functions.is_long_trip(time):
            print(f'{conditions} conditions: Stops are not considered. It will take you more time!')
        else:
            pass

    @staticmethod
    def print_result(place_current,
                     place_destination,
                     transport,
                     duration,
                     distance,
                     conditions):
        mean_speed = Functions.get_mean_speed(distance, duration)

        print(f'\n{Misc.SEPARATOR}')
        print(f'{conditions} conditions:')
        print(f'{place_current} -> {place_destination}')
        print(f'Transport: {transport}')
        print(f'{conditions} duration: {Functions.print_duration_beauty(duration)}. '
              f'Distance: {distance} {Unit.KILOMETER_UNIT}')
        Functions.print_is_long_trip(duration, conditions)
        print(f'Mean speed: {mean_speed} {Unit.SPEED_UNIT}.')
        print(Misc.SEPARATOR)

    @staticmethod
    def print_observation(duration_maps,
                          duration_user,
                          distance):

        mean_speed_maps = Functions.get_mean_speed(distance, duration_maps)
        mean_speed_user = Functions.get_mean_speed(distance, duration_user)
        print(f'\n{Misc.SEPARATOR}')
        print(f'Observations:')
        Functions.print_fast_slow(mean_speed_user, mean_speed_maps)

        print(Misc.SEPARATOR)

#-------------------------------------------------------------------------------------------
#------------------------------------------Main---------------------------------------------
#-------------------------------------------------------------------------------------------

if __name__ == '__main__':
    pass


import streamlit as st

st.set_page_config(layout="wide")

import threading

import src.pages.front_page as front_page
import src.pages.air_quality as air_quality
import src.pages.monthly_averages as monthly_averages
import src.pages.pickups_dropoffs as pickups_dropoffs

import ag_grid_hack

import base64
import json

## retro code review comment

PAGES = {
    "Central Business District Tolling Program": {
        "NYC Air Quality": air_quality,
        "TLC Monthly Averages": monthly_averages,
        "TLC Pickups and Dropoffs": pickups_dropoffs
    }
}

## retro code review comment

def set_session_state(page_session_key, parent_selection, child_selection):
    st.session_state[page_session_key] = {"parent_selection": parent_selection, "child_selection": child_selection}

## retro code review comment

def main() -> None:
    """Main function of the App"""
    # render_svg_example()

    ag_grid_hack.inject_css()

    st.markdown(
        """ <style>
        .css-18e3th9 {{
                padding-top: 0rem;
                padding-right: -1rem;
                padding-left: 1rem;
                padding-bottom: 0rem;
                width: 10rem;
            }}
        .css-12oz5g7 {{
            padding-top: 0rem;
            padding-right: -1rem;
            padding-left: 1rem;
            padding-bottom: 0rem;
            max-width: 80%;
        }}
        #MainMenu {visibility: hidden;}
        footer {visibility: hidden;}
         </style> """,
        unsafe_allow_html=True,
    )
## retro code review comment

    # Initialize session state:
    page_session_key = "page_selected"
    if page_session_key not in st.session_state:
        st.session_state[page_session_key] = None

    # Multi hierarchy sidebar:
    with st.sidebar:
        parents = [k for k in PAGES.keys()]
        parent_selection = None
        child_selection = None
        expanders = {}
        for parent in parents:
            expanders[parent] = st.expander(parent, expanded=False)
            for page in PAGES[parent].keys():
                with expanders[parent]:
                    blank, button_col = st.columns((0.05, 0.95))
                    with button_col:
                        st.button(
                            page,
                            key=f"{parent}${page}",
                            on_click=set_session_state,
                            args=(page_session_key, parent, page),
                        )
## retro code review comment

    # Call page
    if st.session_state[page_session_key]:
        parent_selection = st.session_state[page_session_key]["parent_selection"]
        child_selection = st.session_state[page_session_key]["child_selection"]
        PAGES[parent_selection][child_selection].app()
        # report statistics
        # count_pageview(f"{parent_selection}: {child_selection}")
    else:
        front_page.app()

if __name__ == "__main__":
    # # Load CSS
    # with open(".streamlit/style") as css:
    #     st.markdown(f"<style>{css.read()}</style>", unsafe_allow_html=True)

    # Run app
    main()


import shutil

import numpy as np
import torchvision.transforms as transforms

from globals import Globals
from mix import Ent
from utils import Rotate
from utils import mkdir, TMix, TGen, TExp

g = Globals()

mkdir(g.default_repo_dir)
shutil.rmtree(g.default_repo_dir + "labels", ignore_errors=True)
tasks = []

# Generate samples and features
if False:
    tasks.append(TGen('Gen', 'lsun', 'true', 9, 'resnet34'))
    tasks.append(TGen('Gen', 'lsun', 'DCGAN', 9, 'resnet34'))
    tasks.append(TGen('Gen', 'celeba', 'true', 24, 'resnet34'))
    tasks.append(TGen('Gen', 'celeba', 'DCGAN', 24, 'resnet34'))
    tasks.append(TGen('Gen', 'cifar10', 'true', 400, 'resnet34'))
    tasks.append(TGen('Gen', 'cifar10', 'WGAN', 1900, 'resnet34'))

    tasks.append(TGen('Gen', 'lsun', 'true', 9, 'vgg16'))
    tasks.append(TGen('Gen', 'lsun', 'DCGAN', 9, 'vgg16'))
    tasks.append(TGen('Gen', 'celeba', 'true', 24, 'vgg16'))
    tasks.append(TGen('Gen', 'celeba', 'DCGAN', 24, 'vgg16'))

    tasks.append(TGen('Gen', 'lsun', 'true', 9, 'inception_v3'))
    tasks.append(TGen('Gen', 'lsun', 'DCGAN', 9, 'inception_v3'))
    tasks.append(TGen('Gen', 'celeba', 'true', 24, 'inception_v3'))
    tasks.append(TGen('Gen', 'celeba', 'DCGAN', 24, 'inception_v3'))

trans = transforms.Compose([transforms.Scale(64), transforms.ToTensor(
), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
trans_rand = transforms.Compose([transforms.Scale(64), transforms.Pad(4), transforms.RandomCrop(
    64), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
trans_rotate = transforms.Compose([transforms.Scale(
    64), Rotate(-1), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

# Metrics on different mixtures
# Only `*_smax` features are suggested to be used for `Incep`, `ModeScore` and `FID`
if False:
    for sampleSize in [2000]:
        for data in ['cifar10', 'celeba', 'lsun']:
            if data == 'celeba':
                model = 'DCGAN24'
            if data == 'lsun':
                model = 'DCGAN9'
            if data == 'cifar10':
                model = 'WGAN1900'

            for mix_ratio in np.arange(0, 1.1, 0.1):
                dataList = []
                if mix_ratio > 0:
                    dataList.append(
                        Ent(mix_ratio, data, 'true_test', trans, imageMode=0))
                if 1 - mix_ratio > 0:
                    dataList.append(
                        Ent(1 - mix_ratio, data, model, None, dup=1, imageMode=0))

                for featureType in ['resnet34_conv', 'pix']:
                    tasks.append(
                        TMix('Mix', sampleSize, data, featureType, dataList))

                tasks.append(
                    TMix('Incep', sampleSize, data, 'resnet34_smax', dataList))
                tasks.append(
                    TMix('ModeScore', sampleSize, data, 'resnet34_smax', dataList))
                tasks.append(
                    TMix('FID', sampleSize, data, 'resnet34_smax', dataList))

# Metrics on different number of samples
if False:
    for sampleSize in [100, 200, 400, 800, 1600, 3200, 6400, 12800]:
        for data in ['celeba', 'lsun']:
            for featureType in ['resnet34', 'vgg16', 'inception_v3']:
                for foldername in ['DCGAN24' if data == 'celeba' else 'DCGAN9', 'true_test']:
                    dataList = []
                    dataList.append(Ent(1.0, data, foldername, trans))

                    tasks.append(
                        TMix('Mix', sampleSize, data, featureType + '_conv', dataList))
                    tasks.append(
                        TMix('Incep', sampleSize, data, featureType + '_conv', dataList))
                    tasks.append(
                        TMix('ModeScore', sampleSize, data, featureType + '_conv', dataList))
                    tasks.append(
                        TMix('FID', sampleSize, data, featureType + '_conv', dataList))

# For robustness
# When using `trans_rotate` and `trans_rand`, only resnet34 is used for feature extraction.
if False:
    for sampleSize in [2000]:
        for data in ['celeba', 'lsun']:
            if data == 'celeba':
                model = 'DCGAN24'
            if data == 'lsun':
                model = 'DCGAN9'

            for mix_ratio in np.arange(0, 1.1, 0.1):
                for image_mode in [1, 2]:
                    dataList = []
                    if mix_ratio > 0:
                        dataList.append(Ent(
                            mix_ratio, data, 'true_test', trans_rotate if image_mode == 2 else trans_rand, imageMode=image_mode))
                    if 1 - mix_ratio > 0:
                        dataList.append(
                            Ent(1 - mix_ratio, data, 'true_test2', None))

                    for featureType in ['resnet34_conv', 'pix']:
                        tasks.append(
                            TMix('Mix', sampleSize, data, featureType, dataList))

                    tasks.append(
                        TMix('Incep', sampleSize, data, 'resnet34_smax', dataList))
                    tasks.append(
                        TMix('ModeScore', sampleSize, data, 'resnet34_smax', dataList))
                    tasks.append(
                        TMix('FID', sampleSize, data, 'resnet34_smax', dataList))

# Mode collapse, mode drop, overfit
if True:
    for data in ['celeba', 'lsun']:
        for exp in ['collapse', 'drop', 'overfit']:
            tasks.append(TExp(exp, data))

print(len(tasks))
np.save(g.default_repo_dir + "tasks", tasks)


"""
Image Utilities for Galen
Author: Siddhant Sharma, 2019
"""
__author__ = "Siddhant Sharma"

import cv2
import torch
import numpy as np
from skimage import measure

def to_channels_last(img):
    """
    Turn (H, W, C) to (C, H, W)

    Args:
    * img
        image (`np.ndarray`)

    Returns:
    channels first (`np.ndarray`)
    """
    img = np.swapaxes(img, 0, 2)
    img = np.swapaxes(img, 1, 2)
    return img

def to_channels_first(img):
    """
    Turn (C, H, W) to (H, W, C)

    Args:
    * img
        image (`np.ndarray`)

    Returns:
    channels last image (`np.ndarray`)
    """
    img = np.swapaxes(img, 0, 2)
    img = np.swapaxes(img, 0, 1)
    return img

def img_to_tensor(img, resize=True, resize_dims=(128, 128), clahe=True):
    """
    Convert image to Pytorch Tensor

    Args:
    * img
        Image to convert to Pytorch Tensor
        NOTE: Assume `np.uint8` input dtype
    * resize
        OPTIONAL
        Resize image to `resize_dims` (bool)
        Default: True
    * resize_dims
        OPTIONAL
        Resize to given size
        Default: (128, 128)
    * clahe
        OPTIONAL
        Apply CLAHE to image (bool)
        Default: True

    Returns:
    Pytorch image Tensor
    """
    if resize:
        img = cv2.resize(img, resize_dims, interpolation = cv2.INTER_AREA)
    if clahe:
        img = clahe_image(img)
    img = img.astype('float32')
    img /= 255.
    img = to_channels_last(img)
    return torch.from_numpy(img[np.newaxis]).float()

def tensor_to_img(tensor):
    """
    Convert Pytorch Tensor to Numpy image

    Args:
    * tensor
        Pytorch Tensor to convert (`torch.Tensor`)

    Returns:
    Numpy image (`np.ndarray`)
    """
    tensor = tensor.data.numpy()
    tensor = tensor[0]
    return to_channels_first(tensor)

def clahe_image(img):
    """
    CLAHE-ify an image

    Args:
    * img
        image (`np.ndarray`)

    Returns:
    CLAHE-ified image (`np.ndarray`)
    """
    img = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
    lab_planes = cv2.split(img)
    clahe = cv2.createCLAHE(clipLimit=2,tileGridSize=(8, 8))
    lab_planes[0]= clahe.apply(lab_planes[0])
    lab = cv2.merge(lab_planes)
    return cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)

def surf_match(img1, img2, ratio=0.5, save=True):
    """
    Return SURF matching score between two images
    First image should be original/input image,
    second image should be reconstruction image
    NOTE: Assume all images are `np.float32`
    TODO: Find a better way to save SURF output,
          it's not pretty right now and hard to
          understand

    Args:
    * img1
        image (`np.ndarray`)
    * img2
        image (`np.ndarray`)
    * ratio
        OPTIONAL
        How accurate of a match (int)
        The lower the ratio, the more accurate the match
    * save
        OPTIONAL
        Save visual output of SURF or not (bool)
        Default: True

    Returns:
    SURF similarity score (float)
    """
    # Convert images to `np.uint8`
    img1 *= 255.
    img1 = img1.astype('uint8')
    img2 *= 255.
    img2 = img2.astype('uint8')

    # Create SURF descriptor and find keypoints in both images
    sift = cv2.xfeatures2d.SURF_create()
    kp_1, desc_1 = sift.detectAndCompute(img1, None)
    kp_2, desc_2 = sift.detectAndCompute(img2, None)

    # Search the keypoints for matches
    index_params = dict(algorithm = 0, trees = 5)
    search_params = dict()
    flann = cv2.FlannBasedMatcher(index_params, search_params)
    matches = flann.knnMatch(desc_1, desc_2, k=2)

    # Find matches (within some give or take)
    good_points = []
    for m, n in matches:
        if m.distance < ratio * n.distance:
            good_points.append(m)

    # Save the output
    if save:
        cv2.imwrite('./outputs/surf.png', cv2.drawMatches(img1, kp_1, img2, kp_2, good_points, None))

    # Return the score
    return len(good_points) * 100 / len(kp_2)

def kaze_match(img1, img2, ratio=0.4, save=True):
    """
    Return KAZE matching score between two images
    First image should be original/input image,
    second image should be reconstruction image
    NOTE: Assume all images are `np.float32`
    TODO: Find a better way to save KAZE output,
          it's not pretty right now and hard to
          understand

    Args:
    * img1
        image (`np.ndarray`)
    * img2
        image (`np.ndarray`)
    * ratio
        OPTIONAL
        How accurate of a match (int)
        The lower the ratio, the more accurate the match
    * save
        OPTIONAL
        Save visual output of KAZE or not (bool)
        Default: True

    Returns:
    KAZE similarity score (float)
    """
    # Convert images to `np.uint8`
    img1 *= 255.
    img1 = img1.astype('uint8')
    img2 *= 255.
    img2 = img2.astype('uint8')

    # Create KAZE descriptor and find keypoints in both images
    kaze = cv2.KAZE_create()
    kp_1, desc_1 = kaze.detectAndCompute(img1, None)
    kp_2, desc_2 = kaze.detectAndCompute(img2, None)

    # Search the keypoints for matches
    index_params = dict(algorithm = 0, trees = 5)
    search_params = dict()
    flann = cv2.FlannBasedMatcher(index_params, search_params)

    # Find matches (within some give or take)
    matches = flann.knnMatch(desc_1, desc_2, k=2)
    good_points = []
    for m,n in matches:
        if m.distance < ratio * n.distance:
            good_points.append(m)

    # Save the output
    if save:
        cv2.imwrite('./outputs/kaze.png', cv2.drawMatches(img1, kp_1, img2, kp_2, good_points, None))

    # Return the score
    return len(good_points) * 100 / len(kp_2)

def get_bbox(img1, img2):
    """
    Get the area of the largest difference between the original
    and reconstructions
    Only should be used if input image is unhealthy

    Args:
    * img1
        original image (`np.ndarray`)
    * img2
        reconstruction image (`np.ndarray`)

    Returns:
    bbox image (`np.ndarray`)
    """
    # Grayscale
    img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    # Get differences using SSIM
    (score, diff) = measure.compare_ssim(img1_gray, img2_gray, full=True)
    diff = (diff * 255).astype("uint8")
    # Threshold differences
    thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
    # Extract contours
    contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    contours = contours[0] if len(contours) == 2 else contours[1]

    contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]

    # Find the largest contour (to a certain extent)
    # Some limits bc contour shouldn't be whole image
    largest = cv2.contourArea(contours[0])
    largest_idx = 0
    for c in range(len(contours)):
        area = cv2.contourArea(contours[c])
        if area > 40 and area < 6000:
            if largest < area:
                largest = area
                largest_idx = c
    img = np.copy(img1)
    x,y,w,h = cv2.boundingRect(contours[largest_idx])
    # Place contour bbox
    cv2.rectangle(img, (x, y), (x + w - 2, y + h - 2), (255,0,0), 2)
    return img

def get_heatmap(img1, img2):
    """
    Get the RGB difference between original and reconstruction
    First image should be original/input image
    Second image should be reconstruction image

    Args:
    * img1
        image (`np.ndarray`)
    * img2
        image (`np.ndarray`)

    Returns:
    heatmap image (`np.ndarray`)
    """
    error_r = np.fabs(np.subtract(img2[:,:,0], img1[:,:,0]))
    error_g = np.fabs(np.subtract(img2[:,:,1], img1[:,:,1]))
    error_b = np.fabs(np.subtract(img2[:,:,2], img1[:,:,2]))
    return np.maximum(np.maximum(error_r, error_g), error_b)


from collections import deque

def solution(s):
    alphabet = {
        'zero': "0",
        'one': '1',
        'two': '2',
        'three': '3',
        'four': '4',
        'five': '5',
        'six': '6',
        'seven': '7',
        'eight': '8',
        'nine': '9',
    }
    alphabet = []
    s = deque(s)
    answer = ''
    temp = ''

    while s:
        i = s.popleft()
        if i.isdigit():
            answer += i

        else:
            temp += i
            if temp in alphabet:
                answer += alphabet[temp]
                temp = ''

    return int(''.join(answer))

num_dic = {"zero": "0", "one": "1", "two": "2", "three": "3", "four": "4",
           "five": "5", "six": "6", "seven": "7", "eight": "8", "nine": "9"}
def solution2(s):
    answer = s
    for key, value in num_dic.items():
        print(answer.replace(key, value))
        # answer = answer.replace(key, value)
    # return int(answer)
s = "2three45sixseven"
print(solution2(s))

숫자 문자열과 영단어.py


#!/usr/bin/env python3

from datetime import datetime
import time
import os
import json

# ToDo
# use it as a command line tool
# have a log file to calculate how many sessions one has done

def main():
    show_header()
    data = read_data() # it is called first because the user might want to see only the progress
    user, user_input = get_user()
    sleep_time(user_input)
    save_data(data, user_input)

def show_header():
    print("=======================")
    print("Welcome to PomFocal")
    print("=======================")

def get_user():
    user = input("What is your name?")
    print(f"Hello {user}")
    choice = ['Pomodoro', 'Long Break', 'Short Break']
    print("What do you wish? - 1. Pomodoro focused work, 2. Long Break and 3. Short Break")
    print(f"""{user} for
    Pomodoro focused work enter : 1
    Long Break enter : 2
    Short Break : 3 """)
    print(" ")
    user_input = input("What do you wish? ")
    return user,user_input

def sleep_time(user_input):
    now = datetime.now()
    if user_input == "1":
        time.sleep(25)
        print("Your Pomodoro session is over, it is time for a break.")
    if user_input == "2":
        time.sleep(15)
        print("Your Long Break is over, it is time for another Pomodoro session.")
    if user_input == "3":
        time.sleep(5)
        print("Your Short Break is over, it is time for another Pomodoro session.")

def read_data():
    # create a json file to keep the data
    # check if the file exists if no - return None
    # if yes - read the file, write new data in it and return the changed file

    directory = os.path.dirname(__file__)
    filename = os.path.join(directory, 'log.json')

    if not os.path.exists(filename):
        return {}
    else:
        with open (filename) as fobj:
           data = json.load(fobj)
           return data

def save_data(data, user_input):
    # check if today's date exists in data, if not create dictionary with default value,0
    # increase based on user input and save the data

    today = datetime.now().strftime("%Y-%B-%d")
    if not data.get(today):
        current_data = {'pomodoro':0,'long_break':0,'short_break':0}
    else:
        current_data = data.get(today)

    # Now we have the todays information we have to increase the changes in there
    # breakpoint()

    if user_input == '1':
        current_data['pomodoro'] +=1
    if user_input == '2':
        current_data['long_break'] +=1
    if user_input == '3':
        current_data['short_break'] +=1
    data[today] = current_data

    directory = os.path.dirname(__file__)
    filename = os.path.join(directory, 'log.json')

    with open(filename,"w") as fobj:
        json.dump(data,fobj)

if __name__ == "__main__":
    main()


from bs4 import BeautifulSoup
import csv

"""
## Example program for processing an xml and saving information as a csv
Typically if we had an XML file already, we'd just process it and not convert.

However, serialization is a key part of Data Engineering & the ETL process,
so we will use this to help expand our ability to process one of the many
file formats available (XML/HTML) and our ability to create another (CSV).
"""

"""
### Tools/Acknowledgements
Using xml data from JAXB files. For Java Implementation see:
  http://www.vogella.com/articles/JAXB/article.html
More information on BeautifulSoup (an HTML/XML scrapper):
  https://www.crummy.com/software/BeautifulSoup/bs4/doc/#parsing-xml

Note - use of bookstore2.xml which has three book stores
"""

"""
### Steps (Algorithm):
----------------------
1. Load xml file into memory and pass to BeautifulSoup
2. Open a csv file for writing
3. Then write the header row
4. Then walk through the top_level items and pass as list to the
   csv writer
"""

xml_report = open('bookstores2.xml', 'r').read()
soup = BeautifulSoup(xml_report, "lxml")

#Open a csv for writing (not appending)
with open('bookstore_report.csv', 'w', newline='') as outfile:
  report = csv.writer(outfile, delimiter=",", quoting=csv.QUOTE_ALL)

  #write the header row
  report.writerow(['isbn', 'title', 'author', 'publisher',
                   'store', 'location'])
  #parse bookstore, create list of books, write to csv
  for bookstore in soup.findAll("bookstore"):
    books = bookstore.booklist
    for book in books:
      if book.name == "book": #i.e. don't write if no books
        report.writerow([
          book.get("isbn"),
          book.title.get_text(),
          book.author.get_text(),
          bookstore.publisher.get_text(),
          bookstore.store.get_text(),
          bookstore.location.get_text()])


import sqlite3, json
from flask_restful import Resource, reqparse
from flask_jwt import jwt_required

class Item(Resource):
	item_parser = reqparse.RequestParser()
	# item_parser.add_argument(
	# 	'name',
	# 	type = str,
	# 	required = True,
	# 	help = "Null value, this is a required field.")
	item_parser.add_argument(
		'price',
		type = float,
		required = True,
		help = "Null value, this is a required field." )

	def find_item(self, name):
		"""
			This method is used to find an item by name in the database
			returns the item or none
		"""
		connection = sqlite3.connect('data.db')
		cursor = connection.cursor()
		sql_item = "SELECT * FROM items WHERE name = ?"

		row = cursor.execute(sql_item, (name,)).fetchone()
		# above is cleaner than:
		# rows = cursor.execute(sql_item, (name,))
		# row = rows.fetchone()
		#print(type(row)) <class 'tuple'>
		connection.close()
		if row:
			# this converts the tuple to a list
			# return json.dumps(row)
			# vs
			return {'id':row[0],'name':row[1],'price':row[2]}
		return None

		# return next(filter(lambda item: item['name'] == name, items), None)

	def insert_item(self, name, price):
		connection = sqlite3.connect('data.db')
		cursor = connection.cursor()
		sql_insert_item = "INSERT INTO items (name,price) VALUES (?, ?)"

		cursor.execute(sql_insert_item, (name, price,))
		connection.commit()
		connection.close()

	@jwt_required()
	def get(self, name):
		# when using an in memory database
		# lets see if we can swap out the storage without changing this method
		item = self.find_item(name)
		return {'item': item}, 200 if item else 404

	@jwt_required()
	def post(self, name):

		data = self.item_parser.parse_args()
		# data = request.get_json()
			# ways to deal with request payloads (content-type = application/json)
			# force=True  # deal with the junk data
			# silent=True # return null but not an error

		item_check = self.find_item(name)
		if item_check:
			return {'message':'Found existing item {}.'.format(item_check['name'])}, 400

		try:
			self.insert_item(name, data['price'])
		except:
			return {'message':'Error, failed to add item {}'.format(name)}, 500

		return {'message':'Item {} added.'.format(name)}, 201

	@jwt_required()
	def delete(self, name):
		# item_check = self.find_item(name)
		# if item_check is None:
		# 	return {'message':'Item {} does not exist.'.format(name)}, 400

		# global items
		# items = list(filter(lambda item: item['name'] != name, items))
		# return {'message':'Item {} has been deleted.'.format(name)}, 200

		connection = sqlite3.connect('data.db')
		cursor = connection.cursor()

		sql_delete_item = "DELETE FROM items WHERE name = ?"

		cursor.execute(sql_delete_item, (name,))
		connection.commit()
		connection.close()
		return {'message':'Item {} has been deleted.'.format(name)}, 200

	@jwt_required()
	def put(self, name):
		data = self.item_parser.parse_args()

		item = self.find_item(name)
		if item:
			try:
				self.update_item(item)
			except:
				return {'message':'Error, failed to update item {}'.format(item['name'])}, 500
			return {'message':'Item {} updated to price {}.'.format(item['name'],item['price'])}, 201
		else:
			try:
				self.insert_item(name, data['price'])
			except:
				return {'message':'Error, failed to add item {}'.format(name)}, 500
			return {'message':'Item {} added.'.format(name)}, 201

	def update_item(self, item):
		sql_update_item = "UPDATE items SET price = ? WHERE name = ?"
		connection = sqlite3.connect('data.db')
		cursor = connection.cursor()
		cursor.execute(sql_update_item, (item['price'],item['name'],))
		connection.commit()
		connection.close()

class Items(Resource):
	@jwt_required()
	def get(self):
		sql_items = "SELECT name, price FROM items"
		connection = sqlite3.connect('data.db')
		cursor = connection.cursor()
		rows = cursor.execute(sql_items)

		# items_list = [ {row['name']: row['price']} for row in rows ]
		items_list = [ {'name':row[0],'price':row[1]} for row in rows ]
		connection.close()
		return {'items': items_list}, 202


import random
from abc import ABC, abstractmethod
from collections import namedtuple
from typing import Optional

import pandas as pd
import sqlalchemy as sa

from .db_util import TempTable

CMU = namedtuple(
    "CMU",
    ["category", "measurement", "unit", "age", "race", "sex"],
    defaults=["cases", "cumulative", "people", "all", "all", "all"]
)

class DatasetBase(ABC):
    autodag: bool = True
    data_type: str = "general"
    table_name: str

    def __init__(self):
        pass

    def extract_cat_measurement_unit(self, df, cmu):
        """
        Adds columns "category", "measurement", and "unit" to df

        Parameters
        ----------
        df : pd.DataFrame
            This DataFrame must have the column `variable` and the
            unique elements of `variable` must be keys in the
            `cmu_dict`
        cmu : dict(str -> CMU)
            This dictionary maps variable names into a subcategory,
            measurement, and unit using a CMU namedtuple

        Returns
        -------
        df : pd.DataFrame
            A copy of the DataFrame passed in that has new columns
            "category", "measurement", and "unit"
        """
        return df.assign(
            category=df["variable"].map(lambda x: cmu[x].category),
            measurement=df["variable"].map(lambda x: cmu[x].measurement),
            unit=df["variable"].map(lambda x: cmu[x].unit),
            age=df["variable"].map(lambda x: cmu[x].age),
            race=df["variable"].map(lambda x: cmu[x].race),
            sex=df["variable"].map(lambda x: cmu[x].sex),
        )

    @abstractmethod
    def put(self, conn, df):
        pass

    def _retrieve_dt(self, tz="US/Eastern"):
        out = pd.Timestamp.utcnow().tz_convert(tz).normalize().tz_localize(None)

        return out

    def _retrieve_vintage(self):
        return pd.Timestamp.utcnow().floor("h")

        pass

class DatasetBaseNoDate(DatasetBase, ABC):
    get_needs_date = False

    @abstractmethod
    def get(self):
        raise NotImplementedError("Must be implemented by subclass")

class DatasetBaseNeedsDate(DatasetBase, ABC):
    get_needs_date = True

    @abstractmethod
    def get(self, date: str):
        raise NotImplementedError("Must be implemented by subclass")

    def transform_date(self, date: pd.Timestamp) -> pd.Timestamp:
        return date

    def quit_early(self, date: pd.Timestamp) -> bool:
        return False

def _build_on_conflict_do_nothing_query(
        df: pd.DataFrame, t_home: str, t_temp: str, pk: str
    ):
    colnames = ", ".join(list(df))
    cols = "(" + colnames + ")"
    if not pk.startswith("("):
        pk = f"({pk})"

    return f"""
    INSERT INTO data.{t_home} {cols}
    SELECT {colnames} from {t_temp}
    ON CONFLICT {pk} DO NOTHING;
    """

class InsertWithTempTable(DatasetBase, ABC):
    pk: str

    def _insert_query(
            self, df: pd.DataFrame, table_name: str, temp_name: str, pk: str
        ):

        out = _build_on_conflict_do_nothing_query(df, table_name, temp_name, pk)
        return out

    def _put(self, connstr: str, df: pd.DataFrame, table_name: str, pk: str):
        temp_name = "__" + table_name + str(random.randint(1000, 9999))

        with sa.create_engine(connstr).connect() as conn:
            kw = dict(temp=False, if_exists="replace", destroy=True)

            with TempTable(df, temp_name, conn, **kw):
                sql = self._insert_query(df, table_name, temp_name, pk)
                conn.execute(sql)

    def put(self, connstr: str, df=None):
        if df is None:
            if hasattr(self, "df"):
                df = self.df
            else:
                raise ValueError("No df found, please pass")

        if not hasattr(self, "pk"):
            msg = "field `pk` must be set on subclass of OnConflictNothingBase"
            raise ValueError(msg)

        self._put(connstr, df, self.table_name, self.pk)


import requests
from tkinter import *
from tkinter import messagebox

window = Tk()
window.geometry("500x500")
window.title("Weather App")
window.config(bg="black")

city = StringVar

def display_result():

    # initialize weather request from API
    try:
        get_city = city_entry.get()
        r = requests.get(
            "https://api.openweathermap.org/data/2.5/weather?q=" + get_city + "&appid=36e6aefc64df32f4ca03bd2cbd44d4d7")
        data = r.json()
        # display labels
        display_temp = Label(window, text=int(data['main']['temp'] - 273.15), font='Helvetica',
                                                                                fg="black",
                                 bg="white")
        display_temp.place(x=200, y=110)
        display_wind_speed = Label(window, text=str(data['wind']['speed']) + "KM/h",
        font='Helvetica',
                                   fg="black",
                                   bg="white")
        display_wind_speed.place(x=200, y=200)
        display_humidity = Label(window, text=str(data['main']['humidity']), font='Helvetica',
                                 fg="black",
                                 bg="white")
        display_humidity.place(x=200, y=150)
        display_cloud_cover = Label(window, text=str(data['weather'][0]['main'] + " skies"),
        font='Helvetica',
                                    fg="black",
                                    bg="white")
        display_cloud_cover.place(x=200, y=250)

    except KeyError:
         messagebox.showinfo("ERROR","PLEASE ENTER YOUR CITY")

def exiting():
    window.destroy()

# Widgets

city_entry=Entry(window, textvariable="city", bg="white")
city_entry.place(x=200, y=73, width=150)

label_Title = Label(window, text="WEATHER APPLICATION", bg="black", fg="white")
label_Title.place(x=200, y=10)
label_Choose = Label(window, text="Choose Location", bg="black", fg="white")
label_Choose.place(x=220, y=50)

label_Temperature = Label(window, text="Temperature", bg="black", fg="white")
label_Temperature.place(x=100, y=110)
label_Humidity = Label(window, text="Humidity", bg="black", fg="white")
label_Humidity.place(x=100, y=150)
label_Wind_speed = Label(window, text="Wind Speed", bg="black", fg="white")
label_Wind_speed.place(x=100, y=200)
label_Cloud_Cover = Label(window, text="Cloud Cover", bg="black", fg="white")
label_Cloud_Cover.place(x=100, y=250)
# Buttons
button_Display = Button(window, text="Display", bg="white", command=display_result)
button_Display.place(x=100, y=300)
# button_clear = Button(window, text="Clear", bg="white", )
# button_clear.place(x=200, y=300)
button_exit = Button(window, text="Exit", bg="white", command=exiting)
button_exit.place(x=300, y=300)
window.mainloop()