import glob
import os
import plistlib
import re
import shutil
from subprocess import PIPE, Popen, run
import sys

from .project import Binary, Path, Project
from . import utils

class Bundler():
    def __init__(self, the_project):
        self.project = the_project

        self.project_dir = the_project.get_project_dir()

        plist_path = self.project.get_plist_path()
        with open(plist_path, "rb") as f:
            self.plist = plistlib.load(f)

        # List of paths that should be recursively searched for
        # binaries that are used to find library dependencies.
        self.binaries_to_copy = []
        self.copied_binaries = []
        #List of frameworks moved into the bundle which need to be set
        #up for private use.
        self.frameworks = []

        # Create the bundle in a temporary location first and move it
        # to the final destination when done.
        self.meta = the_project.get_meta()
        self.bundle_path = os.path.join(self.meta.dest, "." + the_project.get_bundle_name() + ".app")

    def recursive_rm(self, dirname):
        # Extra safety ;)
        if dirname in [ "/", os.getenv("HOME"), os.path.join(os.getenv("HOME"), "Desktop"), self.meta.dest ]:
            print(f"Eek, trying to remove a bit much, eh? {dirname}")
            sys.exit(1)

        if not os.path.exists(dirname):
            return

        files = os.listdir(dirname)
        for file in files:
            path = os.path.join (dirname, file)
            if os.path.isdir(path):
                self.recursive_rm(path)
            else:
                os.unlink(path)
        if os.path.islink(dirname):
            os.unlink(dirname)
        else:
            os.rmdir(dirname)

    def create_skeleton(self):
        utils.makedirs(self.project.get_bundle_path("Contents/Resources"))
        utils.makedirs(self.project.get_bundle_path("Contents/MacOS"))

    def create_pkglist(self):
        path = self.project.get_bundle_path("Contents", "PkgInfo")
        path = self.project.evaluate_path(path)
        with open (path, "w", encoding='utf-8') as fout:
            fout.write(self.plist['CFBundlePackageType'])
            fout.write(self.plist['CFBundleSignature'])

    def copy_plist(self):
        path = Path(self.project.get_plist_path(),
                    self.project.get_bundle_path("Contents/Info.plist"))
        path.copy_target(self.project)

    def run_module_catalog(self, env_var, env_val, exe_name):
        exepath = self.project.evaluate_path(f'${{prefix}}/bin/{exe_name}')
        temppath = self.project.get_bundle_path('Contents/MacOS/', exe_name)
        path = Binary(exepath, temppath)
        path.copy_target(self.project)

        local_env = os.environ.copy()
        local_env[env_var] = env_val
        with Popen(temppath, env=local_env, stdout=PIPE) as output:
            catalog = output.communicate()[0].splitlines()
            os.remove(temppath)
            return catalog

    def create_gtk_immodules_setup(self):
        path = self.project.get_bundle_path("Contents/Resources")
        env_var = "GTK_EXE_PREFIX"
        exe_name = 'gtk-query-immodules-' + self.project.get_gtk_version()
        f = self.run_module_catalog(env_var, path, exe_name)
        if self.meta.gtk == 'gtk+-2.0':
            path = self.project.get_bundle_path("Contents/Resources/etc/",
                                                self.project.get_gtk_dir())
            file = 'gtk.immodules'
        else:
            gtkdir = self.project.evaluate_path('${pkg:'+
                                                self.meta.gtk +
                                                ':gtk_binary_version}')
            path = self.project.get_bundle_path("Contents/Resources/lib/",
                                                self.project.get_gtk_dir(),
                                                gtkdir)
            file = 'immodules.cache'
        utils.makedirs(path)
        with open(os.path.join(path, file), "w", encoding='utf-8') as fout:

            prefix = "\"" + self.project.get_bundle_path("Contents/Resources")

            for line in f:
                if sys.version_info[0] > 2:
                    line = line.decode('utf-8')
                    line = line.strip()
                    if line.startswith("#"):
                        continue

                # Replace the hardcoded bundle path with @executable_path...
                if line.startswith(prefix):
                    line = line[len(prefix):]
                    line = "\"@executable_path/../Resources" + line
                fout.write(line)
                fout.write("\n")

    def create_gdk_pixbuf_loaders_setup(self):
        if os.path.exists(os.path.join(self.project.get_prefix(), "lib",
                                       "gdk-pixbuf-2.0")):

            modulespath = self.project.get_bundle_path("Contents/Resources/lib/",
                                                     "gdk-pixbuf-2.0",
                                                     "${pkg:gdk-pixbuf-2.0:gdk_pixbuf_binary_version}",
                                                     "loaders")
            cachepath = self.project.get_bundle_path("Contents/Resources/lib/",
                                                     "gdk-pixbuf-2.0",
                                                     "${pkg:gdk-pixbuf-2.0:gdk_pixbuf_binary_version}",
                                                     "loaders.cache")
        elif os.path.exists(os.path.join(self.project.get_prefix(), "lib",
                                       "gdk-pixbuf-3.0")):
            modulespath = self.project.get_bundle_path("Contents/Resources/lib/",
                                                     "gdk-pixbuf-3.0",
                                                     "${pkg:gdk-pixbuf-3.0:gdk_pixbuf_binary_version}",
                                                     "loaders")
            cachepath = self.project.get_bundle_path("Contents/Resources/lib/",
                                                     "gdk-pixbuf-3.0",
                                                     "${pkg:gdk-pixbuf-3.0:gdk_pixbuf_binary_version}",
                                                     "loaders.cache")
        else:
            modulespath = self.project.get_bundle_path("Contents/Resources/lib/",
                                                       self.project.get_gtk_dir(),
                                                       "${pkg:" + self.meta.gtk + ":gtk_binary_version}",
                                                       "loaders")
            cachepath = self.project.get_bundle_path("Contents/Resources/etc/",
                                                     self.project.get_gtk_dir(),
                                                     "gdk-pixbuf.loaders")

        modulespath = utils.evaluate_pkgconfig_variables (modulespath)
        cachepath = utils.evaluate_pkgconfig_variables (cachepath)

        env_var = 'GDK_PIXBUF_MODULEDIR'
        f = self.run_module_catalog(env_var, modulespath,
                                    'gdk-pixbuf-query-loaders')

        utils.makedirs(os.path.dirname(cachepath))
        with open(cachepath, "w", encoding='utf-8') as fout:

            prefix = "\"" + self.project.get_bundle_path("Contents/Resources")
            for line in f:
                if sys.version_info[0] > 2:
                    line = line.decode('utf-8')
                line = line.strip()
                if line.startswith("#"):
                    continue

                # Replace the hardcoded bundle path with @executable_path...
                if line.startswith(prefix):
                    line = line[len(prefix):]
                    line = "\"@executable_path/../Resources" + line
                fout.write(line)
                fout.write("\n")

    def copy_binaries(self):
        #clean up duplicates
        binaries = list(set(self.binaries_to_copy))
        for path in binaries:
            if not isinstance(path, Path):
                print(f'Warning, {path} not a Path object, skipping.')
                continue
            if os.path.islink(path.source):
                continue
            if path.compute_destination(self.project) in binaries:
                continue
            copied_paths = path.copy_target(self.project)
            if isinstance(copied_paths, str):
                print(f'Warning: copy_target returned string {copied_paths}')
                copied_paths = [copied_paths]
            bad_paths = [p for p in copied_paths if (p.endswith('.la')
                                                     or p.endswith('.a'))]
            for path in bad_paths:
                os.remove(path)
                copied_paths.remove(path)
            self.copied_binaries.extend(copied_paths)

    # Lists all the binaries copied in so far. Used in the library
    # dependency resolution and icon theme lookup.
    def list_copied_binaries(self):
        def filter_path(path):
            if os.path.islink(path):
                return False
            if path.endswith(".so") or path.endswith(".dylib") or os.access(path, os.X_OK):
                return True
            return False

        paths = []
        for path in self.copied_binaries:
            try:
                if os.path.isdir(path):
                    print (f'Recursing down copied binary path {path}.')
                    for root, dummy_dirs, files in os.walk(path):
                        paths.extend([os.path.join(root, l) for l in files])
                else:
                    paths.append(path)
            except TypeError:
                if isinstance(path, Path):
                    print(f'Warning, Path object for {path.source} in copied binaries list.')
                else:
                    print(f'Warning: Wrong object of type {type(path)} in copied_binaries list.')
                continue

        paths = list(filter(filter_path, paths))
        return list(set(paths))

    def resolve_library_dependencies(self):
        # Get the libraries we link to, filter out anything that
        # doesn't come from any of the prefixes we have declared. Then
        # copy in the resulting list, and repeat until the list
        # doesn't change. At that point, all dependencies are
        # resolved.
        n_iterations = 0
        n_paths = 0
        paths = self.binaries_to_copy

        def relative_path_map(line):
            if not os.path.isabs(line):
                for prefix in list(prefixes.values()):
                    if line.startswith('@'):
                        line = re.sub(r'@[-_a-z]+/', '', line)
                    path = os.path.join(prefix, "lib", line)
                    if os.path.exists(path):
                        return path
                print(f'Cannot find a matching prefix for {line}')
            return line

        def prefix_filter(line):
            if not "(compatibility" in line:
                #print(f'Removed {line}')
                return False

            if line.startswith("/usr/X11"):
                print("Warning, found X11 library dependency, you most likely don't want that:", line.strip().split()[0])

            if os.path.isabs(line):
                for prefix in list(prefixes.values()):
                    if prefix in line:
                        return True

                if not line.startswith("/usr/lib") and not line.startswith("/System/Library"):
                    print("Warning, library not available in any prefix:",
                          line.strip().split()[0])
                return False

            return True

        while n_paths != len(paths):
            cmds = ['otool', '-L']
            binaries= []
            for path in paths:
                if isinstance(path, Path):
                    source = path.compute_source_path(self.project)
                    if path.is_source_glob():
                        source_dir, pattern = os.path.split(source)
                        for root, dummy_dirs, dummy_files in os.walk(source_dir):
                            for item in glob.glob(os.path.join(root, pattern)):
                                if os.path.isfile(os.path.join(root, item)):
                                    binaries.append(os.path.join(root, item))
                    elif os.path.isdir(source):
                        for root, dummy_dirs, dummy_files in os.walk(source):
                            for item in glob.glob(os.path.join(root, '*.so')):
                                binaries.append(os.path.join(root, item))
                            for item in glob.glob(os.path.join(root, '*.dylib')):
                                binaries.append(os.path.join(root, item))
                    else:
                        binaries.append(source)
                else:
                    binaries.append(path)

            if not binaries:
                break
            cmds.extend(binaries)
            with Popen(cmds, stdout=PIPE, stderr=PIPE) as output:
                results, errors = output.communicate()
                if errors:
                    if sys.version_info[0] > 2:
                        print(f'otool errors:\n{errors.decode("utf-8")}')
                    else:
                        print(f'otool errors:\n{errors}')

                if sys.version_info[0] > 2:
                    results = results.decode("utf-8")
                prefixes = self.meta.prefixes
                lines = list(filter(prefix_filter,
                                    [line.strip() for line in results.splitlines()]))
                p = re.compile(r"(.*\.dylib\.?.*)\s\(compatibility.*$")
                lines = utils.filterlines(p, lines)
                lines = list(map(relative_path_map, lines))
                new_libraries = []
                for library in set(lines):
                    # Replace the real path with the right prefix so we can
                    # create a Path object.
                    for (key, value) in list(prefixes.items()):
                        if library.startswith(value):
                            path = Binary("${prefix:" + key + "}" + library[len(value):])
                            new_libraries.append(path)

                n_paths = len(paths)
                n_iterations += 1
                if n_iterations > 10:
                    print("Too many tries to resolve library dependencies")
                    sys.exit(1)

                self.binaries_to_copy.extend(new_libraries)
                paths = new_libraries

    def copy_icon_themes(self):
        all_icons = set()

        themes = self.project.get_icon_themes()

        for theme in themes:
            theme.copy_target(self.project)
            all_icons |= theme.enumerate_icons(self.project)

        strings = set()

        # Get strings from binaries.
        for f in self.list_copied_binaries():
            p = run("strings " + f, shell=True, stdout=PIPE, text=True,
                    check=False, errors='ignore')
            for string in p.stdout.splitlines():
                string = string.strip()
                strings.add(string)

        # FIXME: Also get strings from glade files.

        used_icons = all_icons.intersection(strings)
        for theme in themes:
            theme.copy_icons(self.project, used_icons)

    def copy_translations(self):
        for translation in self.project.get_translations():
            translation.copy_target(self.project)

    def install_gir(self):
        if not self.project.get_gir():
            return
        gir_dest = self.project.get_bundle_path('Contents', 'Resources',
                                                'share', 'gir-1.0')
        typelib_dest = self.project.get_bundle_path('Contents', 'Resources',
                                                    'lib', 'girepository-1.0')
        lib_path = os.path.join(self.project.get_prefix(), 'lib')
        utils.makedirs(gir_dest)
        utils.makedirs(typelib_dest)

        for gir in self.project.get_gir():
            self.binaries_to_copy.extend(gir.copy_girfile(self.project, gir_dest,
                                                          typelib_dest, lib_path))

    def run(self):
        # Remove the temp location forcefully.
        path = self.project.evaluate_path(self.bundle_path)
        self.recursive_rm(path)

        final_path = os.path.join(self.meta.dest, self.project.get_bundle_name() + ".app")
        final_path = self.project.evaluate_path(final_path)

        if not self.meta.overwrite and os.path.exists(final_path):
            print("Bundle already exists: " + final_path)
            sys.exit(1)

        self.create_skeleton()
        self.create_pkglist()
        self.copy_plist()

        # Note: could move this to xml file...
        #Path("${prefix}/lib/charset.alias").copy_target(self.project)

        # Main binary
        main_binary_path = self.project.get_main_binary()
        source = self.project.evaluate_path(main_binary_path.source)
        if not os.path.exists(source):
            print("Cannot find main binary: " + source)
            sys.exit(1)

        self.binaries_to_copy.append(main_binary_path)
        self.binaries_to_copy.extend(self.project.get_binaries())
        self.resolve_library_dependencies()
        self.binaries_to_copy.remove(main_binary_path)

        # Additional binaries (executables, libraries, modules)
        self.resolve_library_dependencies()
        self.copy_binaries()

        # Gir and Typelibs
        self.install_gir()

        # Data
        for path in self.project.get_data():
            path.copy_target(self.project)

        # Translations
        self.copy_translations()

        # Frameworks
        frameworks = self.project.get_frameworks()
        for path in frameworks:
            dest = path.copy_target(self.project)
            self.frameworks.append(dest)

        self.copy_icon_themes()

        self.create_gtk_immodules_setup()
        self.create_gdk_pixbuf_loaders_setup()

        main_binary_path.copy_target(self.project)

        launcher_script = self.project.get_launcher_script()
        if launcher_script:
            launcher_script.copy_target(self.project)

        if self.meta.overwrite:
            self.recursive_rm(final_path)
        shutil.move(self.project.get_bundle_path(), final_path)

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print(f'Usage: {sys.argv[0]} <bundle description file>')
        sys.exit(2)

    if not os.path.exists(sys.argv[1]):
        print(f'File {sys.argv[1]} does not exist')
        sys.exit(2)

    project = Project(sys.argv[1])
    bundler = Bundler(project)

    bundler.run()


