from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
import numpy as np
import matplotlib as mpl
from IPython.display import clear_output
from matplotlib import pyplot as plt
from tensorflow.keras.preprocessing import image

url = 'https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1576136828&di=92dee6fdb1f43f75b633aa503418397c&src=http://img.pconline.com.cn/images/upload/upc/tx/wallpaper/1209/26/c0/14139494_1348624365103.jpg'

# Download an image and read it into a NumPy array.
def download(url, target_size=None):
  name = url.split('/')[-1]
  image_path = tf.keras.utils.get_file(name, origin=url)
  img = tf.keras.preprocessing.image.load_img(image_path, target_size=target_size)
  return img

# Normalize an image
def deprocess(img):
  img = 255*(img + 1.0)/2.0
  return tf.cast(img, tf.uint8)

# Display an image
def show(img):
  plt.figure(figsize=(12,12))
  plt.grid(False)
  plt.axis('off')
  plt.imshow(img)
  plt.show()

# Downsizing the image makes it easier to work with.
original_img = download(url, target_size=[225, 375])
original_img = np.array(original_img)

show(original_img)

print("下载数据完成-----")
#准备特征提取模型
base_model = tf.keras.applications.InceptionV3(include_top=False, weights='imagenet')
# InceptionV3架构非常大（有关模型架构的图表，请参见TensorFlow的研究报告）。对于DeepDream，感兴趣的层是将卷积串联在一起的层。InceptionV3中有11层，名为“ mixed0”至“ mixed10”。使用不同的图层将产生不同的梦幻图像。较深的层对较高级的特征（例如，眼睛和面部）做出响应，而较早的层对较简单的特征（例如，边缘，形状和纹理）做出响应。请随意尝试以下选择的图层，但请记住，由于渐变计算的深度较大，较深的图层（具有较高索引的图层）将需要较长的训练时间。
# Maximize the activations of these layers
names = ['mixed3', 'mixed5']
layers = [base_model.get_layer(name).output for name in names]

# Create the feature extraction model
dream_model = tf.keras.Model(inputs=base_model.input, outputs=layers)
# 计算损失
# 损失是所选层中激活的总和。损耗在每一层均经过归一化处理，因此较大层的贡献不会超过较小层。通常，损耗是您希望通过梯度下降最小化的数量。在DeepDream中，您将通过梯度上升来最大化此损失。
def calc_loss(img, model):
  # Pass forward the image through the model to retrieve the activations.
  # Converts the image into a batch of size 1.
  img_batch = tf.expand_dims(img, axis=0)
  layer_activations = model(img_batch)

  losses = []
  for act in layer_activations:
    loss = tf.math.reduce_mean(act)
    losses.append(loss)

  return  tf.reduce_sum(losses)

# 渐变上升
# 一旦计算出所选图层的损耗，剩下的就是计算相对于图像的渐变，并将其添加到原始图像中。
#
# 将渐变添加到图像可以增强网络看到的图案。在每个步骤中，您将创建一个图像，该图像将越来越激发网络中某些层的激活。

@tf.function
def deepdream(model, img, step_size):
    with tf.GradientTape() as tape:
        # This needs gradients relative to `img`
        # `GradientTape` only watches `tf.Variable`s by default
        tape.watch(img)
        loss = calc_loss(img, model)

    # Calculate the gradient of the loss with respect to the pixels of the input image.
    gradients = tape.gradient(loss, img)

    # Normalize the gradients.
    gradients /= tf.math.reduce_std(gradients) + 1e-8

    # In gradient ascent, the "loss" is maximized so that the input image increasingly "excites" the layers.
    # You can update the image by directly adding the gradients (because they're the same shape!)
    img = img + gradients * step_size
    img = tf.clip_by_value(img, -1, 1)

    return loss, img

def run_deep_dream_simple(model, img, steps=100, step_size=0.01):
    # Convert from uint8 to the range expected by the model.
    img = tf.keras.applications.inception_v3.preprocess_input(img)

    for step in range(steps):
        loss, img = deepdream(model, img, step_size)
        print()

        # if step% 10==0:
        #     clear_output(wait=True)
        #     show(deprocess(img))
        #     print("没调整10色，显示图片，Step {}, loss {}".format(step, loss))

        if step % 100 == 0:
            clear_output(wait=True)
            show(deprocess(img))
            print("退出了，Step {}, loss {}".format(step, loss))

    result = deprocess(img)
    clear_output(wait=True)
    show(result)

    return result

print("最后数据是++++++++++++++++++++++++++++++++++")
dream_img = run_deep_dream_simple(model=dream_model, img=original_img,
                                  steps=100, step_size=0.01)

print("数据炫彩完了。。。。。。。")
# 调整照片质量
# 调高八度
# 很好，但是第一次尝试有一些问题：
#
# 输出有噪声（可能会tf.image.total_variation造成损失）。
# 图像分辨率低。
# 这些模式看起来好像都发生在相同的粒度上。
# 解决所有这些问题的一种方法是在不同规模上应用梯度上升。这将允许将较小比例尺生成的图案合并到较高比例尺的图案中，并附加其他细节。
#
# 为此，您可以执行以前的渐变上升方法，然后增加图像的大小（以八度表示），并对多个八度重复此过程。

OCTAVE_SCALE = 1.3

img = tf.constant(np.array(original_img))
base_shape = tf.cast(tf.shape(img)[:-1], tf.float32)

for n in range(3):
  new_shape = tf.cast(base_shape*(OCTAVE_SCALE**n), tf.int32)

  img = tf.image.resize(img, new_shape).numpy()

  img = run_deep_dream_simple(model=dream_model, img=img, steps=200, step_size=0.001)

clear_output(wait=True)
show(img)

# 照片移位置
# 放大瓷砖
# 要考虑的一件事是，随着图像尺寸的增加，执行梯度计算所需的时间和内存也将随之增加。上面的倍频程实现不适用于非常大的图像或许多倍频程。
#
# 为避免此问题，您可以将图像拆分为图块并计算每个图块的梯度。
#
# 在每次平铺计算之前对图像应用随机移位可防止出现平铺接缝。
#
# 首先实现随机移位：
def random_roll(img, maxroll):
  # Randomly shift the image to avoid tiled boundaries.
  shift = tf.random.uniform(shape=[2], minval=-maxroll, maxval=maxroll, dtype=tf.int32)
  shift_down, shift_right = shift[0],shift[1]
  img_rolled = tf.roll(tf.roll(img, shift_right, axis=1), shift_down, axis=0)
  return shift_down, shift_right, img_rolled

shift_down, shift_right, img_rolled = random_roll(np.array(original_img), 512)
show(img_rolled)

# 平铺
# 这是deepdream先前定义的函数的平铺等效项：

@tf.function
def get_tiled_gradients(model, img, tile_size=512):
  shift_down, shift_right, img_rolled = random_roll(img, tile_size)

  # Initialize the image gradients to zero.
  gradients = tf.zeros_like(img_rolled)

  for x in tf.range(0, img_rolled.shape[0], tile_size):
    for y in tf.range(0, img_rolled.shape[1], tile_size):
      # Calculate the gradients for this tile.
      with tf.GradientTape() as tape:
        # This needs gradients relative to `img_rolled`.
        # `GradientTape` only watches `tf.Variable`s by default.
        tape.watch(img_rolled)

        # Extract a tile out of the image.
        img_tile = img_rolled[x:x+tile_size, y:y+tile_size]
        loss = calc_loss(img_tile, model)

      # Update the image gradients for this tile.
      gradients = gradients + tape.gradient(loss, img_rolled)

  # Undo the random shift applied to the image and its gradients.
  gradients = tf.roll(tf.roll(gradients, -shift_right, axis=1), -shift_down, axis=0)

  # Normalize the gradients.
  gradients /= tf.math.reduce_std(gradients) + 1e-8

  return gradients

# 将它们放在一起可提供可扩展的，倍频感知的Deepdream实现：
def run_deep_dream_with_octaves(model, img, steps_per_octave=100, step_size=0.01,
                                num_octaves=3, octave_scale=1.3):
    img = tf.keras.preprocessing.image.img_to_array(img)
    img = tf.keras.applications.inception_v3.preprocess_input(img)

    for octave in range(num_octaves):
        # Scale the image based on the octave
        if octave > 0:
            new_size = tf.cast(tf.convert_to_tensor(img.shape[:2]), tf.float32) * octave_scale
            img = tf.image.resize(img, tf.cast(new_size, tf.int32))

        for step in range(steps_per_octave):
            gradients = get_tiled_gradients(model, img)
            img = img + gradients * step_size
            img = tf.clip_by_value(img, -1, 1)

            if step % 10 == 0:
                clear_output(wait=True)
                show(deprocess(img))
                print("Octave {}, Step {}".format(octave, step))

    clear_output(wait=True)
    result = deprocess(img)
    show(result)

    return result

dream_img = run_deep_dream_with_octaves(model=dream_model, img=original_img, step_size=0.01)

clear_output()
show(original_img)
show(dream_img)
print("所有数据全部跑完了")


import django_filters
from api.models import LauncherConfig
from django.db.models import Q