"""
Author: Paloma Arellano, arellanp@purdue.edu
Assignment: 10.1 - Monthly Sales
Date: 11/19/2022

Description:
    This program asks the user for monthly sales data and then plots
    the sales as a pie chart.

Contributors:
    Name, login@purdue.edu [repeat for each]

My contributor(s) helped me:
    [ ] understand the assignment expectations without
        telling me how they will approach it.
    [ ] understand different ways to think about a solution
        without helping me plan my solution.
    [ ] think through the meaning of a specific error or
        bug present in my code without looking at my code.
    Note that if you helped somebody else with their code, you
    have to list that person as a contributor.

Academic Integrity Statement:
    I have not used source code obtained from any unauthorized
    source, either modified or unmodified; nor have I provided
    another student access to my code.  The project I am
    submitting is my own original work.
"""

"""Import additional modules below this line (starting with unit 6)."""
import calendar
import matplotlib.pyplot as plt

"""Write new functions below this line (starting with unit 4)."""

def main():
    fig, ax = plt.subplots()        # subplot
    month = ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')  # month vals
    col = ['#4D4038', '#BAA892', '#5B6870', '#6E99B4', '#A3D6D7', '#085C11', '#849E2A', '#C3BE0B', '#E9E45B', '#6B4536', '#B46012', '#FF9B1A']  # color vals
    vals = []   # user input vals
    for i in range(1, 13):
        numVal = input("Enter the sales for " + calendar.month_name[i] + ": ")  # user input for each month
        vals.append(numVal)     # adds value to vals list

    ax.pie(vals, colors=col, labels=month)  # plots piechart
    ax.set_title('Monthly Sales Values')    # chart title
    plt.show()                              # plots the piechart and title

"""Do not change anything below this line."""
if __name__ == "__main__":
    main()


# Spark UI: localhost:4040
import findspark
findspark.init('C:\\Spark')

from pyspark.sql import SparkSession
from pyspark.sql.types import Row
from pyspark.sql.types import *
from pyspark.sql.functions import *

spark = SparkSession \
    .builder \
        .appName('PySpark Application') \
            .master('local[*]') \
                .getOrCreate()

# df_rows = [Row(id=1, name='Balaji', city='Hyderabad'), Row(id=2, name='Pari', city='Chennai')]
# df = spark.createDataFrame(df_rows)
# df.show()

spark.sparkContext.setLogLevel('ERROR')

KAFKA_BOOTSTRAP_CONS = 'localhost:9092'
KAFKA_TOPIC = 'msgtopic1'
df = spark.readStream\
    .format('kafka')\
        .option('kafka.bootstrap.servers', KAFKA_BOOTSTRAP_CONS)\
            .option('subscribe', KAFKA_TOPIC)\
                .option('startingOffsets', 'latest') \
                    .load()

print(df.isStreaming)
df.printSchema()

data_df = df.selectExpr("CAST(value AS STRING)", "timestamp")

# Define a Schema for the data

data_schema = StructType() \
    .add("transaction_id", StringType()) \
        .add("transaction_card_type", StringType()) \
            .add("transaction_amount", StringType()) \
                .add("transaction_datetime", StringType())

data_df1 = data_df.select(from_json(data_df['value'], data_schema).alias('transactions'), "timestamp")

data_df2 = data_df1.select('transactions.*', 'timestamp')

data_df3 = data_df2.groupBy('transaction_card_type') \
    .agg({'transaction_amount': 'max'}) \
        .select('transaction_card_type', col('max(transaction_amount)').alias('max transaction')
        )
write_query = data_df3 \
    .writeStream \
        .format('console').outputMode('complete').option('checkpointLocation', './KafkaStreaming/checkpoint-loc-kafka').option('truncate', 'false') \
            .start()

write_query.awaitTermination()
spark.stop()


import tkinter as t
def reset():
	e1.delete(0,t.END)
	e2.delete(0,t.END)
	e3.delete(0,t.END)
	e4.delete(0,t.END)
	e5.delete(0,t.END)
	e6.delete(0,t.END)

def encode():
	s=e1.get()
	s1=int(e2.get())
	c=list(s)#list of all  individual characters in string s

	l=[]#to store the cipher text characters

	for i in c:#taking every character(i) in list c
		if(ord(i)>=97 and ord(i)<=122): #a-b
			x=(ord(i)+s1-97)%26
			l.append(chr(x+97))
		elif(ord(i)>=65 and ord(i)<=90): #A-Z
			x=(ord(i)+s1-65)%26
			l.append(chr(x+65))
		elif(ord(i)>=48 and ord(i)<=57): #0-9
			x=(ord(i)+s1-48)%10
			l.append(chr(x+48))
		elif(ord(i)>=58 and ord(i)<=64): #( : , ; , < , = , > , ? , @ )
			x=(ord(i)+s1-58)%7
			l.append(chr(x+58))
		elif(ord(i)>=32 and ord(i)<=47): #(space, ! , " ,#,$,%,&, ' ,(,),*,+, , , - , . , / )
			x=(ord(i)+s1-32)%16
			l.append(chr(x+32))
		elif(ord(i)>=123 and ord(i)<=126): #( { , | , } , ~ )
			x=(ord(i)+s1-123)%4
			l.append(chr(x+123))
		else:
			if(ord(i)>=91 and ord(i)<=96): #( [ , \ , ] , ^ , _ , ` )
				x=(ord(i)+s1-91)%6
				l.append(chr(x+91))

	mess="".join(l)#join the characters in list l and convert into string
	e3.delete(0,t.END)
	e3.insert(0,mess)
	e4.delete(0,t.END)
	e4.insert(0,mess)
def decode():
	m=e3.get()
	l=list(m)
	l2=[]#to store decoded text characters
	s2=int(e5.get())

	for i in l:#taking every character(i) in list c
		if(ord(i)>=97 and ord(i)<=122): #a-b
			x=(ord(i)-s2-97)%26
			l2.append(chr(x+97))
		elif(ord(i)>=65 and ord(i)<=90): #A-Z
			x=(ord(i)-s2-65)%26
			l2.append(chr(x+65))
		elif(ord(i)>=48 and ord(i)<=57): #0-9
			x=(ord(i)-s2-48)%10
			l2.append(chr(x+48))
		elif(ord(i)>=58 and ord(i)<=64): #( : , ; , < , = , > , ? , @ )
			x=(ord(i)-s2-58)%7
			l2.append(chr(x+58))
		elif(ord(i)>=32 and ord(i)<=47): #(space, ! , " ,#,$,%,&, ' ,(,),*,+, , , - , . , / )
			x=(ord(i)-s2-32)%16
			l2.append(chr(x+32))
		elif(ord(i)>=123 and ord(i)<=126): #( { , | , } , ~ )
			x=(ord(i)-s2-123)%4
			l2.append(chr(x+123))
		else:
			if(ord(i)>=91 and ord(i)<=96): #( [ , \ , ] , ^ , _ , ` )
				x=(ord(i)-s2-91)%6
				l2.append(chr(x+91))
	e6.delete(0,t.END)
	e6.insert(0,"".join(l2))
frame=t.Tk()
frame.title("PROJECT")
l1=t.Label(frame,text="MESSAGE",bg="red")
l2=t.Label(frame,text="SHIFT KEY",bg="red")
l3=t.Label(frame,text="CIPHER TEXT",bg="red")

e1=t.Entry(frame,font=('Arial',11))
e2=t.Entry(frame,font=('Arial',11))
e3=t.Entry(frame,font=('Arial',11))

b1=t.Button(frame,text="ENCODE",command=encode,bg="green")

l1.place(x=100,y=100,width=70,height=30)
l2.place(x=100,y=140,width=70,height=30)
l3.place(x=100,y=180,width=70,height=30)

e1.place(x=200,y=100,width=200,height=30)
e2.place(x=200,y=140,width=70,height=30)
e3.place(x=200,y=180,width=200,height=30)

b1.place(x=150,y=220,width=60,height=30)

l4=t.Label(frame,text="CIPHER TEXT",bg="red")
l5=t.Label(frame,text="SHIFT KEY",bg="red")
l6=t.Label(frame,text="DECODED TEXT",bg="red")

e4=t.Entry(frame,font=('Arial',11))
e5=t.Entry(frame,font=('Arial',11))
e6=t.Entry(frame,font=('Arial',11))

l4.place(x=450,y=100,width=83,height=30)
l5.place(x=450,y=140,width=83,height=30)
l6.place(x=450,y=180,width=83,height=30)

e4.place(x=550,y=100,width=200,height=30)
e5.place(x=550,y=140,width=70,height=30)
e6.place(x=550,y=180,width=200,height=30)

b2=t.Button(frame,text="DECODE",command=decode,bg="green")
b2.place(x=500,y=220,width=60,height=30)

b3=t.Button(frame,text="RESET",bg="skyblue",command=reset)
b3.place(x=320,y=280,width=60,height=30)

frame.mainloop()


# -*- coding: utf-8 -*-
"""
Created on Mon Aug 27 22:52:19 2018

@author: LTF
"""

import numpy as np
import matplotlib.pyplot as plt

plot_x = np.linspace(-1, 6, 140)
plot_y = (plot_x - 2.5)**2 - 1
plt.plot(plot_x, plot_y)

"""求导函数"""
def dJ(theta):
    return 2*(theta - 2.5)

def J(theta):
    try:
        return (theta - 2.5)**2 -1
    except:
        return float('inf')

#学习率
eta = 0.1
#精度
"""
epsilon = 1e-8
theta = 0.0
theta_history = [theta]
while True:
    gradient = dJ(theta)
    last_theta = theta
    theta = theta - eta * gradient
    theta_history.append(theta)

    if(abs(J(theta) - J(last_theta)) < epsilon):
        break

print(theta)
print(J(theta))
print(theta_history)

plt.plot(np.array(theta_history), J(np.array(theta_history)),color="r", marker="+")
plt.show()
"""
def gardient_descent(initial_theta, eta, n_iters = 1e4, epsilon=1e-8):
    theta = initial_theta
    theta_history.append(initial_theta)
    i_iter = 0

    while i_iter < n_iters:
        gradient = dJ(theta)
        last_theta = theta
        theta = theta - eta * gradient
        theta_history.append(theta)

        if(abs(J(theta) - J(last_theta)) < epsilon):
            break

        i_iter += 1

    return theta

def plot_theta_history():
    plt.plot(plot_x, J(plot_x), color="b")
    plt.plot(np.array(theta_history), J(np.array(theta_history)), color="r", marker="+")
    plt.show()

eta = 0.09
theta_history=[]
gardient_descent(0., eta)
plot_theta_history()
print(len(theta_history))

# 随机题第下降法
np.random.seed(666)
x = 2 * np.random.random(size=100)
y = x * 3. + 4. + np.random.normal(size=100) #正态分布

X = x.reshape(-1, 1) # 100行 1列

def dj_sgd(theta,X_b_i,y_i):
    return X_b_i.dot(X_b_i.dot(theta) - y_i) * 2

def sgd(X_b, y, initial_theta, n_iters):
    t0 = 5
    t1 = 50
    def learning_rate(t):
        return t0/(t+t1)

    theta = initial_theta
    for cur_iter in range(n_iters):
        rand_i = np.random.randint(len(X_b))
        gradient = dj_sgd(theta, X_b[rand_i], y[rand_i])
        theta = theta - learning_rate(cur_iter) * gradient

    return theta


import pytest
from html.parser import HTMLParser
import sys
import os
import json
import time
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
from services.api_gateway import api_gateway
from services.drone_information import drone_information
from scripts.util import config
from common import start_server, stop_server, __run_drone_information

class DataHTMLParser(HTMLParser):

    parsed_data = []

    def handle_data(self, data):
        data = data.strip()
        if data:
            self.parsed_data.append(data)

@pytest.fixture
def htmlparser():
    yield DataHTMLParser()

@pytest.fixture
def client():
    api_gateway.app.config['TESTING'] = True
    api_gateway.config = json.load(open(api_gateway.__services_config_file))
    client = api_gateway.app.test_client()
    yield client

@pytest.fixture
def drone_information_server():
    server = start_server(__run_drone_information, config['drone_information']['port'])
    yield server
    stop_server(server)

@pytest.fixture
def drone_data_points():
    yield [{
        'id': 919,
        'lat': 55.37000,
        'lon': 10.43000,
        'alt': 00.00000,
        'time': 1524231287
    },
    {
        'id': 919,
        'lat': 55.38050,
        'lon': 10.43000,
        'alt': 100.00000,
        'time': 1524231299
    }]

def epoch_to_datetime(epoch):
    return time.strftime('%d %b %Y, %H:%M:%S', time.gmtime(epoch))

def test_routes_service_unavailable(client):
    response = client.get('/routes')
    assert response.status_code == 503
    assert response.data.decode().strip() == 'Drone information service unavailable'

def test_routes(client, drone_data_points, htmlparser, drone_information_server):
    post_response = client.post('/routes', json=drone_data_points)
    routeid = post_response.data.decode().strip()
    assert post_response.status_code == 201

    get_response = client.get('/routes')
    assert get_response.status_code == 200
    htmlparser.feed(get_response.data.decode())

    droneid = str(drone_data_points[0]['id'])
    start_time = epoch_to_datetime(drone_data_points[0]['time'])
    end_time = epoch_to_datetime(drone_data_points[-1]['time'])
    assert all(item in htmlparser.parsed_data for item in (droneid, start_time, end_time))

    delete_response = client.delete('/routes/{}'.format(routeid))
    assert delete_response.status_code == 200
    assert delete_response.data.decode().strip() == routeid

def test_routes_by_routeid(client, drone_data_points, drone_information_server):
    post_response = client.post('/routes', json=drone_data_points)
    routeid = post_response.data.decode().strip()
    assert post_response.status_code == 201

    get_response = client.get('/routes/{}'.format(routeid))
    get_response_data = json.loads(get_response.data)
    assert get_response.status_code == 200

    for i in range(len(drone_data_points)):
        drone_data_points[i]['id'] = str(drone_data_points[i]['id'])
        assert all((key, value) in get_response_data[i].items() for (key, value) in drone_data_points[i].items())

    delete_response = client.delete('/routes/{}'.format(routeid))
    assert delete_response.status_code == 200
    assert delete_response.data.decode().strip() == routeid

if __name__ == '__main__':
    pytest.main()


import os
from utils import Scope
from mytypes.types import AudioFeaturesObject, PlaylistObject
from spotipy_client import SpotipyClient

def bpm_sorter(audio_feature: AudioFeaturesObject, threshold: int | None = None) -> float:
    bpm = audio_feature.tempo
    if threshold is not None and audio_feature.tempo >= threshold:
        bpm /= 2
    return bpm

def duplicate_playlist_sorted_by_bpm(
    client: SpotipyClient,
    playlist: str,
    name: str = '',
    threshold: int | None = None,
    dry_run: bool | int = False,
) -> None:

    playlist: PlaylistObject = client.playlist(playlist_id=playlist)

    songs_by_uris = {item.track.uri: item.track for item in playlist.tracks.items}

    audio_features: list[AudioFeaturesObject] = client.audio_features(tracks=songs_by_uris.keys())

    sorted_audio_features = sorted(
        audio_features,
        key=lambda s: bpm_sorter(audio_feature=s, threshold=threshold),
    )
    sorted_audio_features_uris = [item.uri for item in sorted_audio_features]

    for i in sorted_audio_features:
        print(i.tempo, songs_by_uris[i.uri].name)

    plname = name or f'{playlist.name} - by bpm'
    if not dry_run:
        new_pl: PlaylistObject = client.user_playlist_create(user=user, name=plname)
        client.playlist_add_items(playlist_id=new_pl.uri, items=sorted_audio_features_uris)
    print(f'Created playlist: {plname}')

if __name__ == '__main__':
    scopes = [Scope.playlist_modify_private, Scope.playlist_modify_public]

    slow_wcs_playlist, slow_t = 'https://open.spotify.com/playlist/0w0YxOMjvKUFS215VPIK6X?si=af0f0880708744c8', 100
    inputpl = 'https://open.spotify.com/playlist/5ISmAZvdFQob5nEZgH9ufI?si=4ee7af478b0b4a38'
    test = 'https://open.spotify.com/playlist/0zTGrbhMKJcOnCnAn55vGZ?si=34295a468ad74e65'
    fast_wcs = 'https://open.spotify.com/playlist/5lTsNph8TgIrTR7znoGfGk?si=49125ed39fe7483e'
    user = os.environ['USER']

    sp = SpotipyClient(username=user, scope=scopes)

    USING_PL = slow_wcs_playlist
    THRESHOLD = None
    # THRESHOLD = 170
    THRESHOLD = slow_t
    DRY_RUN = 1

    duplicate_playlist_sorted_by_bpm(client=sp, playlist=USING_PL, threshold=THRESHOLD, dry_run=DRY_RUN)


import sys
import heapq
sys.stdin = open('bj14235_in.txt', 'r')

charge = []
n = int(input())

for i in range(n):
    data = list(map(int, input().split()))

    if len(data) == 1:
        if len(charge) == 0:
            print(-1)
        else:
            print(-heapq.heappop(charge))
    else:

        iteration = data[0]
        for j in range(1,iteration+1):
            heapq.heappush(charge, -data[j])


#!/usr/bin/python
'''
A linear regression learning algorithm example using TensorFlow library.
Author: Aymeric Damien
Project: https://github.com/aymericdamien/TensorFlow-Examples/
'''
from __future__ import print_function
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
a = tf.constant(10)
b = tf.constant(32)
print(sess.run(a + b))


#measure total height of pile as function of time

import numpy as np

import matplotlib.pyplot as plt

import pickle as p

import OS

l = [4, 8, 16,32,64,128,256]

M = 10

# need to average heights over realisations,
#each realisation average the height of all at each time

ha = 0

#avg height
ht = []

tth = []

tdt = []

tdn = []

for q in l:

    #for each realisation take the height at the time

    #first of all open all realisations and use the time check to be the minimum of all
    #realisations, each run will have a slightly different time so to use in loop
    #use the minimum as this will work for all

    real = []

    #open all files

    for k in range(M):

        filein =  open(f"{q}_{k}", "rb")

        real.append(p.load(filein))

    #t_min = real[0][-1][3]

    tloop = range(0,100000,1)#range(int(1.5*t_min))

    for i in tloop: #each time as each entry corresponds to a time

        ha = 0

        ttc = 0

        for k in real:

            ha += k[i][1]/M

            ttc += k[-1][3]/M

        ht.append(ha) # avg added to list

        tth.append(i)

    #data collapse dividing by system size and time by critical time

    #plt.plot(np.array(tth)/ttc,np.array(ht)/q,label = q)#,s=1)

    ht[0] = 0 # forgot to add initial sandbox when saving data

    plt.rcParams.update({'font.size': 32})

    plt.loglog(np.array(tth)/q**2,np.array(ht)/q,label = q)

    print('done')

    ht.clear()

    tth.clear()