class LauncherConfigListFilter(django_filters.FilterSet):
    search = django_filters.CharFilter(field_name="search", label="Search", method="filter_by_all_name_fields")

    class Meta:
        model = LauncherConfig
        fields = ["manufacturer", "family", "active", "reusable"]
        order_by = ["pk"]

    def filter_by_all_name_fields(self, queryset, name, value):
        return queryset.filter(
            Q(name__icontains=value)
            | Q(description__icontains=value)
            | Q(full_name__icontains=value)
            | Q(variant__icontains=value)
            | Q(alias__icontains=value)
            | Q(manufacturer__name__icontains=value)
            | Q(manufacturer__abbrev__icontains=value)
        )


if __name__ == '__main__':
    f = open('./input', 'r')
    lines = f.readlines()
    f.close()

    dirs = [] # List of all dirs as strings
    dir_sizes = [] # This is the total size of all files and dirs
    dir_direct_sizes = [] # This is the size of all files directly in the dir

    cur_dir = '/' # Start at root
    for line in lines:
        split_line = line.split(' ')
        if split_line[0] == '$': # This is a command
            if 'cd' in split_line[1]:
                new_dir = split_line[2][:-1] # Removes newline
                if new_dir == '/':
                    cur_dir = '/'
                elif '..' in new_dir:
                    cur_dir = cur_dir[0:cur_dir.rindex('/')] # Finds the last '/'
                else:
                    if cur_dir != '/':
                        cur_dir = cur_dir + '/' + new_dir
                    else:
                        cur_dir = cur_dir + new_dir

                if cur_dir == '': # This is a special case so that cur_dir does not get empty
                    cur_dir = '/'

                # Append zeroes to the sizes to that the indexes exist for later
                if not cur_dir in dirs:
                    dirs.append(cur_dir)
                    dir_direct_sizes.append(0)
                    dir_sizes.append(0)

        elif split_line[0] == 'dir': # We ignore dir lines
            pass
        else: # Add all the files in cur_dir to the list
            dir_direct_sizes[dirs.index(cur_dir)] += int(split_line[0])

    # Sum all subdirectories
    for i in range(len(dirs)):
        for j in range(len(dirs)):
            if dirs[i] in dirs[j]: # This is a real subdirectory
                dir_sizes[i] += dir_direct_sizes[j]

    sum_p1 = 0
    for size in dir_sizes:
        if size <= 100000:
            sum_p1 += size

    total_space = 70000000  # 70 000 000
    needed_space = 30000000 # 30 000 000
    used_space = dir_sizes[dirs.index('/')] # "/" Includes all other dirs
    unused_space = total_space - used_space
    space_to_delete = needed_space - unused_space

    smallest_size = total_space # Every dir is smaller than this
    for dir_size in dir_sizes:
        if smallest_size > dir_size and dir_size > space_to_delete:
            smallest_size = dir_size

    # Print results
    print('Sum of dirs smaller than 100k: ' + str(sum_p1))
    print('Smallest dir to delete: ' + str(smallest_size))


"""
(C) 2014-2016 Roman Sirokov and contributors
Licensed under BSD license

http://github.com/r0x0r/pywebview/
"""

import sys
import os
import logging
import threading

from webview.localization import localization
from webview import OPEN_DIALOG, FOLDER_DIALOG, SAVE_DIALOG

logger = logging.getLogger(__name__)

# Try importing Qt4 modules
try:
    from PyQt4 import QtCore
    from PyQt4.QtWebKit import QWebView
    from PyQt4.QtGui import QWidget, QMainWindow, QVBoxLayout, QApplication, QDialog, QFileDialog

    logger.debug("Using Qt4")
except ImportError as e:
    logger.warn("PyQt4 is not found")
    _import_error = True
else:
    _import_error = False

# Try importing Qt5 modules
if _import_error:
    try:
        from PyQt5 import QtCore

        # Check to see if we're running Qt > 5.5
        from PyQt5.QtCore import QT_VERSION_STR
        if float(QT_VERSION_STR[:3]) > 5.5:
            from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView
        else:
            from PyQt5.QtWebKitWidgets import QWebView

        from PyQt5.QtWidgets import QWidget, QMainWindow, QVBoxLayout, QApplication, QFileDialog

        logger.debug("Using Qt5")
    except ImportError as e:
        logger.warn("PyQt5 is not found")
        _import_error = True
    else:
        _import_error = False

if _import_error:
    raise Exception("This module requires PyQt4 or PyQt5 to work under Linux.")

class BrowserView(QMainWindow):
    instance = None
    url_trigger = QtCore.pyqtSignal(str)
    html_trigger = QtCore.pyqtSignal(str, str)
    dialog_trigger = QtCore.pyqtSignal(int, str, bool, str)
    destroy_trigger = QtCore.pyqtSignal()

    def __init__(self, title, url, width, height, resizable, fullscreen, min_size, webview_ready):
        super(BrowserView, self).__init__()
        BrowserView.instance = self

        self._file_name_semaphor = threading.Semaphore(0)

        self.resize(width, height)
        self.setWindowTitle(title)

        if not resizable:
            self.setFixedSize(width, height)

        if fullscreen:
            self.showFullScreen()

        self.setMinimumSize(min_size[0], min_size[1])

        self.view = QWebView(self)
        self.view.setContextMenuPolicy(QtCore.Qt.NoContextMenu)  # disable right click context menu
        if url != None:
            self.view.setUrl(QtCore.QUrl(url))

        self.setCentralWidget(self.view)
        self.url_trigger.connect(self._handle_load_url)
        self.html_trigger.connect(self._handle_load_html)
        self.dialog_trigger.connect(self._handle_file_dialog)
        self.destroy_trigger.connect(self._handle_destroy_window)

        self.move(QApplication.desktop().availableGeometry().center() - self.rect().center())
        self.activateWindow()
        self.raise_()
        webview_ready.set()

    def _handle_file_dialog(self, dialog_type, directory, allow_multiple, save_filename):
        if dialog_type == FOLDER_DIALOG:
            self._file_name = QFileDialog.getExistingDirectory(self, localization["linux.openFolder"], options=QFileDialog.ShowDirsOnly)
        elif dialog_type == OPEN_DIALOG:
            if allow_multiple:
                self._file_name = QFileDialog.getOpenFileNames(self, localization["linux.openFiles"], directory)
            else:
                self._file_name = QFileDialog.getOpenFileName(self, localization["linux.openFile"], directory)
        elif dialog_type == SAVE_DIALOG:
            if directory:
                save_filename = os.path.join(str(directory), str(save_filename))

            self._file_name = QFileDialog.getSaveFileName(self, localization["linux.saveFile"], save_filename)

        self._file_name_semaphor.release()

    def _handle_load_url(self, url):
        self.view.setUrl(QtCore.QUrl(url))

    def _handle_load_html(self, content, base_uri):
        self.view.setHtml(content, QtCore.QUrl(base_uri))

    def _handle_destroy_window(self):
        self.close()

    def load_url(self, url):
        self.url_trigger.emit(url)

    def load_html(self, content, base_uri):
        self.html_trigger.emit(content, base_uri)

    def create_file_dialog(self, dialog_type, directory, allow_multiple, save_filename):
        self.dialog_trigger.emit(dialog_type, directory, allow_multiple, save_filename)
        self._file_name_semaphor.acquire()

        if dialog_type == FOLDER_DIALOG or not allow_multiple:
            return str(self._file_name)
        elif allow_multiple:
            file_names = map(str, self._file_name)

            if len(file_names) == 1:
                return file_names[0]
            else:
                return file_names
        else:
            return None

    def destroy_(self):
        self.destroy_trigger.emit()

def create_window(title, url, width, height, resizable, fullscreen, min_size, webview_ready):
    app = QApplication([])

    browser = BrowserView(title, url, width, height, resizable, fullscreen, min_size, webview_ready)
    browser.show()
    app.exec_()

def load_url(url):
    BrowserView.instance.load_url(url)

def load_html(content, base_uri):
    BrowserView.instance.load_html(content, base_uri)

def destroy_window():
    BrowserView.instance.destroy_()

def create_file_dialog(dialog_type, directory, allow_multiple, save_filename):
    return BrowserView.instance.create_file_dialog(dialog_type, directory, allow_multiple, save_filename)


from flask import Flask, request, render_template, jsonify
from spider import Spider

app = Flask(__name__)

def web_start(host, port):
    app.run(host=host, port=port)

# @app.route('/new', methods=['GET'])
# def new():
#     dynamic_ = get_content()
#     delete_create()
#     if dynamic_:
#         return jsonify(dynamic_)
#     else:
#         return jsonify(' ')

@app.route('/', methods=['GET'])
def hello():
    return render_template('index.html')

@app.route('/search/<keyword>')
def search(keyword):
    if request.referrer:
        Spider(keyword).search()
        return render_template('search.html', keyword=keyword)
    else:
        return render_template('404.html')


'''
Created on 08-Mar-2019

@author: Admin
'''
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import xlrd
import IPython
import skimage

demo_df=pd.read_excel("f:/CodeRepo/titanic3.xls","titanic3",index_col=None,na_values=['na'])
print(demo_df.head())
print(demo_df.describe())
print(demo_df.drop(['ticket','cabin','body','boat'],axis=1).head())
print(demo_df.isnull().sum())
print(pd.value_counts(demo_df["survived"]).plot.bar())
print(demo_df.groupby(["sex"]).mean())
print(demo_df.groupby(["sex","pclass"]).mean())
print(demo_df.groupby(["sex","pclass"]).mean())

def header(msg):
    print('-' * 50)
    print('[ ' + msg + ' ]')

# 1. load hard-coded data into a dataframe
header("1. load hard-coded data into a df")
df = pd.DataFrame(
    [['Jan',518,42,74,22,2.95],
    ['Feb',61,45,78,26,3.02],
    ['Mar',65,48,84,25,2.34],
    ['Apr',67,50,92,28,1.02],
    ['May',71,53,98,35,0.48],
    ['Jun',75,56,107,41,0.11],
    ['Jul',77,58,105,44,0.0],
    ['Aug',77,59,102,43,0.03],
    ['Sep',77,57,103,40,0.17],
    ['Oct',73,54,96,34,0.81],
    ['Nov',64,48,84,30,1.7],
    ['Dec',58,42,73,21,2.56]],
    index = [0,1,2,3,4,5,6,7,8,9,10,11],
    columns = ['month','avg_high','avg_low','record_high','record_low','avg_precipitation'])
print(df)

# 2. read text file into a dataframe
header("2. read text file into a df")
filename = 'sample.txt'
df = pd.read_csv(filename)
print(df)

# 3. print first 5 or last 3 rows of df
header("3. df.head()")
print(df.head())
header("3. df.tail(3)")
print(df.tail(3))

# 4. get data types, index, columns, values
header("4. df.dtypes")
print(df.dtypes)

header("4. df.index")
print(df.index)

header("4. df.columns")
print(df.columns)

header("4. df.values")
print(df.values)

# 5. statistical summary of each column
header("5. df.describe()")
print(df.describe())

# 6. sort records by any column
header("6. df.sort_values('record_high', ascending=False)")
print (df.sort_values('record_high', ascending=False))

ls=df.sort_values('record_high', ascending=False)

df1=pd.DataFrame(ls)
# 12. write to csv file
df1.to_csv('test.csv')

# 7. slicing records
header("7. slicing -- df.avg_low")
print(df.avg_low)                            # index with single column

header("7. slicing -- df['avg_low']")
print(df['avg_low'])

header("7. slicing -- df[2:4]")                # index with single column
print(df[2:4])                                # rows 2 to 3

header("7. slicing -- df[['avg_low','avg_high']]")
print(df[['avg_low','avg_high']])

header("7. slicing -- df.loc[:,['avg_low','avg_high']]")
print(df.loc[:,['avg_low','avg_high']])        # multiple columns: df.loc[from_row:to_row,['column1','column2']]

header("7. slicing scalar value -- df.loc[9,['avg_precipitation']]")
print(df.loc[9,['avg_precipitation']])

header("7. df.iloc[3:5,[0,3]]")                # index location can receive range or list of indices
print(df.iloc[3:5,[0,3]])

# 8. filtering
header("8. df[df.avg_precipitation > 1.0]")    # filter on column values
print(df[df.avg_precipitation > 1.0])

header("8. df[df['month'].isin['Jun','Jul','Aug']]")
print(df[df['month'].isin(['Jun','Jul','Aug'])])

# 9. assignment -- very similar to slicing
header("9. df.loc[9,['avg_precipitation']] = 101.3")
df.loc[9,['avg_precipitation']] = 101.3
print(df.iloc[9:11])

header("9. df.loc[9,['avg_precipitation']] = np.nan")
df.loc[9,['avg_precipitation']] = np.nan
print(df.iloc[9:11])

header("9. df.loc[:,'avg_low'] = np.array([5] * len(df))")
df.loc[:,'avg_low'] = np.array([5] * len(df))
print(df.head())

header("9. df['avg_day'] = (df.avg_low + df.avg_high) / 2")
df['avg_day'] = (df.avg_low + df.avg_high) / 2
print(df.head())

# 10. renaming columns
header("10. df.rename(columns = {'avg_precipitation':'avg_rain'}, inplace=True)")
df.rename(columns = {'avg_precipitation':'avg_rain'}, inplace=True)        # rename 1 column
print(df.head())

header("10. df.columns = ['month','av_hi','av_lo','rec_hi','rec_lo','av_rain','av_day']")
df.columns = ['month','av_hi','av_lo','rec_hi','rec_lo','av_rain','av_day']
print(df.head())


"""Utility data and functions for WFC"""

import collections
import numpy as np

CoordXY = collections.namedtuple("coords_xy", ["x", "y"])
CoordRC = collections.namedtuple("coords_rc", ["row", "column"])

def hash_downto(a, rank, seed=0):
    state = np.random.RandomState(seed)
    assert rank < len(a.shape)
    # print((np.prod(a.shape[:rank]),-1))
    # print(np.array([np.prod(a.shape[:rank]),-1], dtype=np.int64).dtype)
    u = a.reshape(
        np.array([np.prod(a.shape[:rank]), -1], dtype=np.int64)
    )  # change because lists are by default float64?
    # u = a.reshape((np.prod(a.shape[:rank]),-1))
    v = state.randint(1 - (1 << 63), 1 << 63, np.prod(a.shape[rank:]), dtype="int64")
    return np.inner(u, v).reshape(a.shape[:rank]).astype("int64")

try:
    import google.colab

    IN_COLAB = True
except:
    IN_COLAB = False

def load_visualizer(wfc_ns):
    if IN_COLAB:
        from google.colab import files

        uploaded = files.upload()
        for fn in uploaded.keys():
            print(
                'User uploaded file "{name}" with length {length} bytes'.format(
                    name=fn, length=len(uploaded[fn])
                )
            )
    else:
        import matplotlib
        import matplotlib.pylab
        from matplotlib.pyplot import figure
        from matplotlib.pyplot import subplot
        from matplotlib.pyplot import title
        from matplotlib.pyplot import matshow

    wfc_ns.img_filename = f"images/{wfc_ns.img_filename}"
    return wfc_ns

def find_pattern_center(wfc_ns):
    # wfc_ns.pattern_center = (math.floor((wfc_ns.pattern_width - 1) / 2), math.floor((wfc_ns.pattern_width - 1) / 2))
    wfc_ns.pattern_center = (0, 0)
    return wfc_ns


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

# file:ResNets.py
# author:xm
# datetime:2023/2/13 19:28
# software: PyCharm

"""
如果 网络很深 可能会出现梯度消失(每一层的梯度都很小 经过链式法则相乘 就会导致趋于0) 那么前面的层权重就得不到更新
我们可以通过逐层训练来解决 但是这在深度学习中不适用
可以使用跳连接，H(x) = F(x) + x,张量维度必须一样，加完后再激活。不要做pooling，张量的维度会发生变化。
H'(x) = F'(x) + 1 这样当F'(x) -> 0时， H'(x) -> 1 而不是趋于0 不会导致梯度消失

这里我们介绍 残差网络(ResNets) 以及其组成部分: 残差块(ResidualBlock)

homework1:
read paper: He K, Zhang X, Ren S, et al. Identity Mappings in Deep Residual Networks
https://arxiv.org/abs/1603.05027

homework2:
read paper: Huang G, Liu Z, Laurens V D M, et al. Densely Connected Convolutional Networks
https://openaccess.thecvf.com/content_cvpr_2017/papers/Huang_Densely_Connected_Convolutional_CVPR_2017_paper.pdf

接下来的路怎么走:
1. 理论 《深度学习》 花书 从数学和工程学的角度重新理解深度学习的理念
2. 阅读 PyTorch文档(通读一遍)
3. 变现经典工作(找经典深度学习论文 进行复现)
    3.1 读代码
    3.2 尝试自己写 复现
    3.3 过程1、2不断循环 这样才是一个学习的过程
4. 扩充视野(先具备前三点能力)
    4.1 选定特定的领域 大量阅读论文 想创新点
    4.2 解决知识上的盲点
    4.3 锻炼代码能力
    4.4 转化成果
"""

# import module your need
import torch
import torch.nn as nn
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim

# prepare dataset

batch_size = 64
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])  # 归一化,均值和方差

train_dataset = datasets.MNIST(root='../data/mnist/', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
test_dataset = datasets.MNIST(root='../data/mnist/', train=False, download=True, transform=transform)
test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)

# design model using class
class ResidualBlock(nn.Module):
    def __init__(self, channels):
        super(ResidualBlock, self).__init__()
        self.channels = channels
        self.conv1 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(channels, channels, kernel_size=3, padding=1)

    def forward(self, x):
        y = F.relu(self.conv1(x))
        y = self.conv2(y)
        return F.relu(x + y)

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=5)
        self.conv2 = nn.Conv2d(16, 32, kernel_size=5)  # 88 = 24x3 + 16

        self.rblock1 = ResidualBlock(16)
        self.rblock2 = ResidualBlock(32)

        self.mp = nn.MaxPool2d(2)
        self.fc = nn.Linear(512, 10)

    def forward(self, x):
        in_size = x.size(0)

        x = self.mp(F.relu(self.conv1(x)))
        x = self.rblock1(x)
        x = self.mp(F.relu(self.conv2(x)))
        x = self.rblock2(x)

        x = x.view(in_size, -1)
        x = self.fc(x)
        return x

model = Net()
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