plt.rcParams.update({'font.size': 20})
plt.legend()
plt.rcParams.update({'font.size': 32})
plt.xlabel('Number of grains added/$L^2$')

plt.ylabel('Height of pile')

plt.title('Pile heights vs time scaled by $L^2$')

plt.axvline(x=1,linestyle = '--')

plt.show()


import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--data_dir', type=str, default='../../data/train_cv/fold_1')
    parser.add_argument('--model', type=str, choices=['lstm', 'tree'], default='tree')
    parser.add_argument('--preds_dir', type=str, default='../../data/train_cv/fold_1/preds.csv')
    arg = parser.parse_args()

    CrossValidate(datapath=arg.data_dir, model_kind=arg.model, preds_dir=arg.preds_dir)


import os

from xdg import DesktopEntry

def get_desktop_entry_path(appname):
    if os.path.isabs(appname):
        return DesktopEntry(appname)

    dirs = (
        os.path.expanduser('~/.local/share/applications'),
        '/usr/local/share/applications',
        '/usr/share/applications',
    )

    # check if it has an extension and strip it
    if os.path.splitext(appname)[1][1:] in ('.desktop',):
        appname = os.path.splitext(appname)[0]

    for d in dirs:
        if not os.path.isdir(d):
            continue

        for f in os.listdir(d):
            filepath = os.path.join(d, f)
            if not os.path.isfile(filepath):
                continue

            if f != f'{appname}.desktop':
                continue

            return DesktopEntry(filepath)


import sys
from subprocess import Popen
from time import sleep

user = sys.argv[1]
symbol = sys.argv[2]
path_to_config = sys.argv[3]

max_n_restarts = 30

restart_k = 0

while True:
    try:
        print(f"\nStarting {user} {symbol} {path_to_config}")
        p = Popen(f"{sys.executable} passivbot.py {user} {symbol} {path_to_config} --nojit", shell=True)
        p.wait()
        restart_k += 1
        if restart_k > max_n_restarts:
            print('max n restarts reached, aborting')
            break
        for k in range(30 - 1, -1, -1):
            print(f"\rbot stopped, attempting restart in {k} seconds", end='   ')
            sleep(1)
    except KeyboardInterrupt:
        break


from django.urls import path, include
from . import views

urlpatterns = [
    path('create', views.create, name='create'),
    path('<int:tweet_id>', views.detail, name='view'),
    path('add_comment/<int:tweet_id>', views.add_comment, name='add_comment'),
    path('edit/<int:tweet_id>', views.edit_post, name='edit_post'),
    path('delete/<tweet_id>', views.delete, name='delete'),
    path('messages', views.messages, name='message'),
    path('messages/<user>/', views.message_detail, name='message'),
    path('post/<user>', views.posts, name='post'),
    path('search', views.search, name='search')
]


from flask import Flask, render_template
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy, BaseQuery
from contextlib import contextmanager
from flask_mail import Mail

__author__ = "TuDi"
__date__ = "2018/12/17 下午6:32"

# 实例化 Flask
app = Flask(__name__)

# 加载配置文件
app.config.from_object("app.secure")
app.config.from_object("app.setting")

class SQLAlchemy(_SQLAlchemy):
    @contextmanager
    def auto_commit(self):
        try:
            yield
            self.session.commit()
        except Exception as e:
            self.session.rollback()
            raise e

class Query(BaseQuery):
    def filter_by(self, **kwargs):
        if "status" not in kwargs.keys():
            kwargs["status"] = 1
        return super().filter_by(**kwargs)

# 注册 SQLAlchemy
db = SQLAlchemy(app, query_class=Query)

# 注册用户登录管理插件 LoginManager
login_manager = LoginManager(app)
login_manager.login_view = "web.login"
login_manager.login_message = "请先登录或注册"

# 注册发送邮件插件 Mail
mail = Mail(app)

# 注册 web 蓝图
from app.web import web

app.register_blueprint(web)


# data = list(map(int, input().split()))
data = [8, 9, 15, 12, 14, 7, 9, 16, 22, 17, 22]
data.sort()

print (data[-3])

# largest = max(data)
# if largest != data[-2]:
#     second = data[-2]
#     if  second != data[-3]:
#         third = data[-3]

# n = data.count(max(data))
# second = data[-(n+1)]
# m= data.count(second)
# third = data[-(n+m+1)]
# print(third)


import requests
import os
import json

SM_API_URL = "https://api.spritmonitor.de/v1"

# To set your enviornment variables in your terminal run the following line:
# export 'BEARER_TOKEN'='<your_bearer_token>'
# export 'APP_TOKEN'='<your_app_token>'
bearer_token = os.environ.get("BEARER_TOKEN")
app_token = os.environ.get("APP_TOKEN")

def bearer_auth(r):
    """
    Set authorization header
    """

    r.headers["Authorization"] = f"Bearer {bearer_token}"
    r.headers["Application-ID"] = app_token
    r.headers["User-Agent"] = "Python Spritmonitor API Access Example"
    return r

def connect_to_sm_rest(url):
    """
    Send request to Spritmonitor REST endpoint
    """
    respose = requests.request("GET", url, auth=bearer_auth)
    if respose.status_code != 200:
        raise Exception(
            "Request returned an error: {} {}".format(
                respose.status_code, respose.text
            )
        )
    return respose.json()

def get_vehicles():
    """
    Retrieve all vehicles from user
    """
    url = f"{SM_API_URL}/vehicles.json"
    vehicles = connect_to_sm_rest(url)
    return vehicles

def get_tanks(vehicle_id):
    """
    Retrieve tanks from vehicle with given id
    """
    url = f"{SM_API_URL}/vehicle/{vehicle_id}/tanks.json"
    tanks = connect_to_sm_rest(url)
    return tanks

def main():
    vehicles = get_vehicles()
    for vehicle in vehicles:
        tanks = get_tanks(vehicle['id'])
        print(json.dumps(vehicle, indent=4, sort_keys=True))
        print(json.dumps(tanks, indent=4, sort_keys=True))

if __name__ == "__main__":
    main()


time=int(input())
length=int(input())

inputNum=input()
numList=inputNum.split()
listNum=[]
for x in numList:
    listNum.append(int(x))
num=int(input())

group=0
temp=length
while(temp>0):
    temp-=num
    group+=1

endList=[]

for i in range(group-1):
    tempList=listNum[i*num:(i+1)*num]
    tempList.reverse()
    endList+=tempList

tempList=listNum[(group-1)*num:]
tempList.reverse()
endList+=tempList
endList.reverse()
print(*endList,end=" ")
print()


#%%

if __name__ == '__main__':
    import matplotlib
    matplotlib.use('Agg')

from cycler import cycler
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from argparse import Namespace

from virn.logging import Metrics
from virn.methods import OG, DualAvg, DualX, DualOpt
from virn.problems import KellyAuction, KellyAuction2D, KellyAuction4D, NoiseProfile
from virn.plot import plot_kelly, savefigs

#%% Least square (const. vs adaptive)
metrics_dict = {}
configs = [
    Namespace(adaptive=True, lr=1.0),
    Namespace(adaptive=False, lr=0.01),
]

for config in configs:
    kelly = KellyAuction4D()
    kelly.equilibrium = np.zeros(kelly.dim())
    noise_profile = NoiseProfile(sigma_abs=1.0, sigma_rel=0.0)

    T = 100000
    N  = 1
    X = 100 * np.ones((N, kelly.dim()))
    method = DualX(lr=config.lr, adaptive=config.adaptive)
    metrics = Metrics(T)

    for t in range(T):
        grad = X#kelly.grad(X)
        stoc_grad = noise_profile.add_noise(grad)
        X = method.step(X, stoc_grad)
        metrics.add('trajectory', X, t)
        metrics.add('grads', grad, t)
        metrics.add('stoc_grads', stoc_grad, t)

    metrics_dict[f'adapt={config.adaptive}'] = metrics

figs, axes = plot_kelly(kelly, metrics_dict, T, num_points=1000)
#savefigs("dim4_noise_compare", figs)


class newnode:
    def __init__(self,value):
        self.value = value
        self.left = None
        self.right = None

# Driver Code
if __name__ == '__main__':
	root = newnode(10)
	root.left = newnode(5)
	root.right = newnode(15)
	root.left.left = newnode(2)
	root.left.right = newnode(5)
	root.left.left.left = newnode(1)
	root.right.right = newnode(22)
	root.right.left = newnode(13)
	root.right.left.right = newnode(14)
	k = 12

# Avarage: O(log(n)) | O(log(n))
# Worst: O(n) time | O(n) space
# def findClosestValueInBst(tree, target):
#     return findClosestValueInBstHelper(tree,target, float("inf"))

# def findClosestValueInBstHelper(tree, target, closest):
#     if tree is None:
#         return closest
#     if abs(target - closest) > abs(target - tree.value):
#         return tree.value
#     if target < tree.value:
#         return findClosestValueInBstHelper(tree.left, target, closest)
#     elif target > tree.value:
#         return findClosestValueInBstHelper(tree.right, target, closest)
#     else:
#         return closest

# Avarage: O(log(n)) | O(log(n))
# Worst: O(n) time | O(1) space
def findClosestValueInBst(tree, target):
    return findClosestValueInBstHelper(tree,target, float("inf"))

def findClosestValueInBstHelper(tree, target, closest):
    currentNode = tree
    while currentNode is not None:
        if abs(target - closest) > abs(target - currentNode.value):
            closest = currentNode.value
        if target < currentNode.value:
           currentNode = currentNode.left
        elif target > currentNode.value:
           currentNode = currentNode.right
        else:
            break
    return closest

print(findClosestValueInBst(root, k))


from ff_iterator import FFIterator
from ff_prediction_network import FeedForwardPredictionNetwork
from ff_prediction_evaluator import FFPredictionEvaluator

from lstm_iterator import LstmIterator
from lstm_prediction_network import LstmPredictionNetwork
from lstm_prediction_evaluator import LstmPredictionEvaluator
from lstm_updater import LstmUpdater

import dataset as ds

from researchutils.chainer.training.extensions.slack_report import SlackReport
from researchutils.chainer.functions import average_k_step_squared_error
from researchutils import files
from researchutils.image import converter, preprocess, viewer
import researchutils.chainer.serializers as serializers

import chainer
from chainer.backends import cuda
from chainer import training
from chainer import optimizers
import numpy as np
import os
import sys
import argparse

IMAGE_HEIGHT = 210
IMAGE_WIDTH = 160

chainer.config.autotune = True
chainer.backends.cuda.set_max_workspace_size(10000000000)

def print_shape(array, msg=''):
    print(msg + 'shape: {}'.format(array.shape))

def verify_batch(batch, mean_image, args):
    examples = ds.concat_examples_batch(batch)
    (train_frame, train_actions) = examples['input']
    target_frames = examples['target']
    print_shape(train_frame, 'train frame shape: ')
    if args.lstm:
        assert train_frame[0][0].shape == (
            args.color_channels,
            IMAGE_HEIGHT,
            IMAGE_WIDTH)
        assert train_actions.shape == (
            args.batch_size, args.unroll_steps, args.num_actions, 1)
        assert target_frames[0][0].shape == (
            args.color_channels,
            IMAGE_HEIGHT,
            IMAGE_WIDTH)
    else:
        assert train_frame.shape == (
            args.batch_size,
            args.color_channels * args.skip_frames,
            IMAGE_HEIGHT,
            IMAGE_WIDTH)
        assert train_actions.shape == (
            args.batch_size, args.k_step, args.num_actions, 1)
        assert target_frames[0][0].shape == (
            args.color_channels,
            IMAGE_HEIGHT,
            IMAGE_WIDTH)

    images = []
    titles = []
    if args.lstm:
        for i in range(args.init_steps):
            images.append(converter.chw2hwc(train_frame[0][i] + mean_image))
            titles.append('step={}, actions={}, action={}'.format(
                i, train_actions[0][0], np.argmax(train_actions[0][0])))
        for i in range(args.k_step):
            images.append(converter.chw2hwc(target_frames[0][i] + mean_image))
            titles.append('target frame kstep={}'.format(i + 1))
    else:
        for i in range(args.skip_frames):
            images.append(
                train_frame[0][i * args.color_channels] + mean_image[0])
            titles.append('channel={}, actions={}, action={}'.format(
                i, train_actions[0][0], np.argmax(train_actions[0][0])))
        for i in range(args.k_step):
            images.append(converter.chw2hwc(target_frames[0][i] + mean_image))
            titles.append('target frame kstep={}'.format(i + 1))

    viewer.show_images(images=images, titles=titles)

def train_model(model, train_iterator, test_iterator, args):
    outdir = files.prepare_output_dir(base_dir='result-{}-kstep{}'.format('lstm' if args.lstm else 'ff', args.k_step),
                                      args=args, time_format='')
    if args.lstm:
        model = LstmPredictionEvaluator(
            model, k_step=args.k_step, init_steps=args.init_steps, unroll_steps=args.unroll_steps)
    else:
        model = FFPredictionEvaluator(model, k_step=args.k_step)
    print('optimizer learning rate is set to: {}'.format(args.learning_rate))
    optimizer = optimizers.Adam(alpha=args.learning_rate)
    optimizer.setup(model)
    if args.lstm:
        updater = LstmUpdater(
            iterator=train_iterator,
            optimizer=optimizer,
            converter=ds.concat_examples_batch,
            device=args.gpu)
    else:
        updater = training.updaters.StandardUpdater(
            iterator=train_iterator,
            optimizer=optimizer,
            converter=ds.concat_examples_batch,
            device=args.gpu)
    evaluation_trigger = (args.test_interval, 'iteration')
    trainer = training.Trainer(updater,
                               stop_trigger=(args.max_iterations, 'iteration'),
                               out=outdir)
    # trainer.extend(training.extensions.Evaluator(iterator=test_iterator,
    #                                             target=model,
    #                                             converter=ds.concat_examples_batch,
    #                                             device=args.gpu),
    #               trigger=evaluation_trigger)
    trainer.extend(training.extensions.LogReport(log_name="training_results",
                                                 trigger=evaluation_trigger))
    trainer.extend(training.extensions.snapshot(
        filename='snapshot_iter-{.updater.iteration}'),
        trigger=evaluation_trigger)
    trainer.extend(training.extensions.snapshot_object(
        model.predictor,
        filename='model_iter-{.updater.iteration}'),
        trigger=evaluation_trigger)
    entries = ['iteration', 'main/loss',
               'validation/main/loss', 'elapsed_time']
    trainer.extend(training.extensions.PrintReport(entries=entries))
    trainer.extend(SlackReport(args.token, entries=entries, channel='learning-progress'),
                   trigger=evaluation_trigger)
    trainer.extend(training.extensions.dump_graph('main/loss'))

    if files.file_exists(args.snapshot_file):
        print('loading snapshot from: {}'.format(args.snapshot_file))
        serializers.load_snapshot(args.snapshot_file, trainer)

    trainer.run()

def prepare_iterator(train_data_files, test_data_files, mean_image, args):
    print('creating frame iterator for train data')
    train_dataset = ds.prepare_dataset(train_data_files)
    print('train dataset len: {}'.format(len(train_dataset)))
    assert train_dataset[0][0].shape == (
        args.color_channels, IMAGE_HEIGHT, IMAGE_WIDTH)
    assert train_dataset[0][1].shape == (args.num_actions, 1)

    if args.lstm:
        train_iterator = LstmIterator(
            dataset=train_dataset,
            batch_size=args.batch_size,
            k_step=args.k_step,
            init_steps=args.init_steps,
            unroll_steps=args.unroll_steps,
            mean_image=mean_image)
    else:
        train_iterator = FFIterator(
            dataset=train_dataset,
            batch_size=args.batch_size,
            skip_frames=args.skip_frames,
            k_step=args.k_step,
            mean_image=mean_image)

    print('creating frame iterator for test data')
    test_dataset = ds.prepare_dataset(test_data_files)
    print('test dataset len: {}'.format(len(test_dataset)))
    if args.lstm:
        test_iterator = LstmIterator(
            dataset=test_dataset,
            batch_size=args.batch_size,
            k_step=args.k_step,
            init_steps=args.init_steps,
            unroll_steps=args.unroll_steps,
            mean_image=mean_image,
            repeat=False,
            shuffle=False)
    else:
        test_iterator = FFIterator(
            dataset=test_dataset,
            batch_size=args.batch_size,
            skip_frames=args.skip_frames,
            k_step=args.k_step,
            mean_image=mean_image,
            repeat=False,
            shuffle=False)

    if args.verify_batch:
        batch = train_iterator.next()
        assert len(batch) == args.batch_size
        verify_batch(batch=batch,
                     mean_image=mean_image,
                     args=args)
        train_iterator.reset()

    return train_iterator, test_iterator

def join_path(directory, filename):
    return os.path.join(directory, filename)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--dataset-dir', type=str, default='dataset')
    parser.add_argument('--mean-image-file', type=str,
                        default='mean_image.pickle')
    parser.add_argument('--token', type=str, default=None,
                        help='Slack client token')
    parser.add_argument('--max-iterations', type=int, default=1500000)
    parser.add_argument('--test-interval', type=int, default=10000)
    parser.add_argument('--color-channels', type=int, default=3)
    parser.add_argument('--skip-frames', type=int, default=4)
    parser.add_argument('--batch-size', type=int, default=32)
    parser.add_argument('--k-step', type=int, default=1)
    parser.add_argument('--num-actions', type=int, default=3)
    parser.add_argument('--gpu', type=int, default=0)
    parser.add_argument('--unroll-steps', type=int, default=20)
    parser.add_argument('--init-steps', type=int, default=11)
    parser.add_argument('--train-file-num', type=int, default=10)
    parser.add_argument('--test-file-num', type=int, default=1)
    parser.add_argument('--verify-batch', action='store_true',
                        help='show created batch')
    parser.add_argument('--lstm', action='store_true',
                        help='train lstm network')
    parser.add_argument('--learning-rate', type=float, default=1e-4)
    parser.add_argument('--model-file', type=str, default='')
    parser.add_argument('--snapshot-file', type=str, default='')

    args = parser.parse_args()

    print('loading mean image')
    mean_image = ds.load_mean_image(
        join_path(args.dataset_dir, args.mean_image_file))
    assert mean_image.shape == (args.color_channels, IMAGE_HEIGHT, IMAGE_WIDTH)

    if args.lstm:
        model = LstmPredictionNetwork()
    else:
        model = FeedForwardPredictionNetwork()

    if files.file_exists(args.model_file):
        print('loading model from: {}'.format(args.model_file))
        serializers.load_model(args.model_file, model)

    if not args.gpu < 0:
        model.to_gpu()

    train_data_files = [join_path(args.dataset_dir, 'train{}.pickle'.format(
        index)) for index in range(args.train_file_num)]
    test_data_files = [join_path(args.dataset_dir, 'test{}.pickle'.format(
        index)) for index in range(args.test_file_num)]

    train_iterator, test_iterator = prepare_iterator(
        train_data_files,
        test_data_files,
        mean_image,
        args)

    try:
        train_model(model, train_iterator, test_iterator, args=args)
    except:
        print('training finished with exception...')

if __name__ == '__main__':
    main()


import socket
import threading
import random

def hilo(address):
    cliente, direccion = address
    random_names = ["proplayer", "weeaboo", "normie", "pepe", "pleb", "topkek", "fritanga", "chileno promedio", "equisde"]
    with cliente:
        name= random.choice(random_names)
        print("Ha ingresado", name)
        while True:
            mensaje, addr = cliente.recvfrom(1024)
            if not mensaje:
                break
            msj = str(direccion[0]) + ":" + str(direccion[1])+ " --> " +mensaje.decode("utf-8")
            print(name, "dijo: ", mensaje.decode())
            cliente.sendall(msj.encode())

HOST = ''
PORT = 15000

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server:
    server.bind((HOST, PORT))
    print("Esperando una conexion...")
    server.listen(1)
    while True:
        threading.Thread(target=hilo, args=(server.accept(),)).start()


# Django
from django.conf import settings
from django.urls import reverse

class AvatarMixin:
    """Mixin for models with an avatar"""

    @property
    def avatar_url(self):
        url = self.avatar.url if self.avatar else self.default_avatar
        return url if url.startswith("http") else f"{settings.SQUARELET_URL}{url}"

class AdminLinkMixin:
    """Add an admin link to a view for staff"""

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        if self.request.user.is_staff:
            meta = self.object._meta
            context["admin_link"] = reverse(
                f"admin:{meta.app_label}_{meta.model_name}_change",
                args=(self.object.pk,),
            )
        return context


import streamlit as st
import plotly.graph_objects as graph
from plotly.subplots import make_subplots
import get_apidata
import sys
import plotly.express as px
from arima import ArimaModel
from io import StringIO
import ta

st.set_page_config(page_title='BlockChain Project',page_icon="❄",layout="wide")

st.markdown('<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">', unsafe_allow_html=True)

# Title
navbar = """

Crypto Price Prediction

using ARIMA model

  </button

"""
st.markdown(navbar, unsafe_allow_html=True)

st.write("---")

tuple_currencies, coinname = get_apidata.getListCoins()