# construct loss and optimizer
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

# training cycle forward, backward, update

def train(epoch):
    running_loss = 0.0
    for batch_idx, data in enumerate(train_loader, 0):
        inputs, target = data
        inputs, target = inputs.to(device), target.to(device)  # 迁移到GPU上
        optimizer.zero_grad()

        outputs = model(inputs)
        loss = criterion(outputs, target)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if batch_idx % 300 == 299:
            print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
            running_loss = 0.0

def test():
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            images, labels = images.to(device), labels.to(device)  # 迁移到GPU上
            outputs = model(images)
            _, predicted = torch.max(outputs.data, dim=1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print("accuracy on test set:%d %% [%d/%d]" % (100 * correct / total, correct, total))

if __name__ == '__main__':
    for epoch in range(10):
        train(epoch)
        test()


import copy
import matplotlib.pyplot as plt
import numpy as np
import os
import time
import requests
import zipfile
import torch
import torchvision.utils
from torchvision import transforms,datasets
import torchvision.models.quantization as models
from torch import nn,optim
from torch.quantization import convert
from PIL import Image,ImageDraw
import cv2

def train_model(model,criterion,optimizer,scheduler,num_epochs = 25,device='cpu'):
    since = time.time()

    best_model_wts = copy.deepcopy(model.state_dict())
    best_acc =0.0
    for epoch in range(num_epochs):
        print("Epoch {}/{}".format(epoch,num_epochs-1))
        for phase in ['train','val']:
            if phase == 'train':
                model.train()
            else:
                model.eval()
            running_loss = 0.0
            running_corrects = 0
            for inputs,lables in dataloaders[phase]:
                inputs = inputs.to(device)
                lables = lables.to(device)

                optimizer.zero_grad()

                with torch.set_grad_enabled(phase == 'train'):
                    outputs = model(inputs)
                    _,preds = torch.max(outputs,1)
                    loss = criterion(outputs,lables)
                    if phase == 'train':
                        loss.backward()
                        optimizer.step()
                running_loss += loss.item() * inputs.size(0)
                running_corrects += torch.sum(preds == lables.data)

            if phase == 'train':
                scheduler.step()

            epoch_loss = running_loss / dataset_sizes[phase]

            epoch_acc = running_corrects.double() / dataset_sizes[phase]

            print("{} loss {:4f} acc {:4f}".format(phase,epoch_loss,epoch_acc))

            if  phase == 'val' and epoch_acc > best_acc:
                best_acc = epoch_acc
                best_model_wts = copy.deepcopy(model.state_dict())

    time_elapsed = time.time() - since

    print("训练耗时 {:0f}m,{:0f}s".format(time_elapsed // 60, time_elapsed % 60))

    print("最好成绩{:4f}", best_acc)

    model.load_state_dict(best_model_wts)

    return model

def create_combined_model(model_fe):
    model_de_features = nn.Sequential(model_fe.quant
                                      ,model_fe.conv1
                                      ,model_fe.bn1
                                      ,model_fe.relu
                                      ,model_fe.maxpool
                                      ,model_fe.layer1
                                      ,model_fe.layer2
                                      ,model_fe.layer3
                                      ,model_fe.layer4
                                      ,model_fe.avgpool
                                      ,model_fe.dequant,)

    new_hea = nn.Sequential(nn.Dropout(0.5),nn.Linear(num_ftrs,2))
    new_model = nn.Sequential(model_de_features,nn.Flatten(1),new_hea)
    return new_model

if __name__ =="__main__":

    DATA_PATH = os.path.join(os.getcwd(), "../../BaiduNetdiskDownload/images")

    # 第二步
    data_transforms = {'train': transforms.Compose([transforms.Resize(224)
                                                       , transforms.RandomCrop(224)
                                                       , transforms.RandomHorizontalFlip()
                                                       , transforms.ToTensor(),
                                                    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
        , "val": transforms.Compose([transforms.Resize(224)
                                        , transforms.RandomCrop(224)
                                        , transforms.ToTensor(),
                                     transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])}

    data_dir = DATA_PATH
    image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x])
                      for x in ['train', 'val']}
    # num_workers=8 不使用多线程
    dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=64, shuffle=True, num_workers=4) for x
                   in ['train', 'val']}
    dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
    class_names = image_datasets['train'].classes
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

    model_fe = models.resnet18(pretrained=True, progress=True, quantize=False)
    num_ftrs = model_fe.fc.in_features
    new_model = create_combined_model(model_fe)
    new_model = new_model.to(device)
    criterion = nn.CrossEntropyLoss()
    optimizer_ft = optim.SGD(new_model.parameters(), lr=0.01, momentum=0.9)
    exp_lr_scheduler = optim.lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)
    new_model = train_model(new_model, criterion, optimizer_ft, exp_lr_scheduler, num_epochs=25, device=device)
    # 转化换模型
    new_model.cpu()

    #保持模型 加载的时候还要重新转换
    # torch.save(model_qbuantized_and_trained.state_dict(), "../../BaiduNetdiskDownload/empter_o_dirct.pt")
    # 保持模型
    torch.save(new_model, "empter_o.pt")


import requests
from datetime import datetime

from django.shortcuts import render

from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework.renderers import JSONRenderer

from .models import Book
from .serializers import (
    BookSerializer,
    BookCreateUpdateSerializer,
    AuthorSerializer
)

class ExternalBookView(APIView):
    renderer_classes = (JSONRenderer, )

    def get(self, request):
        query = request.GET.get('name', '')
        response = requests.get(f"https://www.anapioficeandfire.com/api/books?name={query}")
        data = []
        if response.ok:
            for d in response.json():
                data.append({
                    'name': d['name'],
                    'isbn': d['isbn'],
                    'authors': d['authors'],
                    'number_of_pages': d['numberOfPages'],
                    'publisher': d['publisher'],
                    'country': d['country'],
                    'release_date': datetime.strptime(d['released'], '%Y-%m-%dT%H:%M:%S').strftime("%Y-%m-%d")
                })
        return Response({
                'status_code': 200,
                'status': 'success',
                'data': data
            })

class BookViewset(viewsets.ModelViewSet):
    serializer_class = BookSerializer

    def get_queryset(self):
        queryset = Book.objects.all()
        name = self.request.query_params.get('name', None)
        country = self.request.query_params.get('country', None)
        publisher = self.request.query_params.get('publisher', None)
        release_date = self.request.query_params.get('release_date', None)

        if name is not None:
            return queryset.filter(name=name)
        elif country is not None:
            return queryset.filter(country=country)
        elif publisher is not None:
            return queryset.filter(publisher=publisher)
        elif release_date is not None:
            return queryset.filter(release_date__year=release_date)
        else:
            return queryset

    def list(self, request, *args, **kwargs):
        books = self.get_queryset()
        if books:
            serializer = self.get_serializer(books, many=True)
            serializer_data = serializer.data
        else:
            serializer_data = []
        return Response({
            'status_code': 200,
            'status': 'success',
            'data': serializer_data
        })

    def create(self, request, *args, **kwargs):
        serializer = BookCreateUpdateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        model_obj = serializer.save()
        model_obj_data = self.get_serializer(model_obj).data
        return Response({
            'status_code': 201,
            'status': 'success',
            'data': model_obj_data
        })

    def retrieve(self, request, *args, **kwargs):
        book = self.get_object()
        serializer = BookSerializer(book)
        return Response({
            'status_code': 200,
            'status': 'success',
            'data': serializer.data
        })

    def destroy(self, request, *args, **kwargs):
        book = self.get_object()
        book_name = book.name
        book.delete()
        return Response({
            'status_code': 204,
            'status': 'success',
            'message': f'The book {book_name} was deleted successfully',
            'data': []
        })

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = BookCreateUpdateSerializer(instance, data=request.data)
        serializer.is_valid(raise_exception=True)
        model_obj = serializer.save()
        model_obj_data = self.get_serializer(model_obj).data
        return Response({
                'status_code': 200,
                'status': 'success',
                'message': f'The book {instance.name} was updated successfully',
                'data': model_obj_data
            })


#!/usr/bin/env python3
import pyowm
import argparse
import subprocess

def process(args):

    owm = pyowm.OWM(args.api_key[0])
    mgr = owm.weather_manager()
    weather_details = mgr.weather_at_place(args.city[0] + ',' + args.ccode[0])
    weather_values = weather_details.weather

    if args.get_temp_c:
        temp = weather_values.temperature(unit='celsius')['temp']
        temp = round(int(temp))
        print(temp)
    if args.get_temp_f:
        temp = weather_values.temperature(unit='fahrenheit')['temp']
        temp = round(int(temp))
        print(temp)
    if args.get_weather_icon:
        print(weather_values.weather_icon_name)

parser = argparse.ArgumentParser(description='Openweather script.')
parser.add_argument('--api_key',help='OWM API key.',nargs=1,metavar=('[api_key]'), required=True)
parser.add_argument('--city',help='Cityname.',nargs=1,metavar=('[city]'), required=True)
parser.add_argument('--ccode',help='Country code.',nargs=1,metavar=('[code]'), required=True)
parser.add_argument('--get_temp_c',help='Get temperature in Celsius.',action='store_true')
parser.add_argument('--get_temp_f',help='Get temperature in Fahrenheit.',action='store_true')
parser.add_argument('--get_weather_icon',help='Get weather icon.',action='store_true')
args = parser.parse_args()