def main():
    # Initialize columns and select boxes
    col1, col2 = st.columns(2)
    with col2:
      date_period = st.selectbox("Choose the prediction period",("1 DAY", "1 WEEK", "2 WEEKS", "1 MONTH"))

    # Get and display data
    with col1:
        coins = st.selectbox("Which coin would you like to predict?", tuple_currencies)
        with st.expander("Data"):
            name = "Coin: " + coinname.get(coins)
            st.subheader(name)
            data = get_apidata.getFinalData(coins, date_period)
            st.dataframe(data)

    # Get and display graph
    with col2:
        with st.expander("Graph"):
            data["MA20"] = ta.trend.sma_indicator(data['close'], window=20)
            data["MA50"] = ta.trend.sma_indicator(data['close'], window=50)
            data["MA100"] = ta.trend.sma_indicator(data['close'], window=100)

            fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
                        vertical_spacing=0.03,
                        row_width=[0.2, 0.7])

            fig.add_trace(graph.Candlestick(x=data.index,
                                  open=data['open'],
                                  high=data['high'],
                                  low=data['low'],
                                  close=data['close'], name="OHLC"),
                  row=1, col=1)
            fig.add_trace(graph.Line(x=data.index, y=data['MA20'], name="MA20", line=dict(
            color="purple",
            width=1)))
            fig.add_trace(graph.Line(x=data.index, y=data['MA50'], name="MA50", line=dict(
            color="yellow",
            width=1.5)))
            fig.add_trace(graph.Line(x=data.index, y=data['MA100'], name="MA100", line=dict(
            color="orange",
            width=2)))

            # Bar trace for volumes on 2nd row without legend
            fig.add_trace(graph.Bar(x=data.index, y=data['volume'], showlegend=False), row=2, col=1)

            fig.update(layout_xaxis_rangeslider_visible=False)

            fig.update_layout(autosize=False,width=780, height=540, margin=dict(l=50,r=50,b=50,t=50,pad=4))
            st.plotly_chart(fig)

    model = ArimaModel(data, date_period)

    st.write('---')
    col1, col2 = st.columns(2)

    with col1:
        period = st.slider("Choose additional period for the prediction", 1, 10, 1)
        if date_period == '1 DAY':
          out = 'DAYS'
        if date_period == '1 WEEK':
          if period == 1:
            out = 'WEEK'
          else:
            out = 'WEEKS'
        if date_period == '2 WEEKS':
          if period == 1:
            out = 'WEEK'
          else:
            out = 'WEEKS'
        if date_period == '1 MONTH':
          if period == 1:
            out = 'MONTH'
          else:
            out = 'MONTHS'
        new_data = "+"+str(period)+" "+out
        st.write(new_data)
    with col2:
        st.markdown(' ')

    st.write("Press the **START** button to show the model and forecast results.")

    if st.button("START"):
      st.warning(model.checkData())
      model.createDataReturn()
      st.write("Stationarity test")
      warn, ADF, p_value = model.checkStationarity()
      s1 = "ADF Statistic: " + str(ADF)
      s2 = "p-value: " + str(p_value)
      st.text(s1)
      st.text(s2)
      st.warning(warn)

      st.markdown("**Please wait...**")
      with st.expander("Summary SARIMAX Results"):
          result = model.displaySummary()

          old_stdout = sys.stdout
          sys.stdout = mystdout = StringIO()
          print(result.summary())
          sys.stdout = old_stdout
          st.text(mystdout.getvalue())

          pre = model.predict(period)

      col1, col2 = st.columns(2)

      with col1:
        st.write("Results of prediction:")
        st.dataframe(pre)

      with col2:
        fig_plot = px.line(data, y="close", x=data.index)
        fig_plot.add_trace(
            graph.Scatter(x=pre.index, y=pre['Mean_Price'], line=dict(color="red"), name="forecast"))
        fig_plot.add_trace(graph.Scatter(x=pre.index, y=pre['Upper_Price'], line=dict(color="green", dash='dash'), name="upper", ))
        fig_plot.add_trace(graph.Scatter(x=pre.index, y=pre['Lower_Price'], line=dict(color="green", dash='dash'), name="lower", ))
        st.plotly_chart(fig_plot)

        st.markdown('---')
if __name__ == '__main__':
    main()

title = """

Built by Joy Bugalia

"""
st.markdown(title, unsafe_allow_html=True)


#!/usr/bin/env python3
"""The structure of a GMA file, parsing and building"""

import json
import os
import subprocess
import sys
import tempfile
import webbrowser  # Useful for opening files
from binascii import crc32
from datetime import datetime
from struct import pack
from time import time

from construct import *

GMA_VERSION = b"\x03".decode("utf-8")

GMAFile = "all_file_meta" / Struct(
    "file_number" / Int32ul,
    "data"
    / IfThenElse(
        this.file_number != 0,
        "data"
        / Struct(
            "file_name" / CString("utf8"), "file_size" / Int64sl, "file_crc" / Int32ul
        ),
        Pass,
    ),
)

class FileContents(Adapter):
    def _encode(self, obj, context, path):
        return b"".join(obj)

    def _decode(self, obj, context, path):
        contents = []
        begin = 0
        for filemeta in context._.all_file_meta:
            # ignore the dummy file with file number 0
            if filemeta.file_number == 0:
                break

            size = filemeta.data.file_size
            contents.append(obj[begin : begin + size])
            begin += size

        return contents

def file_content_size(context):
    total = 0
    for filemeta in context.all_file_meta:
        if filemeta.file_number == 0:
            return total

        total += filemeta.data.file_size

GMAContents = "content" / Struct(
    "signature" / Const(b"GMAD"),
    "format_version" / PaddedString(1, "utf8"),
    "steamid" / Int64sl,
    "timestamp" / Int64sl,
    "required_content" / CString("utf8"),
    "addon_name" / CString("utf8"),
    "addon_description" / CString("utf8"),
    "addon_author" / CString("utf8"),
    "addon_version" / Int32sl,
    # For each file get the metadata
    "all_file_meta" / RepeatUntil(lambda x, lst, ctx: x["file_number"] == 0, GMAFile),
    "total_file_size" / Computed(lambda ctx: file_content_size(ctx)),
    "embedded_files"
    / LazyStruct("contents" / FileContents(Bytes(this._.total_file_size))),
)

GMAVerifiedContents = "GMAVerifiedContents" / Struct(
    GMAContents,
    "addon_crc" / Optional(Int32ul),
    "MagicValue" / Optional(Int8ul)
    # Don't enforce terminator. Some GMA files appear to have 0-padding after the magic value
    # Terminator
)

def build_gma(addon, file_list, addon_path="."):
    file_meta = []
    file_contents = []

    for i in range(0, len(file_list)):
        file_path = os.path.join(addon_path, file_list[i])

        with open(file_path, "rb") as f:
            contents = f.read()
            containeredData = Container(
                file_number=i + 1,
                data=Container(
                    file_name=file_list[i],
                    file_crc=crc32(contents) & 0xFFFFFFFF,
                    file_size=len(contents),
                ),
            )
            file_meta.append(containeredData)
            file_contents.append(contents)

    # Dummy end file
    file_meta.append(Container(file_number=0, data=Container()))

    container = Container()
    container.format_version = GMA_VERSION
    container.steamid = addon.getsteamid()
    container.timestamp = int(time())
    container.required_content = b"".decode("utf-8")
    container.addon_name = addon.gettitle()
    container.addon_description = addon.get_description_json()
    container.addon_author = addon.getauthor()
    container.addon_version = addon.getversion()
    container.all_file_meta = file_meta
    container.embedded_files = {"contents": file_contents}

    return GMAContents.build(container)

def write(addon, destination_path="."):
    file_list = addon.getfiles()
    addon_path = addon.getpath()
    gma = build_gma(addon, file_list, addon_path)

    crc = crc32(gma) & 0xFFFFFFFF

    file_name, extension = os.path.splitext(destination_path)
    destination = (
        extension and destination_path or os.path.join(destination_path, "out.gma")
    )

    # Force .gma extension
    destination = os.path.splitext(destination)[0] + ".gma"

    with open(destination, "wb") as file:
        file.write(gma)
        file.write(pack("<I", crc))

def extract(file_path, destination_path, fil=set()):
    with open(file_path, "rb") as file:
        gma = GMAVerifiedContents.parse_stream(file)

        for i in range(0, len(gma.content.all_file_meta) - 1):
            meta = gma.content.all_file_meta[i]
            gma_file_name = meta.data.file_name

            # Discontinue extracting this file if it's not in the filter
            if fil:
                for prefix in fil:
                    if gma_file_name.startswith(prefix):
                        # Remove prefix, so it won't create all subfolders
                        strip, _ = os.path.split(prefix)
                        if not strip:
                            break

                        gma_file_name = gma_file_name[len(strip) + 1 :]
                        break
                else:
                    continue

            file_name = os.path.join(destination_path, gma_file_name)
            file_folder = os.path.dirname(file_name)

            if not os.path.exists(file_folder):
                os.makedirs(file_folder)

            print(file_name)

            with open(file_name, "wb") as output:
                output.write(gma.content.embedded_files.contents[i])

def openFiles(gma_path, fil):
    with open(gma_path, "rb") as file:
        gma = GMAVerifiedContents.parse_stream(file)

        for i in range(0, len(gma.content.all_file_meta) - 1):
            meta = gma.content.all_file_meta[i]
            gma_file_name = meta.data.file_name
            for prefix in fil:
                if gma_file_name.startswith(prefix):
                    break
            else:
                continue

            _, filename = os.path.split(gma_file_name)

            print('Extracting "%s"' % filename)

            prefix, extension = os.path.splitext(filename)
            # Don't delete, otherwise it'll be deleted before it gets opened
            with tempfile.NamedTemporaryFile(
                prefix=prefix, suffix=extension, delete=False
            ) as output:
                output.write(gma.content.embedded_files.contents[i])
                if sys.platform == "darwin":
                    subprocess.call(["open", output.name])
                else:
                    webbrowser.open(output.name)

def getfiles(file_path):
    """Get the list of files that exist in the GMA file"""
    with open(file_path, "rb") as file:
        gma = GMAVerifiedContents.parse_stream(file)

    res = []
    for i in range(0, len(gma.content.all_file_meta) - 1):
        res.append(gma.content.all_file_meta[i].data.file_name)

    return res

gmaStr = """crc                   = {crc}
Magic value           = {magic}
format version        = {format_version!r}
Steam ID              = {steamid}
Time created          = {timestamp}
required content      = "{required_content}"
addon name            = "{addon_name}"
addon description     = "{addon_description}"
addon author          = "{addon_author}"
addon version         = {addon_version}

Files:
{files}
"""

filemetaStr = "{name} ({size}, crc: {crc})"

def sizeof_simple(num):
    n = num
    if num < 1024:
        return "%.0f bytes" % num

    for x in ["bytes", "KB", "MB", "GB"]:
        if num < 1024.0:
            return "%.0f %s" % (num, x)
        num /= 1024.0
    return "%.0f %s" % (num, "TB")

def sizeof_fmt(num):
    if num < 1024:
        return "%.0f bytes" % num

    size = sizeof_simple(num)

    return "%s, %s bytes" % (size, num)

def dump(file_path):
    with open(file_path, "rb", 0) as file:
        gma = GMAVerifiedContents.parse_stream(file)

        files = []

        for filemeta in gma.content.all_file_meta:
            if filemeta.file_number == 0:
                break

            files.append(
                filemetaStr.format(
                    name=filemeta.data.file_name,
                    size=sizeof_fmt(filemeta.data.file_size),
                    crc=filemeta.data.file_crc,
                )
            )

        return gmaStr.format(
            crc=gma.addon_crc,
            magic=gma.MagicValue,
            format_version=gma.content.format_version,
            steamid=gma.content.steamid,
            timestamp=datetime.fromtimestamp(int(gma.content.timestamp)).strftime(
                "%Y-%m-%d %H:%M:%S"
            ),
            required_content=gma.content.required_content,
            addon_name=gma.content.addon_name,
            addon_description=gma.content.addon_description,
            addon_author=gma.content.addon_author,
            addon_version=gma.content.addon_version,
            files="\n".join(files),
        )

def gmaInfo(file_path):
    res = dict()
    with open(file_path, "rb", 0) as file:
        gma = GMAVerifiedContents.parse_stream(file)

        res["files"] = []
        res["crc"] = gma.addon_crc
        res["magic"] = gma.MagicValue
        res["format_version"] = gma.content.format_version
        res["steamid"] = gma.content.steamid
        res["timestamp"] = int(gma.content.timestamp)
        res["required_content"] = gma.content.required_content
        res["addon_name"] = gma.content.addon_name
        res["addon_description"] = gma.content.addon_description
        res["addon_author"] = gma.content.addon_author
        res["addon_version"] = gma.content.addon_version

        try:
            data = json.loads(res["addon_description"])
            res["description"] = data["description"]
            res["tags"] = data["tags"]
            res["type"] = data["type"]
        except Exception:
            pass

        for filemeta in gma.content.all_file_meta:
            if filemeta.file_number == 0:
                break

            res["files"].append(
                {
                    "name": filemeta.data.file_name,
                    "size": sizeof_fmt(filemeta.data.file_size),
                    "puresize": filemeta.data.file_size,
                    "crc": filemeta.data.file_crc,
                }
            )

        return res


import transformers
from datasets import load_dataset
import evaluate
from transformers import Seq2SeqTrainer
# import wandb

# load our robot commands dataset
dataset = load_dataset('ezishiri/robot_commands')

print(dataset)

# import nltk
# nltk.download('punkt')
import string
from transformers import AutoTokenizer

model_checkpoint = "t5-base"
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint, model_max_length=512)

# BELOW IS CODE TAKEN FROM https://medium.com/nlplanet/a-full-guide-to-finetuning-t5-for-text2text-and-building-a-demo-with-streamlit-c72009631887

# NEED TO FIX AND CHANGE FOR MY USECASE (less data cleaning, only need to remove \n at some point, but for now should be fine

prefix = "translate command utterance to logical form: " # need prefix for good performance with t5
max_input_length = 512
max_target_length = 512

# def clean_text(text):
#   sentences = nltk.sent_tokenize(text.strip())
#   sentences_cleaned = [s for sent in sentences for s in sent.split("\n")]
#   sentences_cleaned_no_titles = [sent for sent in sentences_cleaned
#                                  if len(sent) > 0 and
#                                  sent[-1] in string.punctuation]
#   text_cleaned = "\n".join(sentences_cleaned_no_titles)
#   return text_cleaned

def preprocess_data(examples):
  texts_cleaned = [text for text in examples["utterance"]]
  inputs = [prefix + text for text in texts_cleaned]
  model_inputs = tokenizer(inputs, max_length=max_input_length, truncation=True)

  # Setup the tokenizer for targets
  with tokenizer.as_target_tokenizer():
    labels = tokenizer(examples["logical_form"], max_length=max_target_length,
                       truncation=True)

  model_inputs["labels"] = labels["input_ids"]
  return model_inputs

tokenized_datasets = dataset.map(preprocess_data,
                                                 batched=True)

from transformers import AutoModelForSeq2SeqLM, DataCollatorForSeq2Seq, Seq2SeqTrainingArguments, Seq2SeqTrainer

batch_size = 8
model_name = "t5-base-robot-command-understanding"
model_dir = f"./{model_name}" # save the model in the models directory we are currently working in

args = Seq2SeqTrainingArguments(
    model_dir,
    evaluation_strategy="steps",
    eval_steps=100,
    logging_strategy="steps",
    logging_steps=100,
    save_strategy="steps",
    save_steps=200,
    learning_rate=4e-5,
    per_device_train_batch_size=batch_size,
    per_device_eval_batch_size=batch_size,
    weight_decay=0.01,
    save_total_limit=3,
    num_train_epochs=150,
    predict_with_generate=True,
    # fp16=True, # no fp16 for now while testing on my machine
    load_best_model_at_end=True,
    metric_for_best_model="exact_match",
    push_to_hub=True,
    # report_to="wandb"  no reporting for now, need to set up personal wandb account
)

data_collator = DataCollatorForSeq2Seq(tokenizer)

metric = evaluate.load("exact_match")

import numpy as np

def compute_metrics(eval_pred): # probably not going to work for exact match calculations
    predictions, labels = eval_pred
    decoded_preds = tokenizer.batch_decode(predictions, skip_special_tokens=True)

    # Replace -100 in the labels as we can't decode them.
    labels = np.where(labels != -100, labels, tokenizer.pad_token_id)
    decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True)

    # Compute ROUGE scores
    result = metric.compute(predictions=decoded_preds, references=decoded_labels,
                            use_stemmer=True)

    # Extract ROUGE f1 scores
    result = {key: value.mid.fmeasure * 100 for key, value in result.items()}

    # Add mean generated length to metrics
    prediction_lens = [np.count_nonzero(pred != tokenizer.pad_token_id)
                      for pred in predictions]
    result["gen_len"] = np.mean(prediction_lens)

    return {k: round(v, 4) for k, v in result.items()}

# Function that returns an untrained model to be trained
def model_init():
    return AutoModelForSeq2SeqLM.from_pretrained(model_checkpoint)

trainer = Seq2SeqTrainer(
    model_init=model_init,
    args=args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer,
    compute_metrics=compute_metrics
)

# trainer.train()
# trainer.push_to_hub


# pip3 install python-dotenv

import os
import logging
from dotenv import load_dotenv
from linebot import (
    LineBotApi, WebhookHandler
)
from datetime import datetime

load_dotenv()

# linebot msg api
Bot_ID = os.environ.get('Bot_ID')
Channel_access_token = os.environ.get('Channel_access_token')
Channel_secret =  os.environ.get('Channel_secret')

line_bot_api = LineBotApi(Channel_access_token)
handler = WebhookHandler(Channel_secret)
#print(os.environ.get('Channel_access_token'))

# db
db_path = 'sqlite:///' + f'{os.path.dirname(__file__)}/hiStaff.db'

# liff
LIFF_LINEPAY = 'https://liff.line.me/1656118882-gGKlpBvr'
LIFF_LINEPAY_REQ = 'https://liff.line.me/1656118882-RWMrlNJO'

# logger
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter(
	'[%(levelname)s %(asctime)s %(module)s:%(lineno)d] %(message)s',
	datefmt='%Y%m%d %H:%M:%S')

ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)

fh = logging.FileHandler(filename=f'linebot_{datetime.today().strftime("%Y-%m-%d")}.log', mode='w')
fh.setLevel(logging.INFO)
fh.setFormatter(formatter)

logger.addHandler(ch)
logger.addHandler(fh)


import pandas as pd
import inspect
import timeit
import functools
import copy

from typing import Callable

df = pd.DataFrame(
    data={
        'col1': [1, 2, 3, 4, 5],
        'col2': [6, 7, 8, 9, 10],
        'cola': ['a', 'b', 'c', 'd', 'e'],
        'col3': [0.1, 0.2, 0.3, 0.4, 0.5],
    },
    index=[10, 11, 12, 13, 14]
)

def f1(col1, col3):
    return col1 + col3

print(f"raw call: {timeit.timeit(lambda: f1(2, 0.2), number=10000):.5f}")

# wrapped f1 should be:
def f1_goal(i):
    return df.at[i, 'col1'] + df.at[i, 'col3']

print(f"goal call: {timeit.timeit(lambda: f1_goal(11), number=10000):.5f}")

def f1_manual(i):
    return f1(df.at[i, 'col1'], df.at[i, 'col3'])

print(f"manual: {timeit.timeit(lambda: f1_manual(11), number=10000):.5f}")

def df_wrap_basic(f: Callable) -> Callable:
    # this works, but it has two issues:
    # it inspects *every time* which is slow
    # it drops any info from the function (ref functools wrapped)
    def wrapped_fn(i):
        new_args = []
        for p in inspect.signature(f).parameters:
            new_arg = df.at[i, p]
            new_args += [new_arg]
        return f(*new_args)
    return wrapped_fn

f1_wrapped = df_wrap_basic(f1)
print(f"wrapped basic: {timeit.timeit(lambda: f1_wrapped(11), number=10000):.5f}")

def df_wrap_partial(f: Callable) -> Callable:
    new_args = []
    for p in inspect.signature(f).parameters:
        nf = lambda i, np: df.at[i, np]
        new_arg = functools.partial(nf, np=p)
        new_args += [new_arg]

    def wrapped_fn(i, wf: Callable, largs):
        fn_args = (arg(i) for arg in largs)
        return wf(*fn_args)

    partial_wrapped = functools.partial(wrapped_fn, wf=f, largs=new_args)
    return partial_wrapped

f1_wrapped_partial = df_wrap_partial(f1)
print(f"wrapped partial: {timeit.timeit(lambda: f1_wrapped_partial(11), number=10000):.5f}")

def df_wrap_cleaner(f: Callable) -> Callable:
    new_args = [functools.partial(lambda i, np: df.at[i, np], np=p) for p in inspect.signature(f).parameters]

    def wrapped_fn(i, wf: Callable, largs):
        return wf(*(arg(i) for arg in largs))

    return functools.partial(wrapped_fn, wf=f, largs=new_args)

f1_wrapped_partial_2 = df_wrap_cleaner(f1)
print(f"wrapped partial: {timeit.timeit(lambda: f1_wrapped_partial_2(11), number=10000):.5f}")


import minimalmodbus
from enum import Enum
from threading import Event, Lock
from time import sleep

from nio.block.base import Block
from nio.block.mixins.retry.retry import Retry
from nio.signal.base import Signal
from nio.properties import StringProperty, IntProperty, FloatProperty, \
    Property, VersionProperty, SelectProperty, PropertyHolder, ObjectProperty

class FunctionName(Enum):
    read_coils = 1
    read_discrete_inputs = 2
    read_holding_registers = 3
    read_input_registers = 4
    write_single_coil = 5
    write_multiple_coils = 15
    write_single_holding_register = 6
    write_multiple_holding_registers = 16

class PortConfig(PropertyHolder):
    baudrate = IntProperty(title='Baud Rate', default=19200, order=21)
    parity = StringProperty(title='Parity (N, E, O)', default='N', order=23)
    bytesize = IntProperty(title='Byte Size', default=8, order=22)
    stopbits = IntProperty(title='Stop Bits', default=1, order=24)
    port = StringProperty(title='Serial Port',
                          default='/dev/ttyUSB0',
                          order=20)