process(args)


import itertools
import logging
import string

log = logging.getLogger('lexer')

def is_newline(c):
    # TODO cross-platform line seps. Multiple chars on windows! so needs multiple states.
    #      or a look ahead
    return c == '\n'

def is_whitespace(c):
    return c == ' '

def is_digit(c):
    return c in string.digits

def is_word_char(c):
    return c in string.ascii_letters + '+-:='

def is_single_quote(c):
    return c == "'"

def is_expression_start(c):
    return c == '('

def is_expression_end(c):
    return c == ')'

class InvalidWord_SingleQuote(Exception):
    message = 'Invalid word: single quotes are not allowed'

class UnrecognizedInput(Exception):
    message = 'Unrecognized input'

class InvalidID_Newline(Exception):
    message = 'Invalid ID: newlines are not allowed'

class InvalidID_Empty(Exception):
    message = 'Invalid ID: empty'

class InvalidID_Incomplete(Exception):
    message = 'Invalid ID: incomplete'

class Token(object):

    def __init__(self, type, value=''):
        self.type = type
        self.value = value

    def _key(self):
        return self.type, self.value

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

    def __repr__(self):
        return 'Token({}, {})'.format(self.type, repr(self.value))

class StateMachine(object):

    def __init__(self):
        self.state = 'start'

    def get_type(self, c):
        if self.state == 'start':

            if is_word_char(c):
                self.state = 'word'
                return 'word'

            elif is_digit(c):
                self.state = 'number'
                return 'number'

            elif is_single_quote(c):
                self.state = 'start ID'
                return 'ignore'

            elif is_expression_start(c):
                return 'expression start'

            elif is_expression_end(c):
                return 'expression end'

            elif is_whitespace(c):
                return 'ignore'

            elif is_newline(c):
                self.state = 'newline'
                return 'newline'

            else:
                raise UnrecognizedInput()

        elif self.state == 'newline':

            if is_whitespace(c):
                return 'indent'

            elif is_expression_start(c):
                return 'expression start'

            elif is_expression_end(c):
                return 'expression end'

            else:
                self.state = 'start'
                return self.get_type(c)

        elif self.state == 'word':

            if is_word_char(c):
                return 'word'

            elif is_whitespace(c):
                self.state = 'start'
                return 'ignore'

            elif is_newline(c):
                self.state = 'newline'
                return 'newline'

            elif is_single_quote(c):
                raise InvalidWord_SingleQuote()

            elif is_expression_end(c):
                return 'expression end'

            else:
                raise UnrecognizedInput()

        # TODO consider moving number to a later step, where word
        #      gets transformed to number
        elif self.state == 'number':

            if is_digit(c):
                return 'number'

            elif is_whitespace(c):
                self.state = 'start'
                return 'ignore'

            elif is_newline(c):
                self.state = 'newline'
                return 'newline'

            elif is_single_quote(c):
                raise InvalidWord_SingleQuote()

            elif is_expression_end(c):
                return 'expression end'

            else:
                raise UnrecognizedInput()

        elif self.state == 'start ID':

            if is_word_char(c):
                self.state = 'ID'
                return 'ID'

            elif is_whitespace(c):
                return 'ignore'

            elif is_newline(c):
                raise InvalidID_Newline()

            elif is_single_quote(c):
                raise InvalidID_Empty()

            else:
                raise UnrecognizedInput()

        elif self.state == 'ID':

            if is_word_char(c) or is_whitespace(c):
                return 'ID'

            elif is_newline(c):
                raise InvalidID_Newline()

            elif is_single_quote(c):
                self.state = 'start'
                return 'ignore'

            else:
                raise UnrecognizedInput()

    def finalize(self):
        if self.state == 'start ID' or self.state == 'ID':
            raise InvalidID_Incomplete()

def source_to_tokens(chars):
    state = StateMachine()
    grouped = itertools.groupby(chars, state.get_type)

    # TODO maybe try to get rid of ''.join() as a perf. enhancement

    for group_type, group in grouped:
        if group_type == 'ignore':
            pass

        elif group_type == 'word':
            yield Token('word', ''.join(group))

        elif group_type == 'ID':
            yield Token('ID', ''.join(group).strip())

        elif group_type == 'newline':
            yield Token('newline', '')

        elif group_type == 'indent':
            yield Token('indent', len(list(group)))

        elif group_type == 'number':
            # TODO handle more than int()
            yield Token('number', int(''.join(group)))

        elif group_type == 'expression start':
            for _ in group:
                yield Token('expression start')

        elif group_type == 'expression end':
            for _ in group:
                yield Token('expression end')

        else:
            raise UnrecognizedInput()

    state.finalize()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Oct  7 19:08:11 2020