class ModbusRTU(Retry, Block):

    """ Communicate with a device using Modbus over RTU.

    Parameters:
        slave_address (str): Slave address of modbus device.
        port (str): Serial port modbus device is connected to.
        timeout (float): Seconds to wait for a response before failing.
    """

    version = VersionProperty('1.0.0', order=100)
    slave_address = IntProperty(title='Slave Address', default=1, order=10)
    function_name = SelectProperty(FunctionName,
                                   title='Function Name',
                                   default=FunctionName.read_input_registers,
                                   order=11)
    address = Property(title='Starting Address', default='0', order=12)
    count = IntProperty(title='Number of coils/registers to read',
                        default=1,
                        order=13)
    value = Property(title='Write Value(s)', default='{{ True }}', order=14)
    port_config = ObjectProperty(PortConfig,
                                 title="Serial Port Setup",
                                 default=PortConfig(),
                                 advanced=True)
    timeout = FloatProperty(title='Timeout', default='0.05', advanced=True)

    def __init__(self):
        super().__init__()
        self._client = None
        self._process_lock = Lock()
        self._modbus_function = None
        self._num_locks = 0
        self._max_locks = 5

    def configure(self, context):
        super().configure(context)
        self._connect()
        self._modbus_function = \
            self._function_name_from_code(self.function_name().value)

    def process_signals(self, signals, input_id='default'):
        output = []
        for signal in signals:
            if self._num_locks >= self._max_locks:
                self.logger.debug(
                    "Skipping signal; max numbers of signals waiting")
                continue
            self._num_locks += 1
            with self._process_lock:
                output_signal = self._process_signal(signal)
                if output_signal:
                    output.append(output_signal)
            self._num_locks -= 1
        if output:
            self.notify_signals(output)

    def _process_signal(self, signal):
        params = self._prepare_params(signal)
        return self.execute_with_retry(self._execute, params=params)

    def _connect(self):
        self.logger.debug('Connecting to modbus')
        minimalmodbus.BAUDRATE = self.port_config().baudrate()
        minimalmodbus.PARITY = self.port_config().parity()
        minimalmodbus.BYTESIZE = self.port_config().bytesize()
        minimalmodbus.STOPBITS = self.port_config().stopbits()
        minimalmodbus.TIMEOUT = self.timeout()
        self._client = minimalmodbus.Instrument(self.port_config().port(),
                                                self.slave_address())
        self.logger.debug(self._client)
        self.logger.debug('Succesfully connected to modbus')

    def _execute(self, params, retry=False):
        self.logger.debug('Executing Modbus function \'{}\' with params: {}, '
                          'is_retry: {}'.format(self._modbus_function,
                                                params, retry))
        response = getattr(self._client, self._modbus_function)(**params)
        self.logger.debug('Modbus function returned: {}'.format(response))
        return self._process_response(response, params)

    def _function_name_from_code(self, code):
        return {
            1: 'read_bit',
            2: 'read_bit',
            5: 'write_bit',
            15: 'write_bit',
            3: 'read_registers',
            4: 'read_registers',
            6: 'write_register',
            16: 'write_registers'
        }.get(code)

    def _prepare_params(self, signal):
        params = {}
        params['functioncode'] = self.function_name().value
        params['registeraddress'] = self._address(signal)
        if self.function_name().value in [3, 4]:
            params['numberOfRegisters'] = self.count()
        elif self.function_name().value in [5, 6, 15, 16]:
            try:
                params['value'] = self.value(signal)
            except:
                raise Exception('Invalid configuration of `value` property')
        return params

    def _process_response(self, response, params):
        if not response:
            return
        signal = Signal({
            'values': response,
            'params': params
        })
        return signal

    def _address(self, signal):
        try:
            return int(self.address(signal))
        except:
            self.logger.warning(
                'Address needs to evaluate to an integer', exc_info=True)

    def before_retry(self, *args, **kwargs):
        """ Reconnect before making retry query. """
        self._close()
        self._connect()

    def _close(self):
        """minimalmodbus needs some help re-connecting"""
        try:
            # Try to manually close the serial connection
            self._client.serial.close()
        except:
            self.logger.warning(
                "Failed to manually close serial connection", exc_info=True)


"""PyAudio Example: Play a WAVE file."""
import time

import pyaudio
import wave
from tqdm import tqdm

# 播放音频
def play_audio(wave_path):

    CHUNK = 1024

    wf = wave.open(wave_path, 'rb')

    # instantiate PyAudio (1)
    p = pyaudio.PyAudio()

    # open stream (2)
    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                    channels=wf.getnchannels(),
                    rate=wf.getframerate(),
                    output=True)

    # read data
    data = wf.readframes(CHUNK)

    # play stream (3)
    datas = []
    while len(data) > 0:
        data = wf.readframes(CHUNK)
        datas.append(data)

    for d in tqdm(datas):
        stream.write(d)

    # stop stream (4)
    stream.stop_stream()
    stream.close()

    # close PyAudio (5)
    p.terminate()

# 回调的方式播放音频，在播放过程中程序可以做其他事情
def play_audio_callback(wave_path):
    CHUNK = 1024

    wf = wave.open(wave_path, 'rb')

    # instantiate PyAudio (1)
    p = pyaudio.PyAudio()

    def callback(in_data, frame_count, time_info, status):
        data = wf.readframes(frame_count)
        return (data, pyaudio.paContinue)

    # open stream (2)
    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                    channels=wf.getnchannels(),
                    rate=wf.getframerate(),
                    output=True,
                    stream_callback=callback)

    # read data
    stream.start_stream()

    while stream.is_active():
        print("1234")
        time.sleep(0.1)

    # stop stream (4)
    stream.stop_stream()
    stream.close()

    # close PyAudio (5)
    p.terminate()

# 录音
def record_audio(wave_out_path,record_second):
    CHUNK = 1024
    FORMAT = pyaudio.paInt16
    CHANNELS = 2
    RATE = 44100

    p = pyaudio.PyAudio()

    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=CHUNK)

    wf = wave.open(wave_out_path, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)

    print("* recording")

    for i in tqdm(range(0, int(RATE / CHUNK * record_second))):
        data = stream.read(CHUNK)
        wf.writeframes(data)

    print("* done recording")

    stream.stop_stream()
    stream.close()

    p.terminate()

    wf.close()

if __name__ == '__main__':
    record_audio("output.wav",record_second=4)
    play_audio("output.wav")


"""Several iterations and playing around with building an LSTM model in torch.
Much of the working portion of this is stolen from KD Nuggets
(https://www.kdnuggets.com/2020/07/pytorch-lstm-text-generation-tutorial.html),
although there are other parts that were built from reviewing PyTorch tutorials."""

import nltk
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import DataLoader

def getCorpus():
    # return nltk.word_tokenize(nltk.corpus.gutenberg.raw("austen-sense.txt").lower())
    return getSyntheticData('syntheticData.txt')

# LSTM from KD Nuggets
class MyLSTM(nn.Module):
    def __init__(self, dataset):
        super(MyLSTM, self).__init__()
        self.lstm_size = 128
        self.embedding_dim = 128
        self.num_layers = 1

        n_vocab = len(dataset.uniq_words)
        self.embedding = nn.Embedding(
            num_embeddings=n_vocab,
            embedding_dim=self.embedding_dim,
        )
        self.lstm = nn.LSTM(
            input_size=self.lstm_size,
            hidden_size=self.lstm_size,
            num_layers=self.num_layers,
            dropout=0.2,
        )
        self.fc = nn.Linear(self.lstm_size, n_vocab)

    def forward(self, x, prev_state):
        embed = self.embedding(x)
        output, state = self.lstm(embed, prev_state)
        logits = self.fc(output)
        return logits, state

    def init_state(self, sequence_length):
        return (torch.zeros(self.num_layers, sequence_length, self.lstm_size),
                torch.zeros(self.num_layers, sequence_length, self.lstm_size))

# Dataset from KD Nuggets
class Dataset(torch.utils.data.Dataset):
    def __init__(
        self,
        args,
    ):
        self.args = args
        self.words = self.load_words()
        self.uniq_words = self.get_uniq_words()

        self.index_to_word = {index: word for index, word in enumerate(self.uniq_words)}
        self.word_to_index = {word: index for index, word in enumerate(self.uniq_words)}

        self.words_indexes = [self.word_to_index[w] for w in self.words]

    def load_words(self):
        return getCorpus()[:10006]

    def get_uniq_words(self):
        word_counts = set((self.words))
        return word_counts

    def __len__(self):
        return len(self.words_indexes) - self.args['sequence_length']

    def __getitem__(self, index):
        return (
            torch.tensor(self.words_indexes[index:index+self.args['sequence_length']]),
            torch.tensor(self.words_indexes[index+1:index+self.args['sequence_length']+1]),
        )

# Train function from KD Nuggets
def train(dataset, model, args, criterion, optimizer):
    model.train()

    dataloader = DataLoader(dataset, batch_size=args['batch_size'])

    for epoch in range(args['max_epochs']):
        state_h, state_c = model.init_state(args["sequence_length"])

        for batch, (x, y) in enumerate(dataloader):
            optimizer.zero_grad()

            y_pred, (state_h, state_c) = model(x, (state_h, state_c))
            loss = criterion(y_pred.transpose(1, 2), y)

            state_h = state_h.detach()
            state_c = state_c.detach()

            loss.backward()
            optimizer.step()

            print({ 'epoch': epoch, 'batch': batch, 'loss': loss.item() })

# Predict function from KD Nuggets
def predict(dataset, model, text, next_words=5):
    model.eval()

    if type(text) == type(str()):
        words = text.split(' ')
    else:
        words = text
    state_h, state_c = model.init_state(len(words))

    for i in range(0, next_words):
        x = torch.tensor([[dataset.word_to_index[w] if w in dataset.word_to_index else dataset.word_to_index[np.random.choice(list(dataset.word_to_index.keys()))] for w in words[i:]]])
        y_pred, (state_h, state_c) = model(x, (state_h, state_c))

        last_word_logits = y_pred[0][-1]
        p = torch.nn.functional.softmax(last_word_logits, dim=0).detach().numpy()
        # Deterministic
        maxValue = -1
        maxKey = -1
        for eachKey in range(len(p)):
            if p[eachKey] > maxValue:
                maxValue = p[eachKey]
                maxKey = eachKey
        word_index = maxKey
        # Probabalistic
        # word_index = np.random.choice(len(last_word_logits), p=p)
        words.append(dataset.index_to_word[word_index])

    return words

def getSyntheticData(filePath):
    corpus = []
    with open(filePath, 'r') as file:
        for line in file:
            words = line[:-1].split(" ")
            corpus.extend(words)
            pass
        pass
    return corpus

# Execution functions from KD Nuggets
def main():
    args = {'max_epochs': 10, 'batch_size': 20, 'sequence_length': 5 }
    # dataset = Dataset(args)
    # modelPath = 'myLSTM.pt'
    modelPath = 'myLSTMsynth.pt'
    criterion = nn.CrossEntropyLoss()
    checkpoint = torch.load(modelPath)
    dataset = checkpoint['dataset']
    model = MyLSTM(dataset)
    model.load_state_dict(checkpoint['model_state_dict'])
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
    criterion = checkpoint['loss']
    train(dataset, model, args, criterion, optimizer)
    torch.save({'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer.state_dict(),
            'loss': criterion,
            'dataset': dataset},
	    modelPath)
    overallTrainingAccuracy = []
    print("Training Data")
    corpus = getCorpus()
    for eachStart in [10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100]:
        trainingData = corpus[eachStart:]
        print("Train:")
        print(trainingData[:10])
        print("Prediction:")
        prediction = predict(dataset, model, text=trainingData[:5])
        print(prediction)
        print("Accuracy:")
        accuracy = sum([prediction[i] == trainingData[i] for i in range(5,10)])/5
        print(accuracy)
        overallTrainingAccuracy.append(accuracy)
    overallTestAccuracy = []
    print("Testing Data")
    for eachStart in [10006, 10014, 10035, 10059, 10091, 10099, 10106, 10120, 10135, 10146, 10155]:
        test = corpus[eachStart:]
        print("Test:")
        print(test[:10])
        print("Prediction:")
        prediction = predict(dataset, model, text=test[:5])
        print(prediction)
        print("Accuracy:")
        testAccuracy = sum([prediction[i] == test[i] for i in range(5,10)])/5
        print(testAccuracy)
        overallTestAccuracy.append(testAccuracy)
    print("Training Accuracy:")
    print(sum(overallTrainingAccuracy)/len(overallTrainingAccuracy))
    print("Testing Accuracy:")
    print(sum(overallTestAccuracy)/len(overallTestAccuracy))

if __name__ == "__main__":
    main()