@author: qwang
"""

import os
import shutil
import torch
import json

#%%
def save_dict_to_json(d, json_path):
    """
    Save dict of floats to json file
    d: dict of float-castable values (np.float, int, float, etc.)

    """
    with open(json_path, 'w') as fout:
        d = {key: float(value) for key, value in d.items()}
        json.dump(d, fout, indent=4)

#%% Checkpoint
def save_checkpoint(state, is_best, checkdir):
    """
    Save model and training parameters at checkpoint + 'last.pth.tar'.
    If is_best==True, also saves checkpoint + 'best.pth.tar'
    Params:
        state: (dict) contains model's state_dict, may contain other keys such as epoch, optimizer state_dict
        is_best: (bool) True if it is the best model seen till now
        checkdir: (string) folder where parameters are to be saved
    """
    filepath = os.path.join(checkdir, 'last.pth.tar')
    if os.path.exists(checkdir) == False:
        os.mkdir(checkdir)
    torch.save(state, filepath)

    if is_best:
        shutil.copyfile(filepath, os.path.join(checkdir, 'best.pth.tar'))

def load_checkpoint(checkfile, model, optimizer=None):
    """
    Load model parameters (state_dict) from checkfile.
    If optimizer is provided, loads state_dict of optimizer assuming it is present in checkpoint.
    Params:
        checkfile: (string) filename which needs to be loaded
        model: (torch.nn.Module) model for which the parameters are loaded
        optimizer: (torch.optim) optional: resume optimizer from checkpoint
    """
    if os.path.exists(checkfile) == False:
        raise("File doesn't exist {}".format(checkfile))
    checkfile = torch.load(checkfile)
    model.load_state_dict(checkfile['state_dict'])

    if optimizer:
        optimizer.load_state_dict(checkfile['optim_dict'])

    return checkfile

#%% Metrics
def metrics_fn(preds, y, th=0.5):
    """
    Params:
        preds: torch tensor, [batch_size, output_dim]
        y: torch tensor, [batch_size]

    Yields:
        A dictionary of accuracy, f1 score, recall, precision and specificity

    """

    #  y_preds = preds.argmax(dim=1, keepdim=False)  # [batch_size, output_dim]  --> [batch_size]
    if torch.cuda.device_count() == 1:
        # y_preds = (preds[:,1] > th).type(torch.ShortTensor).cuda()
        y_preds = (preds[:,1] > th).int().type(torch.LongTensor).cuda()
    else:
        # y_preds = (preds[:,1] > th).type(torch.ShortTensor)
        y_preds = (preds[:,1] > th).int().type(torch.LongTensor)

    ones = torch.ones_like(y_preds)
    zeros = torch.zeros_like(y_preds)

    pos = torch.eq(y_preds, y).sum().item()
    tp = (torch.eq(y_preds, ones) & torch.eq(y, ones)).sum().item()
    tn = (torch.eq(y_preds, zeros) & torch.eq(y, zeros)).sum().item()
    fp = (torch.eq(y_preds, ones) & torch.eq(y, zeros)).sum().item()
    fn = (torch.eq(y_preds, zeros) & torch.eq(y, ones)).sum().item()

    assert pos == tp + tn

    acc = pos / y.shape[0]  # torch.FloatTensor([y.shape[0]])
    f1 = 2*tp / (2*tp + fp + fn) if (2*tp + fp + fn != 0) else 0
    rec = tp / (tp + fn) if (tp + fn != 0) else 0
    ppv = tp / (tp + fp) if (tp + fp != 0) else 0
    spc = tn / (tn + fp) if (tn + fp != 0) else 0

    return {'accuracy': acc, 'f1': f1, 'recall': rec, 'precision': ppv, 'specificity': spc}


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

import rarfile

path = r"testrar.rar"
path2 = r"./new"

rf = rarfile.RarFile(path)
rf.extractall(path2)  # 解压指定文件路径
rf.close()

'''
运行后报错缺少unrar进入第三部。
3.配置环境

　　需要WinRAR软件提供的UnRAR.exe文件（rar非开源所以必须使用winrar的文件）,以下三种方法。

　　WinRAR下载地址： http://www.winrar.com.cn

　　(1).据winrar的目录中的UnRAR.exe，拷贝到我的python脚本目录下，再执行就ok了；
　　(2).环境变量path中加入unrar.exe所在目录；(未成功)
　　(3).PyCharm的话，可以将unrar.exe复制到项目的venv/Scripts下。（未测试）

4.问题参考

　　https://blog.csdn.net/big_talent/article/details/52367184
　　https://blog.csdn.net/luoye7422/article/details/41873499
'''


import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
# sns.set_theme(style="whitegrid")
sns.set(font_scale = 2)
# plt.rcParams["axes.labelsize"] = 15

fig = plt.figure(figsize=(16,16))
ax = fig.add_subplot(111)
# Total time
x = ['a_2_c', 'a_2_v', 'a_1_c', 'a_1_v', 'na_2_c', 'na_2_v', 'na_1_c', 'na_1_v']
y = [246.063, 250.069, 150.984, 146.275, 132.25, 131.882, 130.84, 131.492]
times = pd.DataFrame()
times['scenario'] = x
times['total_process_time'] = y
ax = sns.barplot(x="scenario", y="total_process_time", data=times, palette="Blues_d")
ax.set_title('Total Time vs. Scenario')
ax.set_xlabel('scenario')
ax.set_ylabel('total process time (s)')
plt.savefig('totaltime.png')
plt.show()

fig = plt.figure(figsize=(16,16))
ax0 = fig.add_subplot(121)
#Proving time
y = [0.042, 0.023]
x = ['a_2_c', 'a_2_v']
times = pd.DataFrame()
times['scenario'] = x
times['proving_time'] = y
ax0 = sns.barplot(x="scenario", y="proving_time", data=times, palette="Blues_d", ax = ax0)
ax0.set_title('Proving Time vs. Scenario')
ax0.set_xlabel('scenario')
ax0.set_ylabel('proving time (s)')
plt.savefig('provingtime.png')
plt.show()

fig = plt.figure(figsize=(16,16))
ax1 = fig.add_subplot(121)
#Verifying time
x = ['a_2_v', 'a_1_v']
y = [0.041, 0.026]
times = pd.DataFrame()
times['scenario'] = x
times['verification_time'] = y
ax1 = sns.barplot(x="scenario", y="verification_time", data=times, palette="Blues_d", ax = ax1)
ax1.set_title('Verification Time vs. Scenario')
ax1.set_xlabel('scenario')
ax1.set_ylabel('verification time (s)')
plt.savefig('verifyingtime.png')
plt.show()


class Solution:
    def removeDuplicates(self, s: str, k: int) -> str:  # 97.11% 17.87%
        stack = []
        for char in s:
            if stack and stack[-1][0] == char:
                stack[-1][1] += 1
                if stack[-1][1] == k:
                    stack.pop()
                    continue
            else:
                stack.append([char, 1])
        return ''.join([x[0]*x[1] for x in stack])

    def removeDuplicates_best_speed(self, s: str, k: int) -> str:
        if not s or k <= 1:
            return ''
        let_counter = 0
        cur_letter = None
        result = []
        for c in s:
            if not cur_letter:
                cur_letter = c
            if c == cur_letter:
                let_counter += 1
                if let_counter == k:
                    if result:
                        prev_letter_counts = result.pop()
                        cur_letter = prev_letter_counts[0]
                        let_counter = prev_letter_counts[1]
                    else:
                        cur_letter = None
                        let_counter = 0
            else:
                result.append((cur_letter, let_counter))
                cur_letter = c
                let_counter = 1
        if cur_letter and let_counter:
            result.append((cur_letter, let_counter))
        return ''.join([r[0]*r[1] for r in result])

    def removeDuplicates_best_memory(self, s: str, k: int) -> str:
        if len(s) < k:
            return s
        counts = defaultdict(int)
        left = right = 0
        while right < len(s):
            counts[s[right]] += 1
            if counts[s[right]] == k:
                s = s[:left] + s[right + 1:]
                if left > 0:
                    left = max(0, left - k - 1)
                right = left
                counts = defaultdict(int)
                continue
            if right - left + 1 == k:
                counts[s[left]] -= 1
                left += 1
            right += 1
        return s

1200 - 1299/1209 - Remove All Adjacent Duplicates in String II/1209 - Remove All Adjacent Duplicates in String II.py


from codecs import BufferedIncrementalEncoder
import random, argparse, sys, datetime
import numpy as np
import cWrapper

from PIL import Image

# luminocity groups. Char will be chosen randomly from each group
luminosityGroups = ['1', '73', '4', '089']

def getAverageL(image):

    """
    Given PIL Image, return average value of grayscale value
    """
    # get image as numpy array
    im = np.array(image)

    # get shape
    w,h = im.shape

    # get average
    return np.average(im.reshape(w*h))

def covertImageToAscii(fileName, cols, scale, borderWidth, borderChar):
    """
    Given Image and dims (rows, cols) returns an m*n list of Images
    """
    # declare globals
    global luminosityGroups, rows

    # open image and convert to grayscale
    image = Image.open(fileName).convert('L')

    # store dimensions
    W, H = image.size[0], image.size[1]
    print("input image dims: %d x %d" % (W, H))

    # compute width of tile
    w = W/cols

    # compute tile height based on aspect ratio and scale
    h = w/scale

    # compute number of rows
    rows = int(H/h)

    print("cols: %d, rows: %d" % (cols, rows))
    print("tile dims: %d x %d" % (w, h))

    # check if image size is too small
    if cols > W or rows > H:
        print("Image too small for specified cols!")
        exit(0)

    # ascii image is a list of character strings
    asciiImage = []
    # generate list of dimensions
    for j in range(rows):
        y1 = int(j*h)
        y2 = int((j+1)*h)

        # correct last tile
        if j == rows-1:
            y2 = H

        # append an empty string
        asciiImage.append("")

        for i in range(cols):

            # crop image to tile
            x1 = int(i*w)
            x2 = int((i+1)*w)

            # correct last tile
            if i == cols-1:
                x2 = W

            # crop image to extract tile
            img = image.crop((x1, y1, x2, y2))

            # get average luminance
            avg = int(getAverageL(img))

            # find which luma group tile corresponds to
            luminosityNumber = int((avg*(len(luminosityGroups)-1))/255)

            # pick a random value within that group for the tile
            gsval = luminosityGroups[luminosityNumber][random.randint(0, len(luminosityGroups[luminosityNumber])-1)]

            # if no border then make sure first and last digits are odd, and not 5
            if borderWidth == 0:
                if (i == 0 and j == 0) or (i == cols-1 and j == rows-1):
                    if int(gsval) % 2 == 0 or int(gsval) % 5 == 0:

                        # first try to find odd digit in same luminosity group
                        for digit in luminosityGroups[luminosityNumber]:
                            if int(digit) % 2 != 0 and int(digit) % 5 != 0:
                                gsval = digit
                                break

                        # if all are even then just use borderChar
                    if int(gsval) % 2 == 0 or int(gsval) % 5 == 0:
                        gsval = borderChar

            # looks better if border width on top is half of side border (aspect ratio)
            topBorderWidth = round(borderWidth / 2.0)

            # check if current tile is part of the border and if so change it to borderChar
            if (j in [*[r for r in range(0, topBorderWidth)], *[r for r in range(rows-topBorderWidth, rows)]]) or (i in [*[c for c in range(0, borderWidth)], *[c for c in range(cols-borderWidth, cols)]]):
                gsval = borderChar

            # append ascii char to string
            asciiImage[j] += gsval

    # return txt image
    return asciiImage

# main() function
def main():
    global luminosityGroups
    # ------------------------------- ARGUMENT PARSER ---------------------------------
    # create parser
    descStr = "This program converts an image into a prime number that is also ASCII art."
    parser = argparse.ArgumentParser(description=descStr)
    # add expected arguments
    parser.add_argument('--file', dest='imgFile', required=True, help='path to image file')
    parser.add_argument('--scale', dest='scale', required=False, help='Vertical scaling of input image to compensate for non square "ascii pixels"')
    parser.add_argument('--cols', dest='cols', required=False, help='width of the final ascii image')
    parser.add_argument('--borderWidth', dest='borderWidth', required=False, help='width of the border')
    parser.add_argument('--borderChar', dest='borderChar', required=False, help='character to use for border, must be and odd number')
    parser.add_argument('--invert', dest='invert', action='store_true', required=False, help='inverts colors of input image')
    parser.add_argument('--autoSave', dest='autoSave', action='store_true', required=False, help='automatically saves ascii art to file, without prompting user')

    # parse args
    args = parser.parse_args()

    imgFile = args.imgFile

    # set scale default as 0.43 which suits
    # a Courier font
    scale = 0.46
    if args.scale:
        scale = float(args.scale)

    # set cols
    cols = 80
    if args.cols:
        cols = int(args.cols)

    # set border
    borderWidth = 0
    if args.borderWidth:
        borderWidth = int(args.borderWidth)

    # set borderChar
    borderChar = '1'
    if args.borderChar:
        try:
            int(args.borderChar)
        except ValueError:
            print("borderChar must be an odd digit and not 5")
            sys.exit(0)

        if int(args.borderChar) % 2 == 0 or int(args.borderChar) % 5 == 0:
            print("borderChar must odd and not 5!")
            sys.exit(0)

        borderChar = args.borderChar

    # set invert
    if args.invert:
        luminosityGroups = luminosityGroups[::-1]

    # set autoSave
    autoSave = False
    if args.autoSave:
        autoSave = True

    numberOfPrimeChecks = 25

    # ------------------------------- Generate Ascii image ---------------------------------

    print('generating ASCII art...\n')
    # convert image to ascii txt
    asciiImage = covertImageToAscii(imgFile, cols, scale, borderWidth, borderChar)

    #print image to terminal
    print('')
    for row in asciiImage:
        print(row)

    # ------------------------------- Estimate calc time ---------------------------------

    # estimate how long it will take to primify the image
    print("\nEstimating time to primify image...", end="")
    sys.stdout.flush()
    durationForSingleCheck = cWrapper.estimateCalcDuration(asciiImage, numberOfPrimeChecks=25, maxNumberOfTrails=100, maxDuration=10)

    # clear previous print
    print('', end="\r")

    # probability of a number of the order 10^(cols*rows) being prime
    power = cols*rows
    primeProbability = (9*power - 1 ) / (9*power *(power + 1) * np.log(10))

    # function that returns number of trails needed to find a prime with probability S
    probableTrailCountEstimate = lambda S: np.log(1 - S) / np.log(1 - primeProbability)

    # display time estimates for different probabilities
    for prob in [0.5, 0.9, 0.99, 0.999]:
        print(f"    {100*prob:.1f}% probability of finding prime within: {str(datetime.timedelta(seconds=round(durationForSingleCheck * probableTrailCountEstimate(prob))))}")

    # ------------------------------- Ask user if they want to primify the image ---------------------------------

    # ask user if they want to move on
    print('\nWould you like to primify this image? (y/n)')
    ans = input('--> ')
    print('')

    if ans != 'y' and ans != 'Y':
        print('Image not primified.')
        print("\n-------------------------------- Program Terminated --------------------------------\n")
        sys.exit(0)

    # ------------------------------- PRIMIFY IMAGE ---------------------------------
    asciiImage = cWrapper.primify(asciiImage, cols, rows, borderWidth, luminosityGroups, primeProbability, numberOfPrimeChecks)

    # print image to terminal
    print("\n------------------------------------- SUCESSFULLY PRIMIFIED IMAGE -------------------------------------\n")
    for row in asciiImage:
        print(row)

    # print extra info
    print(f'\nThe probability of this number being truly prime is:\t{(1- 0.25**numberOfPrimeChecks)*100:.20f}%')

    # ------------------------------- Ask user if they want to save the image ---------------------------------

    if not autoSave:
        print('\nWould you like to save this image? (y/n)')
        ans = input('--> ')
        if ans != 'y' and ans != 'Y':
            print("\n-------------------------------- Program Terminated --------------------------------\n")
            sys.exit(0)

    # ------------------------------- SAVE IMAGE ---------------------------------

    fileName = imgFile.rsplit(".", 1)[0].rsplit("/", 1)[1] + f"_primified_cols_{cols}.txt"
    with open(fileName, "w") as f:

        f.write("\n------------------------------------- Sucessfully primified image -------------------------------------\n\n")

        for row in asciiImage:
            f.write(row + "\n")

        f.write("\n------------------------------------- Number as single string -------------------------------------\n\n")
        f.write(''.join(asciiImage))

        f.write("\n\n-------------------------------------------- Properties --------------------------------------------\n\n")
        f.write(f"Number of columns: {cols}\n")
        f.write(f"Number of rows: {rows}\n")
        f.write(f"Number of digits: {cols*rows}\n")

    print("\nSaved image to: ", fileName)
    print("\n-------------------------------- Program Terminated --------------------------------\n")

# call main
if __name__ == '__main__':
    main()


import numpy as np
import scipy
import numpy as np
import torch

from model import *
from util import *
from sklearn import datasets

device = "cuda"
print("###################EXPERIMENTS ON COVERTYPE#########################")
cover_data, cover_targets = datasets.fetch_covtype(data_home=None, download_if_missing=True, random_state=None, shuffle=False, return_X_y=True)
print(cover_data.shape, cover_targets.shape)
train_loader = []
cla = cover_targets
for i in range(cover_data.shape[0]//100):
    train_loader.append(torch.from_numpy(cover_data[i*100:(i+1)*100]).float().to(device))

model = VaDE(7, 10, 54).to(device)
model.pre_train(train_loader, 50)
train(model, train_loader, 100)
torch.save(model.state_dict(), "covertype_VaDE_parameters.pth")

print("###################EXPERIMENTS ON DIGIT###########################")

data, target = datasets.load_digits(n_class=10, return_X_y=True)
train_loader = []
cla = target
for i in range(data.shape[0]//10):
    train_loader.append(torch.from_numpy(data[i*10:(i+1)*10]).float())

model = VaDE(10, 3, 64)
model.pre_train(train_loader, 50)
train(model, train_loader, 100)

Z_vade = linkage(mean.detach().numpy()[:200], "average")
rootnode, nodelist = scipy.cluster.hierarchy.to_tree(Z_vade, rd=True)
print("Dendrogram Purity:", compute_purity(Z_vade, cla[:200], 10))

print("###################EXPERIMENTS ON GLASS##########################")


import streamlit as st

import arrow
import datetime
import json
import pandas as pd
import requests

from typing import Any

from .helpers import *

def get_page_data(page: int = 1) -> Any:

    offset = (page - 1) * 25
    headers = {
        'content-type': 'application/json',
    }

    data = '{"operationName":"ContractInteractionsQuery","variables":{"id":"A.8b148183c28ff88f.Gaia","limit":25,"offset":' + str(offset) + '},"query":"query ContractInteractionsQuery($id: ID!, $limit: Int!, $offset: Int) {\\n  contract(id: $id) {\\n    interactions(limit: $limit, offset: $offset) {\\n      count\\n      edges {\\n        node {\\n          time\\n          id\\n          proposer {\\n            address\\n            __typename\\n          }\\n          status\\n          eventTypes(contractIds: [$id]) {\\n            fullId\\n            __typename\\n          }\\n          __typename\\n        }\\n        __typename\\n      }\\n      __typename\\n    }\\n    __typename\\n  }\\n}\\n"}'  # noqa

    response = requests.post('https://flowscan.org/query', headers=headers, data=data)

    if response.status_code == 200:
        return json.loads(response.text)
    else:
        print(response.text)
        raise Exception("Flowscan retrieval issue")

def get_detail(id: str) -> Any:
    headers = {
        'content-type': 'application/json',
    }

    data = '{"operationName":"TransactionEventsSectionQuery","variables":{"id":"' + id + '","limit":20,"offset":0},"query":"query TransactionEventsSectionQuery($id: ID!, $eventTypeFilter: [ID!], $limit: Int, $offset: Int) {\\n  checkTransaction(id: $id) {\\n    transaction {\\n      eventTypes {\\n        fullId\\n        __typename\\n      }\\n      events(first: $limit, skip: $offset, type: $eventTypeFilter) {\\n        edges {\\n          node {\\n            indexInTransaction\\n            eventType {\\n              fullId\\n              __typename\\n            }\\n            fields\\n            __typename\\n          }\\n          __typename\\n        }\\n        count\\n        __typename\\n      }\\n      __typename\\n    }\\n    __typename\\n  }\\n}\\n"}'

    response = requests.post('https://flowscan.org/query', headers=headers, data=data)

    return json.loads(response.text)

def transaction_info(time: str, id: str) -> Any:

    response = get_detail(id)
    tx_events = response["data"]["checkTransaction"]["transaction"]["events"]["edges"]

    if len(tx_events) != 18:
        return None

    evt_price = tx_events[0]["node"]
    evt_price_type = "A.ead892083b3e2c6c.DapperUtilityCoin.TokensWithdrawn"
    if evt_price["indexInTransaction"] != 0 or evt_price["eventType"]["fullId"] != evt_price_type:
        return None
    price = float(evt_price["fields"][0]["value"])

    evt_seller = tx_events[1]["node"]
    evt_seller_type = "A.8b148183c28ff88f.Gaia.Withdraw"
    if evt_seller["indexInTransaction"] != 1 or evt_seller["eventType"]["fullId"] != evt_seller_type:
        return None
    seller = evt_seller["fields"][1]["value"]["value"]

    evt_buyer = tx_events[14]["node"]
    evt_buyer_type = "A.8b148183c28ff88f.Gaia.Deposit"
    if evt_buyer["indexInTransaction"] != 14 or evt_buyer["eventType"]["fullId"] != evt_buyer_type:
        return None
    buyer = evt_buyer["fields"][1]["value"]["value"]
    transaction_token_id = int(evt_buyer["fields"][0]["value"])
    buyer = evt_buyer["fields"][1]["value"]["value"]

    # map baller id from transaction token
    baller_result = BALLERZ[BALLERZ["transaction_token_id"] == transaction_token_id]
    if len(baller_result) != 1:
        return None
    baller = baller_result.iloc[0]

    return {
        "baller_id": baller["baller_id"],
        "image": baller["Image"],
        "price": price,
        "combo": baller["Combo Rank"],
        "rarity": baller["Trait Rank"],
        "skill": baller["Skill Rank"],
        "team": baller["Team"],
        "role": baller["Role"],
        "timestamp": int(time),
        "datetime": arrow.get(int(time)).datetime,
        "time": arrow.get(int(time)).humanize(),
        "buyer": buyer,
        "seller": seller,
        "transaction_id": id,
    }

def matches_top_level_events(x: Any) -> bool:
    types = str(x["node"]["eventTypes"])
    result = "A.8b148183c28ff88f.Gaia.Deposit" in types and "A.8b148183c28ff88f.Gaia.Withdraw" in types
    return result

def get_raw_df_for_page(page: int = 1) -> pd.DataFrame:
    response = get_page_data(page)
    edges = response["data"]["contract"]["interactions"]["edges"]
    transactions = [transaction_info(x["node"]["time"], x["node"]["id"]) for x in edges if matches_top_level_events(x)]  # noqa
    transactions = [tx for tx in transactions if tx is not None]

    r = pd.DataFrame(transactions)
    if 'datetime' in r.columns:
        r.set_index('datetime', inplace=True)
    return r

def get_display_df_for_page(page: int = 1) -> pd.DataFrame:

    df = get_raw_df_for_page(page)

    # make it prettier for ux
    df['baller_id'] = df['baller_id'].apply(make_baller_id_clickable)
    df['price'] = df['price'].apply(lambda x: f"${x:.0f}")
    df['transaction_id'] = df['transaction_id'].apply(make_tx_clickable)
    df['buyer'] = df['buyer'].apply(make_wallet_clickable)
    df['seller'] = df['seller'].apply(make_wallet_clickable)
    df['image'] = df['image'].apply(path_to_image_html)
    df = df.to_html(escape=False)
    return df

def display() -> Any:
    st.title("Ballerz Recent Salez")

    page_choice = st.sidebar.selectbox('Page?', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

    df = get_display_df_for_page(page_choice)
    st.write(df, unsafe_allow_html=True)


# imports
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
# from sklearn import set_config; set_config(display='diagram')
from TaxiFareModel.encoders import DistanceTransformer, TimeFeaturesEncoder
from TaxiFareModel.utils import compute_rmse
from TaxiFareModel.data import get_data, clean_data
from google.cloud import storage
import joblib

### GCP Storage - - - - - - - - - - - - - - - - - - - - - -

BUCKET_NAME = 'wagon-data-577-hunt'

##### Data  - - - - - - - - - - - - - - - - - - - - - - - -

# train data file location
BUCKET_TRAIN_DATA_PATH = 'data/train_1k.csv'

##### Training  - - - - - - - - - - - - - - - - - - - - - -

# not required here

##### Model - - - - - - - - - - - - - - - - - - - - - - - -

# model folder name (will contain the folders for all trained model versions)
MODEL_NAME = 'taxifare'

# model version folder name (where the trained model.joblib file will be stored)
MODEL_VERSION = 'v1'

# For storing model
STORAGE_LOCATION = 'models/simpletaxifare/model.joblib'

class Trainer():
    def __init__(self, X, y):
        """
            X: pandas DataFrame
            y: pandas Series
        """
        self.pipeline = None
        self.X = X
        self.y = y

    def set_pipeline(self):
        """defines the pipeline as a class attribute"""

        # create distance pipeline
        dist_pipe = Pipeline([
                    ('dist_trans', DistanceTransformer()),
                    ('stdscaler', StandardScaler())])

        # create time pipeline
        time_pipe = Pipeline([
                    ('time_enc', TimeFeaturesEncoder('pickup_datetime')),
                    ('ohe', OneHotEncoder(handle_unknown='ignore'))])

        # create preprocessing pipeline
        preproc_pipe = ColumnTransformer([
                        ('distance',
                            dist_pipe,
                            ["pickup_latitude",
                             "pickup_longitude",
                             'dropoff_latitude',
                             'dropoff_longitude']),
                        ('time', time_pipe,
                         ['pickup_datetime'])],
                        remainder="drop")

        # Add linear regression model
        self.pipeline = Pipeline([
                ('preproc', preproc_pipe),
                ('linear_model', LinearRegression())])

    def train(self):
        """set and train the pipeline"""
        self.set_pipeline()
        self.pipeline.fit(self.X, self.y)

    def evaluate(self, X_test, y_test):
        """evaluates the pipeline on df_test and return the RMSE"""
        y_pred = self.pipeline.predict(X_test)
        rmse = compute_rmse(y_pred, y_test)
        return rmse

    def upload_model_to_gcp(self):
        client = storage.Client()
        bucket = client.bucket(BUCKET_NAME)
        blob = bucket.blob(STORAGE_LOCATION)
        blob.upload_from_filename('model.joblib')

    def save_model(self):
        """method that saves the model into a .joblib file and uploads it on Google Storage /models folder
        HINTS : use joblib library and google-cloud-storage"""

        # saving the trained model to disk necessary to upload it to storage
        joblib.dump(self.pipeline, 'model.joblib')
        print("saved model.joblib locally")

        # Implement here
        self.upload_model_to_gcp()
        print(f"uploaded model.joblib to gcp cloud storage under \n => {STORAGE_LOCATION}")

if __name__ == "__main__":
    # store the data in a DataFrame
    df = get_data()

    # clean data
    df = clean_data(df)

    # set X and y
    y = df["fare_amount"]
    X = df.drop("fare_amount", axis=1)

    # hold out
    X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.15)

    # Initialise
    trainer = Trainer(X_train, y_train)

    # train the pipeline
    trainer.train()

    # evaluate the pipeline
    rmse = trainer.evaluate(X_val, y_val)

    print(f'RMSE is: {rmse}')

    #Saving model
    trainer.save_model()


from .rrt import *
from .sampleutils import InformedSampler
from math import ceil

class RRTStar(RRT):

    def __init__(self, start, goal, Map,
                 max_extend_length = 10.0,
                 path_resolution = 0.5,
                 goal_sample_rate = 0.05,
                 max_iter = 200 ):
        super().__init__(start, goal, Map, max_extend_length,
                         path_resolution, goal_sample_rate, max_iter)
        self.final_nodes = []
        self.Informedsampler = InformedSampler(goal, start)

    def plan(self):
        """Plans the path from start to goal while avoiding obstacles"""
        self.start.cost = 0
        self.tree.add(self.start)
        for i in range(self.max_iter):
            #Generate a random node (rnd_node)
            rnd = self.get_random_node()
            # Get nearest node
            nearest_node = self.tree.nearest(rnd)
            # Get new node by connecting rnd_node and nearest_node
            new_node = self.steer(nearest_node, rnd)
            # If path between new_node and nearest node is not in collision
            if not self.map.collision(nearest_node.p,new_node.p):
              #add the node to tree
              self.add(new_node)
        #Return path if it exists
        if not self.goal.parent: path = None
        else: path = self.final_path()
        return path, self.goal.cost

    def add(self,new_node):
        near_nodes = self.near_nodes(new_node)
        # Connect the new node to the best parent in near_inds
        self.choose_parent(new_node,near_nodes)
        #add the new_node to tree
        self.tree.add(new_node)
        # Rewire the nodes in the proximity of new_node if it improves their costs
        self.rewire(new_node,near_nodes)
        #check if it is in close proximity to the goal
        if self.dist(new_node,self.goal) <= self.max_extend_length:
          # Connection between node and goal needs to be collision free
          if not self.map.collision(self.goal.p,new_node.p):
            #add to final nodes if in goal region
            self.final_nodes.append(new_node)
        #set best final node and min_cost
        self.choose_parent(self.goal,self.final_nodes)

    def choose_parent(self, node, parents):
        """Set node.parent to the lowest resulting cost parent in parents and
           node.cost to the corresponding minimal cost
        """
        # Go through all near nodes and evaluate them as potential parent nodes
        for parent in parents:
          #checking whether a connection would result in a collision
          if not self.map.collision(node.p,parent.p):
            #evaluating the cost of the new_node if it had that near node as a parent
            cost = self.new_cost(parent, node)
            #picking the parent resulting in the lowest cost and updating the cost of the new_node to the minimum cost.
            if cost < node.cost:
              node.parent = parent
              node.cost = cost

    def rewire(self, new_node, near_nodes):
        """Rewire near nodes to new_node if this will result in a lower cost"""
        #Go through all near nodes and check whether rewiring them to the new_node is useful
        for node in near_nodes:
          self.choose_parent(node,[new_node])
        self.propagate_cost_to_leaves(new_node)

    def near_nodes(self, node):
        """Find the nodes in close proximity to given node"""
        nnode = self.tree.len + 1
        r = ceil(5.5*np.log(nnode))
        return self.tree.k_nearest(node,r)

    def new_cost(self, from_node, to_node):
        """to_node's new cost if from_node were the parent"""
        return from_node.cost + self.dist(from_node, to_node)

    def propagate_cost_to_leaves(self, parent_node):
        """Recursively update the cost of the nodes"""
        for node in self.tree.all():
            if node.parent == parent_node:
                node.cost = self.new_cost(parent_node, node)
                self.propagate_cost_to_leaves(node)

    def sample(self):
        """Sample random node inside the informed region"""
        lower,upper = self.map.bounds
        if self.goal.parent:
          rnd = np.inf
          #sample until rnd is inside bounds of the map
          while not self.map.inbounds(rnd):
              # Sample random point inside ellipsoid
              rnd = self.Informedsampler.sample(self.goal.cost)
        else:
          # Sample random point inside boundaries
          rnd = lower + np.random.rand(self.dim)*(upper - lower)
        return rnd