import streamlit as st
import pandas as pd
import altair as alt
from collections import Counter

st.title("Let's analyze some Video Game Sales Data ðŸŽ®ðŸ“Š.")

data_file = "./vgsales.csv"

@st.cache  # add caching so we load the data only once
def load_data():
	# Load the penguin data
	df = pd.read_csv(data_file).dropna()

	trimmed_df = df.copy(deep=True)
	trimmed_df.loc[trimmed_df["Publisher"].value_counts()[trimmed_df["Publisher"]].values < 100, "Publisher"] = "Other Publisher"
	trimmed_df.loc[trimmed_df["Platform"].value_counts()[trimmed_df["Platform"]].values < 20, "Platform"] = "Other Platform"
	return df, trimmed_df

def show_dataset(df):
	st.write("## Dataset Description")
	show_dataset_description()
	st.write("**Dataset:**")
	st.write("shape: ",df.shape)
	if st.checkbox("Show Raw Data"):
		st.write(df)

def get_melt_year_df(df, columns):
	return df[columns+["Year"]].melt('Year').rename(columns = {'variable':'Region'})

def show_yearly_sale(df):

	st.write('## Yearly Sales Trend')
	st.write("**The dataset contains yearly sales data for various games in different regions. Let's explore the sales trend in different regions through some interactions!** ðŸ‘‡ðŸ�»")

	columns = ['NA_Sales', 'EU_Sales', 'JP_Sales', 'Other_Sales', 'Global_Sales']
	select_box = alt.binding_select(options=columns, name='Select a Region:')
	sel = alt.selection_single(fields=['Region Sale'], bind=select_box, init={'Region Sale': 'Global_Sales'})

	# line chart
	st.write("ðŸ’¡ *You can select specific region by clicking on the lines*")

	data = get_melt_year_df(df, columns)
	brush = alt.selection_single(encodings=['color'])

	st.write(alt.Chart(data).mark_line(opacity=0.75,thickness=10).encode(
    	x='Year:N',
    	y=alt.Y('value:Q', title='Sale (in millions)', aggregate='sum'),
    	color=alt.condition(brush, "Region:N", alt.value('lightgrey'), scale=alt.Scale(scheme='tableau20')),
	).add_selection(
		brush
	))

	# bar chart
	st.write("ðŸ’¡ *You can select specific region with the dropdown menu below*")

	st.write(alt.Chart(df).transform_fold(
		columns,
		as_=['Region Sale', 'Sale']
	).transform_filter(
		sel
	).mark_bar().encode(
			x=alt.X('Year:N'),
			y=alt.Y('Sale:Q', title='Sale (in millions)')
	).add_selection(
		sel
	).properties(
		height=500
	))

def show_game_trend_scatter(df):

	st.write('## Individual Game Sales')
	st.write("**Now let's zoom in to explore individual games.**")

	columns = ['Global_Sales', 'NA_Sales', 'EU_Sales', 'JP_Sales', 'Other_Sales']
	select_box = alt.binding_select(options=columns, name='Select a Region:')
	sel = alt.selection_single(fields=['Select a Region:'], bind=select_box, init={'Select a Region:': 'Global_Sales'})

	colors = ['Platform', 'Genre', 'Publisher']
	select_box2 = alt.binding_select(options=colors, name='Group By:')
	sel2 = alt.selection_single(fields=['Group By:'], bind=select_box2, init={'Group By:': 'Platform'})

	brush = alt.selection_single(encodings=['color'])

	st.write("ðŸ’¡ *You can click on individual games to see the group it belongs to*")

	st.write(alt.Chart(df).mark_point(opacity=0.75).transform_fold(
		columns,
		as_=['Select a Region:', 'Sale']
	).transform_fold(
		colors,
		as_=['Group By:', 'Group']
	).transform_filter(
		sel
	).transform_filter(
		sel2
	).add_selection(
		brush
	).encode(
			x= 'Year:N',
			y= alt.Y('Sale:Q', title='Sale (in millions)', aggregate='sum', scale=alt.Scale()),
			color=alt.condition(brush, "Group:N", alt.value('lightgrey'), scale=alt.Scale(scheme='tableau20')),
			tooltip=['Name', 'Platform', 'Genre', 'Publisher']
	).add_selection(
		sel
	).add_selection(
		sel2
	).properties(
		height=500
	).interactive())

@st.cache
def get_game_agg_df(df, regions, k):
	res = {}
	for region in regions:
		res[region] = df[["Name",region]].groupby(["Name"]).agg({region:"sum"}).sort_values(by=[region], ascending=False).iloc[:k,:].reset_index()
	return res

def show_game_region_bar(df):
	st.write('## Popular Games')

	st.write("**What are the popular games in each region and over the years?ðŸ§� Let's keep exploring!**")

	st.write("ðŸ’¡ *You can select specific year range with slider*")

	min_year, max_year = get_year_range(df)
	selected_year = st.slider("View Top 10 Game in Year Range:", min_year, max_year, (min_year, max_year), 1)

	df_selected = df[ (df["Year"] >= selected_year[0]) & (df["Year"] <= selected_year[1])]

	regions = ['Global_Sales', 'NA_Sales', 'EU_Sales', 'JP_Sales', 'Other_Sales']
	new_df = get_game_agg_df(df_selected, regions, 10)

	brush = alt.selection_single(encodings=['color'])

	titles = {'Global_Sales':'Global', 'NA_Sales':'North America',
				'EU_Sales':'Europe', 'JP_Sales': 'Japan', 'Other_Sales': 'Other Regions'}
	for region in regions:
		st.write("**%s**"%(titles[region]))
		st.write(alt.Chart(new_df[region]).mark_bar().encode(
			x=alt.X("Name:N", sort='-y'),
			y=alt.Y(region, title='Sale (in millions)'),
			color=alt.Color("Name:N", scale=alt.Scale(scheme='tableau20'))
		).properties(
			width=600,
			height=350
		))

@st.cache
def get_year_range(df):
	return int(df["Year"].min()), int(df["Year"].max())

def show_genre_region_bar(df):

	st.write('## Popular Genres')
	st.write("**What about genres? Let's compare!**")

	st.write("ðŸ’¡ *You can select specific year range with slider*")
	st.write("ðŸ’¡ *Try clicking on one or more genres to see how they perform in different regions*")
	st.write("ðŸ’¡ *You can also click on the individual points in the scatterplot to see other games in its genre*")
	st.write("âŒ› *Since it takes time to load the transformed data, the response may take a few seconds. Please be patient.*")

	brush = alt.selection_multi(encodings=['color'])

	min_year, max_year = get_year_range(df)
	selected_year = st.slider("View Popular Genre in Year Range", min_year, max_year, (min_year, max_year), 1)

	new_df = df[ (df["Year"] >= selected_year[0]) & (df["Year"] <= selected_year[1])]

	hist = (alt.Chart(new_df).mark_bar().encode(
		y=alt.Y(alt.repeat('row'), aggregate='sum', type='quantitative'),
	))

	color_scheme = alt.condition(brush, "Genre:N", alt.value('lightgrey'),scale=alt.Scale(scheme='tableau20'))

	top_chart = alt.layer(hist.encode(
		x=alt.X("Genre:N", sort='-y'),
		color=color_scheme
	)).properties(
		width=500,
		height=200
	).repeat(row=['Global_Sales', 'NA_Sales', 'EU_Sales', 'JP_Sales', 'Other_Sales'], data=new_df).add_selection(
		brush
	)

	bottom_chart = alt.Chart(new_df).mark_point().encode(
		x = alt.X(alt.repeat("column"), type ='quantitative', scale=alt.Scale(type='sqrt')),
		y = alt.Y(alt.repeat("row"), type='quantitative', scale=alt.Scale(type='sqrt')),
		color = color_scheme,
		tooltip = ['Name']
	).properties(
		width=150,
		height=150
	).repeat(
		row = ["NA_Sales", "EU_Sales", "JP_Sales", "Other_Sales"],
		column = ["NA_Sales", "EU_Sales", "JP_Sales", "Other_Sales"]
	).add_selection(
		brush
	)

	complete_chart = alt.vconcat(top_chart, bottom_chart)
	st.write(complete_chart)

@st.cache
def get_publisher_agg_df(df, regions, k):
	res = {}
	for region in regions:
		res[region] = df[["Publisher", "Name", region]].groupby(["Publisher"]).agg({region:"sum", "Name":"count"}).sort_values(by=[region], ascending=False).iloc[:k,:].reset_index()
	return res

def show_publisher_region_bar(df):
	st.write('## Popular Publishers')

	st.write("**It might also be interesting to compare different publishers.ðŸ¤”**")

	st.write("ðŸ’¡ *You can select specific year range with slider*")
	st.write("ðŸ’¡ *Hover over publishers to see the number of games they released during the time*")
	min_year, max_year = get_year_range(df)
	selected_year = st.slider("View Popular Publisher in Year Range:", min_year, max_year, (min_year, max_year), 1)

	df_selected = df[ (df["Year"] >= selected_year[0]) & (df["Year"] <= selected_year[1])]

	regions = ['Global_Sales', 'NA_Sales', 'EU_Sales', 'JP_Sales', 'Other_Sales']
	new_df = get_publisher_agg_df(df_selected, regions, 10)

	brush = alt.selection_single(encodings=['color'])

	titles = {'Global_Sales':'Global', 'NA_Sales':'North America',
				'EU_Sales':'Europe', 'JP_Sales': 'Japan', 'Other_Sales': 'Other Regions'}
	for region in regions:
		st.write("**%s**"%(titles[region]))
		st.write(alt.Chart(new_df[region]).mark_bar().encode(
			x=alt.X("Publisher:N", sort='-y'),
			y=alt.Y(region, title='Sale (in millions)'),
			color=alt.Color("Publisher:N", scale=alt.Scale(scheme='tableau20')),
			tooltip=[alt.Tooltip(field="Name", title="Total Released Games", type="quantitative")]
		).properties(
			width=600,
			height=350
		))

def show_genre_platform(df):
	st.write('## Popular Game Genres on each Platform')

	st.write("**Let's see how game trends evolve on each platform. Are gamers' preference changing over the decades?**")

	columns = list(df["Platform"].unique())
	select_box = alt.binding_select(options=columns, name='Select a Platform:')
	sel = alt.selection_single(fields=['Platform'], bind=select_box, init={'Platform': 'Wii'})

	# stacked bar chart
	st.write("ðŸ’¡ *You can select specific platform with the dropdown menu below*")
	st.write("ðŸ’¡ *Hover over the genres to see their popularities in different regions*")

	st.write(alt.Chart(df).transform_filter(
		sel
	).mark_bar().encode(
			x=alt.X('Year:N'),
			y=alt.Y('sum(Global_Sales):Q', title='Sale (in millions)'),
			color=alt.Color('Genre', scale=alt.Scale(scheme='tableau20')),
			order=alt.Order(
				'Genre',
				sort='ascending'
			),
			tooltip=['Genre', 'sum(NA_Sales)', 'sum(EU_Sales)', 'sum(JP_Sales)', 'sum(Other_Sales)']
	).add_selection(
		sel
	).properties(
		width=800,
		height=500
	))

def show_game_publisher(df):
	st.write('## Top 20 Best-selling Game for each Company/Publisher')

	st.write("**What are the most popular games by each company/publisher?**")

	columns = list(df["Publisher"].unique())
	select_box = alt.binding_select(options=columns, name='Select a Publisher:')
	sel = alt.selection_single(fields=['Publisher'], bind=select_box, init={'Publisher': 'Nintendo'})

	# stacked bar chart
	st.write("ðŸ’¡ *You can select specific publisher/company with the dropdown menu below*")
	st.write("ðŸ’¡ *Hover over the game titles to see their popularities in different regions*")

	st.write(alt.Chart(df).transform_filter(
		sel
	).mark_bar().encode(
			x=alt.X('Year:N'),
			y=alt.Y('sum(Global_Sales):Q', title='Sale (in millions)'),
			color=alt.Color('Name', scale=alt.Scale(scheme='tableau20')),
			order=alt.Order(
				'sum(Global_Sales)',
				sort='ascending'
			),
			tooltip=['Name', 'Genre', 'sum(NA_Sales)', 'sum(EU_Sales)', 'sum(JP_Sales)', 'sum(Other_Sales)']
	).transform_window(
		rank="rank(Global_Sales)",
		sort=[alt.SortField("Global_Sales", order="descending")]
	).transform_filter(
		(alt.datum.rank < 20)
	).add_selection(
		sel
	).properties(
		width=800,
		height=500
	))

@st.cache
def get_game_series(df):
	games = sorted(list(df["Name"].unique()))
	tokenized_games = [game.replace(":", "").split() for game in games]

	game_series = {}
	for idx in range(len(tokenized_games)):
		current = tokenized_games[idx]
		previous = tokenized_games[idx-1]
		game_series_cnt = 0
		for l in range(min(len(current), len(previous))):
			if current[l] == previous[l]:
				game_series_cnt += 1
		if game_series_cnt >= 1:
			game_series_name = " ".join(current[:game_series_cnt])
			if game_series_name not in game_series:
				game_series[game_series_name] = []
			game_series[game_series_name].append(" ".join(current))
			game_series[game_series_name].append(" ".join(previous))

	return game_series

@st.cache
def get_game_series_df(df, game_series):
	new_df = df.copy()
	game_serie_cnt = Counter()
	def series_name(row):
		for k in game_series:
			if row["Name"].replace(":", "") in game_series[k]:
				game_serie_cnt.update((k, 1))
				return k
	new_df["Series_Name"] = new_df.apply(lambda row: series_name(row), axis=1)
	game_serie = [game for game in game_serie_cnt if game_serie_cnt[game] > 1]
	return new_df, game_serie

def show_game_series(df):
	st.write('## Popular Game Series')

	st.write("**Let's explore some of the most popular game series**")

	game_series = get_game_series(df)
	game_series_df, columns = get_game_series_df(df, game_series)

	select_box = alt.binding_select(options=columns, name='Select a Game Series:')
	sel = alt.selection_single(fields=['Series_Name'], bind=select_box, init={'Series_Name': 'Pokemon'})

	# stacked bar chart

	st.write("ðŸ’¡ *You can select specific game serie with the dropdown menu below*")
	st.write("ðŸ’¡ *Hover over the game titles to see their popularities in different regions*")

	st.write(alt.Chart(game_series_df).transform_filter(
		sel
	).mark_bar().encode(
			x=alt.X('Year:N'),
			y=alt.Y('sum(Global_Sales):Q', title='Sale (in millions)'),
			color=alt.Color('Name', scale=alt.Scale(scheme='tableau20')),
			order=alt.Order(
				'Name',
				sort='ascending'
			),
			tooltip=['Name', 'Genre', 'sum(NA_Sales)', 'sum(EU_Sales)', 'sum(JP_Sales)', 'sum(Other_Sales)']
	).add_selection(
		sel
	).properties(
		width=800,
		height=500
	))

def show_dataset_description():
	st.write("This dataset contains a list of video games with sales greater than 100,000 copies. It was generated by a scrape of [vgchartz.com](vgchartz.com).");
	st.write("**Fields:**")

	lst = ["- Rank: Ranking of overall sales",
		"- Name: The games name",
		"- Platform: Platform of the games release (i.e. PC,PS4, etc.)",
		"- Year: Year of the game's release",
		"- Genre: Genre of the game",
		"- Publisher: Publisher of the game",
		"- NA_Sales: Sales in North America (in millions)",
		"- EU_Sales: Sales in Europe (in millions)",
		"- JP_Sales: Sales in Japan (in millions)",
		"- Other_Sales: Sales in the rest of the world (in millions)",
		"- Global_Sales: Total worldwide sales"]

	if st.checkbox("Show Field Description:"):
		for l in lst:
			st.write(l)

# Intro
st.write("# Video Game Sales Dataset")
st.write("Datset collected From [Kaggle](https://www.kaggle.com/snanilim/video-games-sales-analysis-and-visualization)")
df, trimmed_df = load_data()

# Data Set
show_dataset(df)

# General Trend Plots
show_yearly_sale(df)

# Region Plots
show_game_trend_scatter(trimmed_df)
show_game_region_bar(df)
show_genre_region_bar(df)
show_publisher_region_bar(df)

# Game Plots
show_genre_platform(df)
show_game_publisher(df)
show_game_series(df)


# Урок 5 задание 2
# "Генератор персонажей" для ролевой игры
# Распеделение 30 пунктов между Силой, Здоровьем, Мудростью и Ловкостью.

chars = {'Сила    ' : 0, 'Здоровье' : 0, 'Мудрость' : 0, 'Ловкость' : 0}
points = 30
choice3 = ""

while points > 0 or choice3 != 'Y':
    point = 31

    print('У вас осталось', points,'очков. На данный момент ваши характеристики:')
    for i in chars:
        print(i, end = '\t')
        print(chars[i])

    input('Далее...')
    print('\nРаспределите оставшиеся очки.'
          """
    "Генератор персонажей"

    0 - Выход
    1 - Сила
    2 - Здоровье
    3 - Мудрость
    4 - Ловкость

          """)
    choice1 = input('Ваш выбор: ')

    if choice1 == '0':
        break
    elif choice1 == '1':
        term = 'Сила    '
    elif choice1 == '2':
        term = 'Здоровье'
    elif choice1 == '3':
        term = 'Мудрость'
    elif choice1 == '4':
        term = 'Ловкость'
    else:
        print('Вашего выбора нет.\n')
        continue

    print('\tВложить хар-ки - "+" \n\tУбрать хар-ки - "-". ')

    choice2 = input('Ваш выбор: ')
    if choice2 == '+':
        while point > points:
            print('У вас всего', points, 'очков.')
            point = int(input('Сколько очков вложить? '))

        points -= point
        chars[term] += point

    elif choice2 == '-' :
        while point > chars[term]:
            print('В характеристике', term, 'только', chars[term],'очков.')
            point = int(input('Сколько очков отнять? '))

        points += point
        chars[term] -= point

    else:
        print('Вашего выбора', choice2,'нет.')
        continue

    if points <= 0:
        choice3 = input('Закончить создание персонажа? Y/N ')
        choice3 = choice3.upper()

print('\nПерсонаж создан, его характеристики:')
for i in chars:
    print(i, end = '\t')
    print(chars[i])
print('Осталось', points, 'очков.')

input('Enter для выхода')


def sum_of_numbers(nums):
    # 1. terminating cond
    if len(nums) == 1:
        return nums[0]

    # 2. breaking the problem into smaller parts
    first_part = nums[:-1]

    # 3. call the recursive with sub-problems
    sum_first_part = sum_of_numbers(first_part)

    # 4. combine the solution
    res = sum_first_part + nums[-1]
    return res

print(sum_of_numbers([12, 1, 8]))


from django.urls import path
from App1 import views
from App1.views import curso

urlpatterns = [
    path('curso/', curso),
    path('', views.inicio, name="Inicio"),
    path('cursos', views.cursos, name="Cursos"),
    path('profesores', views.profesores, name="Profesores"),
    path('estudiantes', views.estudiantes, name="Estudiantes"),
    path('entregables', views.entregables, name="Entregables"),

]


__author__ = 'ee364g07'
# $Author: ee364g07 $
# $Date: 2015-04-20 15:54:28 -0400 (Mon, 20 Apr 2015) $
# $Revision: 79275 $
# $HeadURL: svn+ssh://ece364sv@ecegrid-thin1/home/ecegrid/a/ece364sv/svn/S15/students/ee364g07/Lab11/NewSteganography.py $
# $Id: NewSteganography.py 79275 2015-04-20 19:54:28Z ee364g07 $

import base64
from PIL import Image
import re
import math
from Steganography import *

class NewSteganography(Steganography):

    def __init__(self, imagePath, direction='horizontal'):
        Steganography.__init__(self, imagePath, direction)

    def wipeMedium(self):
        new_pixel = []
        for oldpixel in self.pixels_medium:
            newpixel = self.forcezero(oldpixel)
            new_pixel.append(newpixel)
        self.embedbydirection(self.direction, new_pixel,self.imagePath)

    def checkIfMessageExists(self):
        mediumdata = []
        message = []
        bcv = 0
        ocv = 0
        for pixel in self.pixels_medium:
            if ocv > 64:
                break
            if bcv == 8:
                encodedpixel = (self.bits2data(message))                   #converts the bits value to an ASCII representation of the character
                mediumdata.append(chr(encodedpixel))
                ocv += 1
                bcv = 0                                                 #reset bit counter
                message = []                                            #reset messagelist
                message.append(self.getlsb(pixel))
                bcv += 1
            else:
                message.append(self.getlsb(pixel))
                bcv += 1

        mediumstring = "".join(mediumdata)

        str = mediumstring
        pat = r'<?.*?type="(.*)"'
        match = re.search(pat, str)

        if match:
            return True,match.group(1)
        else:
            return False, None

if __name__ == "__main__":
    #b = Steganography('files/tiger_lena_h.png', 'horizontal')
    c = NewSteganography('files/grays/bridge.png', 'horizontal')
    print(c.checkIfMessageExists())


import subprocess

class Receiver(object):

    def __init__(self, path, port):
        self.path = path
        self.port = port
        self.fp = None
        self.sock = None

    def open(self):
        self.fp = open(self.path, 'wb+')
        # self.sock =

class Sender(object):
    def __init__(self, path, port):
        self.path = path
        self.port = port
        self.fp = None
        self.sock = None

    # def

# if __name__ == '__main__':

    # transcode('/data/leader/incoming/The Big Bang Theory Season 10/The_Big_Bang_Theory_Season_10_Disc_1_t00.mkv',
    #           '/data/leader/outgoing/The_Big_Bang_Theory_Season_10_Disc_1_t00.mkv')


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
Build a command to run `mach l10n-cross-channel`.
"""

from pipes import quote as shell_quote

from taskgraph.transforms.base import TransformSequence
from taskgraph.util.schema import resolve_keyed_by

transforms = TransformSequence()

@transforms.add
def resolve_keys(config, jobs):
    for job in jobs:
        for item in ["ssh-key-secret", "run.actions"]:
            resolve_keyed_by(job, item, item, **{"level": str(config.params["level"])})
        yield job

@transforms.add
def build_command(config, jobs):
    for job in jobs:
        command = [
            "l10n-cross-channel",
            "-o",
            "/builds/worker/artifacts/outgoing.diff",
            "--attempts",
            "5",
        ]
        ssh_key_secret = job.pop("ssh-key-secret")
        if ssh_key_secret:
            command.extend(["--ssh-secret", ssh_key_secret])
            job.setdefault("scopes", []).append(f"secrets:get:{ssh_key_secret}")

        command.extend(job["run"].pop("actions", []))
        job.setdefault("run", {}).update(
            {"using": "mach", "mach": " ".join(map(shell_quote, command))}
        )
        yield job


""" Test file for the operations of the pipeline.

For now, all operations will be tested in this file. It is forseen though, that
the file will grow to a point where it is no longer practical and the
testcases need to be split into different files. How this will be done is not
entirely clear right now.

@author Max Weise
created 23.07.2022
"""

from src.pipetex import operations
from src.pipetex import enums, exceptions
from tests import util_functions

import os
import os.path
import pytest
import shutil
from typing import Optional, Tuple

# === Fixtures ===
FILE_PREFIX = "[piped]"

@pytest.fixture
def simple_testfile():
    """Generates a simple tex file to run tests with."""
    file_name = "test_file"
    with open(f"{file_name}.tex", "w+", encoding="utf-8") as f:
        f.write(
            "\\documentclass[a4paper, draft, 12pt]{article}\n"
            "\\begin{document}\n"
            "This is a testfile\n"
            "\\end{document}\n"
        )

    yield file_name

    util_functions.remove_files(file_name)

@pytest.fixture
def simple_testfile_no_draft():
    """Generates a simple tex file to run tests with."""
    file_name = "test_file"
    with open(f"{file_name}.tex", "w+", encoding="utf-8") as f:
        f.write(
            "\\documentclass[a4paper, 12pt]{article}\n"
            "\\begin{document}\n"
            "This is a testfile\n"
            "\\end{document}\n"
        )

    yield file_name

    util_functions.remove_files(file_name)

@pytest.fixture
def dirty_working_dir():
    """Create some auxiliary files to 'pollute' the working dir."""
    file_name = f"{FILE_PREFIX}_test_file"
    ex = ['tex', 'aux', 'pdf', 'glo', 'bib']
    util_functions.write_empty_file(file_name, ex)

    yield file_name

    util_functions.remove_files(file_name)

    util_functions.remove_files("not_removed")

    if "DEPLOY" in os.listdir():
        shutil.rmtree("DEPLOY")

@pytest.fixture
def config_dict():
    return {"file_prefix": "[piped]"}

# === Type Def ===
Monad = Tuple[bool, Optional[exceptions.InternalException]]

def test_remove_draft_option(simple_testfile, config_dict):
    """Tests that the draft option from the classdefinition gets removed. """
    file_name = simple_testfile

    success, error = operations.remove_draft_option(file_name, config_dict)

    with open(f"{file_name}.tex", "r") as f:
        lines_in_testfile: list[str] = [line.rstrip() for line in f]

    assert success
    assert not error
    assert "draft" not in lines_in_testfile[0]
    assert len(lines_in_testfile) == 4

def test_remove_draft_option_fileNotFound(config_dict):
    """Tests that the draft option from the classdefinition gets removed. """
    file_name = "not_a_file"
    success, error = operations.remove_draft_option(file_name, config_dict)

    assert not success
    assert error
    assert type(error.severity_level) == int
    assert 20 < error.severity_level <= 30

def test_remove_draft_option_draftOptionNotFound(simple_testfile_no_draft,
                                                 config_dict):
    """Tests that the draft option from the classdefinition gets removed. """
    file_name = simple_testfile_no_draft

    with open(f"{file_name}.tex", "r") as f:
        lines_befor_runing_test: list[str] = [line.rstrip() for line in f]

    success, error = operations.remove_draft_option(
        simple_testfile_no_draft,
        config_dict
    )

    with open(f"{file_name}.tex", "r") as f:
        lines_after_runing_test: list[str] = [line.rstrip() for line in f]

    assert lines_after_runing_test[1:] == lines_befor_runing_test[1:]
    assert not success
    assert error
    assert type(error.severity_level) == int
    assert error.severity_level <= 10

def test_copy_file(simple_testfile, config_dict):
    """Tests that the working file is copied correctly."""
    file_name = simple_testfile
    new_file_name = f"{FILE_PREFIX}_{file_name}"

    success, error = operations.copy_latex_file(file_name, config_dict)
    expectedNewName: str = config_dict[enums.ConfigDictKeys.NEW_NAME.value]

    assert success
    assert not error
    assert f"{new_file_name}.tex" in os.listdir()
    assert f"{new_file_name}" == expectedNewName
    assert f"{file_name}.tex" in os.listdir()

def test_copy_file_fileNotFound(config_dict):
    """Tests that the working file is copied correctly."""

    success, error = operations.copy_latex_file("Not a testfile", config_dict)

    assert not success
    assert error
    assert type(error.severity_level) == int
    assert 20 < error.severity_level <= 30

def test_clean_working_dir(dirty_working_dir, config_dict):
    """Tests that the working dir gets cleaned properly."""

    # write a testfile which should not be removed by the method
    not_removed = "not_removed"
    with open(f"{not_removed}.tex", "w+"):
        pass

    test_file = dirty_working_dir

    success, error = operations.clean_working_dir(
        test_file,
        config_dict,
        new_file_name=test_file
    )
    current_dir = os.listdir()

    assert success
    assert not error

    for ex in ['tex', 'aux', 'pdf', 'glo', 'bib']:
        assert f"{test_file}.{ex}" not in current_dir
    assert f"{not_removed}.tex" in current_dir
    assert "DEPLOY" in current_dir
    assert f"{test_file}.pdf" in os.listdir("./DEPLOY")

def test_clean_working_dir_FolderAlreadyExists(dirty_working_dir, config_dict):
    """Tests that the function executes properly."""

    test_file = dirty_working_dir
    # Create the folder as part of the env setup
    os.mkdir("DEPLOY")

    success, error = operations.clean_working_dir(
        dirty_working_dir,
        config_dict,
        new_file_name=test_file
    )
    current_dir = os.listdir()

    assert not success
    assert error
    assert type(error.severity_level) == int
    assert error.severity_level <= 10

    for ex in ['tex', 'aux', 'pdf', 'glo', 'bib']:
        assert f"{test_file}.{ex}" not in current_dir
    assert "DEPLOY" in current_dir
    assert f"{test_file}.pdf" in os.listdir("./DEPLOY")

def test_clean_working_dir_FileInFolderAlreadyExists(dirty_working_dir,
                                                     config_dict):
    """Tests that the function executes properly."""

    # Create folder and file
    os.mkdir("DEPLOY")
    with open("DEPLOY/test_file.pdf", "w+", encoding="utf-8"):
        pass

    success, error = operations.clean_working_dir(
        dirty_working_dir,
        config_dict
    )

    assert not success
    assert error
    assert type(error.severity_level) == int
    assert error.severity_level <= 10

    files_in_deploy = os.listdir("./DEPLOY")
    print(files_in_deploy)
    assert len(files_in_deploy) == 2

def test_clean_working_dir_PdfFileNotFound(dirty_working_dir, config_dict):
    """Tests that the correct error type is thrown."""
    test_file = dirty_working_dir

    os.remove(f"{test_file}.pdf")
    success, error = operations.clean_working_dir(
        dirty_working_dir,
        config_dict
    )

    assert not success
    assert error
    assert type(error.severity_level) == int
    assert 20 < error.severity_level <= 30


import zipfile
import os
import shutil
import sys
import time

# Function to get the directory that this script resides in to use as cwd
def get_script_path():
    return os.path.dirname(os.path.realpath(sys.argv[0]))
cwd = get_script_path()

assignment = "lab02"
extensionLookingFor = ".java"
# Set up our folders to work from our current working directory
fromFolder = cwd+"/"+"submissions"+assignment
extractedFolder = cwd+"/"+"submissionsExtracted"+assignment
outFolder = cwd+"/"+assignment+"FilesMOSS"

# print(cwd)
# If output files have already been generated then delete them and their contents
try:
    shutil.rmtree(outFolder)
    shutil.rmtree(extractedFolder)
except:
    pass

os.makedirs(extractedFolder) # create folder for unziped files
os.makedirs(outFolder) #create output folder
# cwd = os.getcwd() #find current working directory

'''
Function that finds the paths to all the files in a given folder with a certian extension and returns the paths
Params:
    filepath: path to folder to search
    filetype: file extension that we want to search for
'''
def list_files(filepath, filetype):
   paths = []
   for root, dirs, files in os.walk(filepath):
      for file in files:
         if file.lower().endswith(filetype.lower()):
            paths.append(os.path.join(root, file))
   return(paths)

'''
Function that unzips all the files in the submission folder and puts them in the extractedFolder sorted into folders by student name
'''
def unzipFiles():
    for folder in os.listdir(fromFolder):
        if folder.endswith(".zip"):
            studentName = folder.split("_", 1)[0] #get student name
            try:
                with zipfile.ZipFile(fromFolder+"/"+folder, "r") as zip_ref:
                    zip_ref.extractall(extractedFolder+"/"+studentName+"/")
            except:
                print("Bad zip: "+studentName)

'''
Function that finds the java files in each student folder in our extractedFolder and copies them to our output folder and prepends the students name on the file name
'''
def copyFiles():
    files = list_files(extractedFolder, ".java")
    for file in files:
        if file.endswith(extensionLookingFor) and file.find("MACOSX") == -1:
            extractedFolderPlus = extractedFolder +"\\"
            start = file.find(extractedFolderPlus) + len(extractedFolderPlus)
            end = file.find("\\", start)
            nameOfStudent = file[start:end]
            nameOfFile = file.rsplit("\\", 1)[1]
            shutil.copy2(file, outFolder+"/"+nameOfStudent+"_"+nameOfFile)

unzipFiles()
copyFiles()


#coding:utf-8
from bs4 import  BeautifulSoup
import json
import re
import urllib.request
from scrapy.selector import Selector
#from pybloom import BloomFilter
from BloomFilter import *
class HtmlParser(object):
    def parse_content(self,response):
        #soup = BeautifulSoup(open(response, encoding='utf-8'), 'lxml')
        soup = BeautifulSoup(response.text, 'lxml')
        #用户名
        userName = soup.find("span", class_='ProfileHeader-name').get_text()
        #一句话介绍
        if soup.find("span",class_='RichText ProfileHeader-headline') ==None:
            introduction = None
        else:
             introduction =soup.find("span",class_='RichText ProfileHeader-headline').get_text()
        #居住地
        if len(soup.select('div[class="ProfileHeader-infoItem"]')) == 0 :
            location = None
        else:
            location =soup.select('div[class="ProfileHeader-infoItem"]')[0].get_text("|")
        with open('topic.txt', 'a',encoding="utf-8") as f:
            f.write('用户:%s  一句话介绍:%s  其他相关信息:%s\n' %(userName,introduction,location))
        #我关注的人的总页数
        follower_maxPage = Selector(response).xpath(".//*[@class='Button PaginationButton Button--plain'][last()]/text()").extract()
        if not follower_maxPage :
            follower_maxPage = 1
        else:
            follower_maxPage = int(follower_maxPage.pop())
            if follower_maxPage>3:
                follower_maxPage = 3
        print("follower_maxPage........",follower_maxPage)
        #用户头像
        imageUrl = soup.find("img",class_='Avatar Avatar--large UserAvatar-inner').attrs['src']
        Image_Address = 'C:/Users/zhou/PycharmProjects/zhihu-Test01/Images/%s.jpg' % (userName)
        print("Image_Address.........",Image_Address)
        if imageUrl is not None:
            urllib.request.urlretrieve(imageUrl,Image_Address)

        return userName,introduction,location,Image_Address,follower_maxPage
        # userItem.userName =userItem
        # userItem.introduction = introduction
        # userItem.other_Infos = location
        # userItem.Image_Address = 'C:/Users/zhou/PycharmProjects/zhihu-Test01/Images/%s.jpg' % (userName)

    def parse_User(self,response):
        soup = BeautifulSoup(response, 'lxml')
        #soup = BeautifulSoup(open("C:/Users/zhou/Desktop/index.html", encoding='utf-8'), 'lxml')
        url_temp = soup.find_all("a",attrs={"data-za-detail-view-element_name":"User"})
        us = set()
        users = set()
        for u in url_temp:
            if u in us:
                pass
            else:
                us.add(u)
               # user='https://www.zhihu.com%s/following'%(u.attrs['href'])
                user = u.attrs['href']
                users.add(user)
        return users

    def parse(self,response):
        if response == None:
            return None
        else:
            self.parse_content(response)
            urls = self.parse_url(response)
            return urls

    def parse_asks(self,response):
        soup = BeautifulSoup(response, 'lxml')

        if response is None:
            pass
        else:
            questionHrefs = []
            questionNames = []
            if soup.find("div", class_='QuestionItem-title') is None:
                pass
            else:
                for question_link in soup.find_all("div", class_='QuestionItem-title'):
                    questionHref = question_link.find('a').attrs['href']
                    questionName = question_link.get_text()
                    # questionHrefs = '%s;%s'%(questionHrefs,questionHref)
                    # questionNames = '%s;%s'%(questionNames,questionName)
                    questionNames.append(questionName)
                    print( 'questionNames...........', questionNames)
                return questionNames

    def parse_collections(self, response):
        soup = BeautifulSoup(response, 'lxml')
        if response is None:
            pass
        else:
            collections = []
            if soup.find("div", class_='FavlistItem-title') is None:
                pass
            else:
                collectionNames = []
                for collection_link in soup.find_all("div", class_='FavlistItem-title'):
                    collectionName = collection_link.get_text()
                    # collectionNames = '%s;%s' %(collectionNames,collectionName)
                    collectionNames.append(collectionName)
                    print('collectionNames...........', collectionNames)
                return collectionNames
    #扒取用户关注的人和关注用户的人
    def parse_followers(self, response):
        soup = BeautifulSoup(response, 'lxml')
        follower_names = []
        follower_hrefs = []
        if soup.find_all("span",class_='UserLink UserItem-name') is None:
            pass
        else:
            for soup_link in soup.find_all("span",class_='UserLink UserItem-name'):
                follower_name = soup_link.get_text()
                follower_href = soup_link.find('a').attrs['href']
                follower_names.append(follower_name)
                follower_hrefs.append(follower_href)
            return follower_hrefs,follower_names
    #扒取关注用户的人
    def parse_followee_maxPage(self,response):
        #关注该用户的用户页数
        followee_maxPage = Selector(response).xpath(".//*[@class='Button PaginationButton Button--plain'][last()]/text()").extract()
        if not followee_maxPage:
            followee_maxPage = 1
        else:
            followee_maxPage = int(followee_maxPage.pop())
            if followee_maxPage > 3:
                followee_maxPage = 3
        return followee_maxPage

    def parse_question_response(self,response,question_Id):
        bf = BloomFilter()
        #问题题目
        soup = BeautifulSoup(response, 'lxml')
        question_title = soup.find("div",class_="QuestionPage").find("meta",attrs={"itemprop":"name"}).attrs["content"]
        question_keywords = soup.find("div",class_="QuestionPage").find("meta",attrs={"itemprop":"keywords"}).attrs["content"]
        question_answerCount = soup.find("div",class_="QuestionPage").find("meta",attrs={"itemprop":"answerCount"}).attrs["content"]
        question_title_details=soup.find("div",class_="QuestionRichText--collapsed").find("span").get_text()
        question_List_item = soup.find_all("div",class_="List-item")
        comments = []
        try:
            for q_L_i in question_List_item:
                comment = {}
                # 回答者
                question_item_name = q_L_i.find("meta", attrs={"itemprop": "name"}).attrs["content"]
                # 回答
                question_item_comment = q_L_i.find("span", class_="RichText CopyrightRichText-richText").get_text()
                # 支持人数
                question_item_vote = q_L_i.find("button", class_='Button VoteButton VoteButton--up').get_text()
                comment['回答者'] = question_item_name
                comment['回答'] = question_item_comment
                comment['点赞数'] = question_item_vote

                if bf.isContains(question_Id,comment):
                    print('存在该comment',comment)
                    pass
                else:
                    print('新评论',comment)
                    bf.insert(question_Id,comment)
                    comments.append(comment)
        except:
            pass
        js = {"标题": question_title, "关键字": question_keywords, "回答数": question_answerCount, "问题说明": question_title_details,
              "回答": comments, }
        question_json = json.loads(json.dumps(js, ensure_ascii=False))
        return question_json

    def parse_question_url(self,response):
        question__urls = []
        soup = BeautifulSoup(response, 'lxml')
        question_item_name = soup.find("meta", attrs={"itemprop": "url","content":re.compile('https://www.zhihu.com/question/(\d){8}')}).attrs["content"]
    #寻找根标题(如游戏、运动等)下面的子标题
    def parse_topic_url(self,response):
        soup = BeautifulSoup(response, 'lxml')
        urls = set()
        topic_finds = soup.find_all("a",attrs={"href":re.compile('/topic/(\d){8}')})
        for topic_find in topic_finds:
            topic_url = topic_find.attrs['href']
            urls.add(topic_url)
        return urls

    def parse_topic_question_url(self,response):
        #问题题目
        soup = BeautifulSoup(response, 'lxml')
        question_links_soup = soup.find_all("a",class_='question_link')
        question_links = set()
        for question_link_soup in question_links_soup:
            question_link = question_link_soup.attrs['href']
            question_links.add(question_link)
        return question_links

if __name__ == '__main__':
    zhihu = HtmlParser()
    zhihu.parse_content()


import math
def power(x):
    return math.sqrt(x)
print(power(2))

def power2(x, n):
    if not isinstance(x, (int)):
        raise TypeError('bad operand type');
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s
print(power2(2,3))

def enroll(name, gender, city='beijing'):
    return ('name:%s'%name+'\ngender:%s'%gender+'\ncity:%s'%city)
print(enroll('admin','F'))
print(enroll('admin','F',city='wuhan'))

def add_end(a):
    a.append('End')
    return a
s=[1,2,3]
print(add_end(s))
print(add_end([]))

def add_end2(a=None):
    if a is None:
        a = []
    a.append('End')
    return a
print(add_end2())

# 可变参数
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum
print(calc(1, 3, 5, 7))
# 传入可变的参数,list或tuple参数
nums = [1, 2, 3]
print(calc(*nums))

# 关键字参数
def person (name, age, **kw):
    print('name:',name,'age:',age,'other:',kw)
person('admin',12,city='hubei',job='Engineer')

extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack',18,city=extra['city'],job=extra['job'])

# 检查关键字参数
def person2 (name,age,**kw):
    if('city'in kw):
        pass
    if('job' in kw):
        pass
    print('name:', name, 'age:', age, 'other:', kw)
person2('Makc', 24, city='Beijing', addr='Chaoyang', zipcode=123456)

# 组合
def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
f1(1, 2, 3, 'a', 'b', x=99)


import paho.mqtt.client as mqtt
from encrypt import AESCipher

def pub_msg(msg):
	broker_address = "localhost"
	broker_portno = 1883
	client = mqtt.Client()
	client.connect(broker_address, broker_portno)
	client.subscribe("TestingTopic")
	client.publish(topic = "TestingTopic", payload = AESCipher("a!m@12ith!s@i").encrypt(msg))


# -*- coding: utf-8 -*-
"""
Created on Sat Jan  2 18:15:05 2021

@author: D-RI
"""
from mpl_toolkits.mplot3d import Axes3D
import math
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
import pandas as pd
import matplotlib.cm as cmx
data = pd.read_csv("iris.csv ")

data.head()
specific_data=data[["SepalLengthCm","SepalWidthCm","PetalLengthCm","PetalWidthCm"]]
setosa=np.transpose(specific_data[0:50].to_numpy())
versicolor=np.transpose(specific_data[50:100].to_numpy())
virginica=np.transpose(specific_data[100:150].to_numpy())
input_array=np.concatenate((versicolor,setosa,virginica),axis=1)

class Som_kohonen:
    def hjfunction(self,weight,j,iteration,iteration_number):
        d=[]
        for i in range(len(weight)):
            d.append(np.linalg.norm(weight[i,:]-weight[j,:]))
        sigma_0=0.305
        sigma=sigma_0*math.exp(-1*(iteration+1)/iteration_number)
        h_ji=[]

        for x in range(len(d)):
            h_ji.append(math.exp(-1*(math.pow(d[x], 2))/2*math.pow(sigma,2)))

        return h_ji

    def c_iteration(self,c,iteration,iteration_number):
        sigma_0=0.305
        sigma=sigma_0*math.exp(-1*(iteration+1)/iteration_number)

        c_iter=c*math.exp(-1*(iteration+1)/sigma)
        return c_iter

    def neuron_win(self,weight,arrays):
        d=[]

        for i in range(len(weight)):
            d.append(np.matmul(weight[i,:],arrays.reshape(4,1)))
        d_np=np.array(d)
        max_index=np.argmax(d_np)
        # max_index = d.index(max(d))
        return max_index

    def update(self,weight,win,array,c,iteration,iteration_number):
        hj=self.hjfunction(weight,win,iteration,iteration_number)
        for i in range(len(weight)):
            for j in range(4):
                weight[i,j]=weight[i,j]+self.c_iteration(c,iteration,iteration_number)*hj[i]*(array[j]-weight[i,j])

        return weight

    def start_som(self,weight,arrays,c,iteration):

        for i in range(iteration):
            for j in range(np.size(arrays,1)):
                win_neuron=self.neuron_win(weight,arrays[:,j])
                #w_list.append(self.update(w_list[a],win_neuron,arrays[:,j],c,i,iteration))

                self.update(weight,win_neuron,arrays[:,j],c,i,iteration)

# a=np.random.rand(6,4)*40

# np.save('W_6noron', a)
W= np.load('W_6noron.npy')

def scatter3d(x,y,z, cs,f, colorsMap='jet'):
    cm = plt.get_cmap(colorsMap)
    cNorm = matplotlib.colors.Normalize(vmin=min(cs), vmax=max(cs))
    scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=cm)
    fig = plt.figure()
    ax = Axes3D(fig)
    for i in range(150):

        ax.scatter(x[i], y[i], z[i], c=scalarMap.to_rgba(cs[i]),marker=f[i])
    scalarMap.set_array(cs)
    fig.colorbar(scalarMap,label='4.boyut')
    plt.show()

c=0.5         #0.60
iteration=1000
som=Som_kohonen()
d=[]
som.start_som(W,input_array,c,iteration)

for i in range(150):
    d.append(som.neuron_win(W,input_array[:,i]))

x=input_array[0,:]
y=input_array[1,:]
z=input_array[2,:]
t=input_array[3,:]

f=[]
# for i in range(150):
#     if d[i]==3 or d[i]==0:
#         f.append("o")
#     elif d[i]==4:
#         f.append("x")
#     elif d[i]==1 or d[i]==2:
#         f.append("v")
for i in range(150):
    if d[i]==5:
        f.append("o")
    elif d[i]==2:
        f.append("x")
    elif d[i]==0 or d[i]==4:
        f.append("v")
scatter3d(x,y,z,t,f)


import torch
import torch.nn as nn
from model import TextCNN, TextRNN, RNN_Attention, bert

class Ensemble(nn.Module):
    def __init__(self, config):
        super(Ensemble, self).__init__()
        self.config = config

        self.TextCNN = TextCNN.TextCNN(config)
        self.bert = bert.BERT(config)

        num_class = 23
        # dim_embedding = args.CNN_dim_embedding * 8 + args.RNN_dim_embedding * 2 * 2 + args.d_model
        dim_embedding = 128 + 768

        # print('dim_embedding', dim_embedding)
        self.linear1 = nn.Linear(dim_embedding, dim_embedding // 2)
        self.relu = nn.ReLU()
        self.sigmoid = nn.Sigmoid()
        self.leakyrelu = nn.LeakyReLU()
        self.linear2 = nn.Linear(dim_embedding // 2, num_class)

    def forward(self, data):
        _, TextCNN_embedding = self.TextCNN(data)
        bert_embedding = self.bert(data)["pooler_output"]

        # embeddings = [embedding1, embedding2, embedding3, embedding4]
        embeddings = [TextCNN_embedding, bert_embedding]

        # print('input_ids', input_ids.size())
        # print('embedding1', embedding1.size())
        # print('embedding2', embedding2.size())

        embeddings = torch.cat(embeddings, dim=-1)
        # print('embeddings', embeddings.size())

        out = self.linear1(embeddings)
        out = self.leakyrelu(out)
        logits = self.linear2(out)
        return logits, bert_embedding


import sys
from typing import IO, Tuple, Callable, Dict, Any, Optional
import spacy
from spacy import Language
from pathlib import Path

@spacy.registry.loggers("custom_logger.v1")
def custom_logger(log_path):
    def setup_logger(
        nlp: Language,
        stdout: IO=sys.stdout,
        stderr: IO=sys.stderr
    ) -> Tuple[Callable, Callable]:
        stdout.write(f"Logging to {log_path}\n")
        log_file = Path(log_path).open("w", encoding="utf8")
        log_file.write("step\t")
        log_file.write("score\t")
        for pipe in nlp.pipe_names:
            log_file.write(f"loss_{pipe}\t")
        log_file.write("\n")

        def log_step(info: Optional[Dict[str, Any]]):
            if info:
                log_file.write(f"{info['step']}\t")
                log_file.write(f"{info['score']}\t")
                for pipe in nlp.pipe_names:
                    log_file.write(f"{info['losses'][pipe]}\t")
                log_file.write("\n")

        def finalize():
            log_file.close()

        return log_step, finalize

    return setup_logger


from PIL import Image, ImageDraw, ImageFont

# Create Image object with the input image

try:
    image = Image.open('background.png')
    print("All done loading!")
except Exception as e:
    print("Something went wrong", e)

# Initialize the drawing context
# The image object as background

draw = ImageDraw.Draw(image)

# Create font object with the font file and specify
# desired size

font = ImageFont.truetype('UDDigiKyokashoN-B.ttc', size=46)

# Tuple that represents the position of the message

(x, y) = (100, 75)

message = "宜しくお願い致します！"
black_color = "rgb(100, 0, 100)" # Black

# draw the image on the background

draw.text((x,y), message, fill=black_color, font=font, align="center")

(x2, y2) = (150, 150)
name = "ケーシーさん"
white_color = "rgb(255, 255, 225)" # White
draw.text((x2, y2), name, fill=white_color, font=font, align="center")

# Save the edited image!

image.save('greeting_card.png')


print("This is my very first line!!")

def counting(A, m) :
    n = len(A)
    count = [0] * (m + 1)
    for k in range(n) :
        count[A[k]] += 1
    return count

print (counting([5,5,6,9,1,3,22,32,1,3], 33))


# -*- coding: utf-8 -*-

from __future__ import division

import numpy as np
import pytest

from FTRLprox.models import FTRLprox
from FTRLprox.models import OGDLR
from FTRLprox.models import SEED
from FTRLprox.utils import logloss
from tutils import ogdlr_before
from tutils import ogdlr_after
from tutils import ftrl_before
from tutils import ftrl_after
from tutils import hash_before
from tutils import hash_after
from tutils import nn_before
from tutils import nn_after
from tutils import X
from tutils import y

def test_FTRL_learns():
    # test that this model learns something
    y_pred = ftrl_before.predict_proba(X)
    ll_before = logloss(y, y_pred)

    y_pred = ftrl_after.predict_proba(X)
    ll_after = logloss(y, y_pred)

    assert ll_before > ll_after

def test_ogdlr_learns():
    # test that this model learns something
    y_pred = ogdlr_before.predict_proba(X)
    ll_before = logloss(y, y_pred)

    y_pred = ogdlr_after.predict_proba(X)
    ll_after = logloss(y, y_pred)
    assert ll_before > ll_after

def test_ogdlr_with_hash_learns():
    # test that this model learns something
    y_pred = hash_before.predict_proba(X)
    ll_before = logloss(y, y_pred)

    y_pred = hash_after.predict_proba(X)
    ll_after = logloss(y, y_pred)

    assert ll_before > ll_after

def test_nn_learns():
    # test that this model learns something
    y_pred = nn_before.predict_proba(X)
    ll_before = logloss(y, y_pred)

    y_pred = nn_after.predict_proba(X)
    ll_after = logloss(y, y_pred)

    assert ll_before > ll_after

def test_models_same_predictions():
    # for lambda1, lambda2 = 0, OGDLR and FTRLprox should generate the
    # same result. The same goes if hashing is used (except for the
    # rare case of hash collisions. A neural net does not necessarily
    # predict exactly the same outcome.
    y_f = ftrl_after.predict_proba(X)
    y_o = ogdlr_after.predict_proba(X)
    y_h = hash_after.predict_proba(X)
    assert np.allclose(y_f, y_o, atol=1e-15)
    assert np.allclose(y_f, y_h, atol=1e-15)

def test_effect_of_alpha():
    # higher alpha should lead to faster learning, thus higher weights
    mean_abs_weights = []
    for alpha in [0, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1, 1e1]:
        clf = OGDLR(alpha=alpha)
        clf.fit(X[:100], y[:100])
        mean_abs_weights.append(np.abs(clf.weights()).mean())
    assert mean_abs_weights[0] == 0.
    assert all(np.diff(mean_abs_weights) > 0)

def test_effect_of_beta():
    # higher beta should lead to slower learning, thus lower weights
    mean_abs_weights = []
    for beta in [10 ** n for n in range(7)]:
        clf = OGDLR(beta=beta)
        clf.fit(X[:100], y[:100])
        mean_abs_weights.append(np.abs(clf.weights()).mean())
    assert np.allclose(mean_abs_weights[-1], 0, atol=1e-6)
    assert all(np.diff(mean_abs_weights) < 0)

@pytest.mark.parametrize('lambda1', [1 / lam for lam in range(1, 6)])
def test_effect_of_lambda1(lambda1):
    # gradients should be the same regardless of magnitude of weights
    weights = range(-5, 0) + range(1, 6)
    clf = OGDLR(lambda1=lambda1)
    grads = clf._get_grads(0, 0, weights)
    # gradient only depends on sign of weight
    abso = [gr * np.sign(w) for gr, w in zip(grads, weights)]
    assert np.allclose(abso[0], abso)

    # contingency test: should fail
    frac = [gr / w for gr, w in zip(grads, weights)]
    with pytest.raises(AssertionError):
        assert np.allclose(frac[0], frac)

@pytest.mark.parametrize('lambda2', [1 / lam for lam in range(1, 6)])
def test_effect_of_lambda2(lambda2):
    # relative difference in gradients should be the same
    weights = range(-5, 0) + range(1, 6)
    clf = OGDLR(lambda2=lambda2)
    grads = clf._get_grads(0, 0, weights)
    # gradient is proportional to weights
    frac = [gr / w for gr, w in zip(grads, weights)]
    assert np.allclose(frac[0], frac)

    # contingencey test: should fail
    abso = [gr * np.sign(w) for gr, w in zip(grads, weights)]
    with pytest.raises(AssertionError):
        assert np.allclose(abso[0], abso)


from typing import Union, Any

import aiohttp

from lmk.utils.ws import WebSocket

async def send_signal(socket_path: str, signal: Union[str, int]) -> None:
    connector = aiohttp.UnixConnector(path=socket_path)
    async with aiohttp.ClientSession(connector=connector) as session:
        async with session.post(
            "http://daemon/signal", json={"signal": signal}
        ) as response:
            if response.status == 200:
                return
            raise ResponseError(response.status, await response.text())

async def set_notify_on(socket_path: str, notify_on: str) -> None:
    connector = aiohttp.UnixConnector(path=socket_path)
    async with aiohttp.ClientSession(connector=connector) as session:
        async with session.post(
            "http://daemon/set-notify-on", json={"notify_on": notify_on}
        ) as response:
            if response.status == 200:
                return
            raise ResponseError(response.status, await response.text())

async def wait_for_job(socket_path: str, wait_for: str = "run") -> Any:
    connector = aiohttp.UnixConnector(path=socket_path)
    async with aiohttp.ClientSession(connector=connector) as session:
        async with WebSocket(session, f"http://daemon/wait?wait_for={wait_for}") as ws:
            async for message in ws:
                if not message["ok"]:
                    raise Exception(f"{message['error_type']}: {message['error']}")
                return message

class ResponseError(Exception):
    """ """

    def __init__(self, status: int, data: str) -> None:
        self.status = status
        self.data = data
        super().__init__(f"Request failed with status {status}: {data}")


#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
## Player module: main module

from properties import Properties
from song import Song
from threading import Timer
import sys
import xbmc
import xbmcgui

class XBMCPlayer(xbmc.Player):
    """
        Subclass of XBMC Player class.
        Overrides onplayback* events, for custom actions.
    """
    def __init__(self, *args, **kwargs):
        # initialize our super classes
        xbmc.Player.__init__(self)

    def onPlayBackStarted(self):
        # handle start event
        self.handle_onplayback_event("onPlayBackStarted")

    def onQueueNextItem(self):
        # handle queuing event, we just pass as started will handle song change
        # TODO: test to see if this is a better event than started
        self.handle_onplayback_event("onQueueNextItem")

    def onPlayBackStopped(self):
        # handle stopped event
        self.handle_onplayback_event("onPlayBackStopped")

    def onPlayBackEnded(self):
        # handle ended event
        self.handle_onplayback_event("onPlayBackEnded")

    def onPlayBackPaused(self):
        # handle paused event
        self.handle_onplayback_event("onPlayBackPaused")

    def onPlayBackResumed(self):
        # handle resumed event
        self.handle_onplayback_event("onPlayBackResumed")

    def onPlayBackSpeedChanged(self, speed):
        # handle FF/RW event
        self.handle_onplayback_event("onPlayBackSpeedChanged", speed)

    def onPlayBackSeek(self, _time, offset):
        # handle seek event
        self.handle_onplayback_event("onPlayBackSeek", (_time, offset,))

    def onPlayBackSeekChapter(self, chapter):
        # handle chapter seek event
        self.handle_onplayback_event("onPlayBackSeekChapter", chapter)

class Player(XBMCPlayer, Properties):
    # window for setting lyrics properties
    WINDOW = xbmcgui.Window(12006)
    # control id's
    CONTROL_LIST = 110
    CONTROL_SAVE_LYRICS = 606
    # FIXME: is 20 seconds a good time?
    PREFETCH_DELAY_TIME = 20

    def __init__(self, *args, **kwargs):
        # set addon object
        self.m_addon = kwargs["addon"]
        # passing "<windowId>" from RunScript() means run in background
        self.use_gui = kwargs["gui"]
        # initialize our super classes
        XBMCPlayer.__init__(self)
        Properties.__init__(self)
        # initialize timers
        self._lyric_timer = None
        self._fetch_timer = None
        # log started action
        self._log_addon_action("started")
        # initialize our Song class
        self.song = Song(addon=self.m_addon)
        # initialize our prefetched Song class
        # TODO: remove the self.isPlayingAudio() check when/if XBMC supports offset for player
        self.prefetched_song = None
        if (self.m_addon.getSetting("prefetch_lyrics") and self.isPlayingAudio()):
            self.prefetched_song = Song(addon=self.m_addon, prefetch=True)
        # start
        if (self.use_gui):
            self._start_gui()
        else:
            self._start_background()

    def _log_addon_action(self, action):
        # log addon info
        xbmc.log("{0:-<80}".format(""), xbmc.LOGNOTICE)
        xbmc.log(
            u"[ADD-ON] - {name!r} has {action}! [{mode}]".format(
            name=self.m_addon.getAddonInfo("Name"),
            action=action,
            mode=["BACKGROUND MODE (window={id})".format(
                id=sys.argv[-1]), "GUI MODE"][self.use_gui]),
            xbmc.LOGNOTICE
        )
        xbmc.log(
            u"{0: <12}Id: {id} - Type: {type} - Version: {version}".format(
            "",
            id=self.m_addon.getAddonInfo("Id"),
            type=self.m_addon.getAddonInfo("Type"),
            version=self.m_addon.getAddonInfo("Version")),
            xbmc.LOGNOTICE
        )
        xbmc.log("{0:-<80}".format(""), xbmc.LOGNOTICE)

    def _start_gui(self):
        # import GUI class
        from resources.lib.gui import GUI
        # set our GUI class
        self._gui = GUI(
            "custom_lyrics.xbmc_lyrics-gui.xml",
            self.m_addon.getAddonInfo("Path"), "default", "720p",
            player=self
        )
        # show dialog
        self._gui.doModal()
        # free memory
        del self._gui
        # cancel any running timers
        # FIXME: why is this necessary now. before subclass changes this was unnecessary
        self.cancel_timers()

    def _start_background(self):
        # set to True so script will continue
        self._loop = True
        # set window id
        self.window_id = int(sys.argv[1]) + 10000
        # get list control if skinner included one
        try:
            window = xbmcgui.Window(self.window_id)
            listcontrol = window.getControl(self.CONTROL_LIST)
        except Exception:
            listcontrol = None
        # start
        self.startup(listcontrol)
        # loop here to keep script running
        while not xbmc.abortRequested and self._loop:
            # 100 msecs seems like a good number FIXME: play with this
            xbmc.sleep(100)
        # FIXME: why is this necessary now. before subclass changes this was unnecessary
        self.cancel_timers()

    def startup(self, listcontrol=None):
        # set listcontrol object if one exists and user preference is to support scrolling lyrics
        self.listcontrol = [None, listcontrol][self.m_addon.getSetting("enable_karaoke_mode")]
        # start
        self.onPlayBackStarted()

    def handle_onplayback_event(self, event, *args):
        # cancel any timers, (we don't want to cancel timers on queue next item
        #                     XBMC queues next item during onQueueNextItem event
        #                     and cross fading would interrupt scrolling lyrics.)
        if (event != "onQueueNextItem"):
            self.cancel_timers()
        # log event
        xbmc.log(
            "XBMCPlayer::handle_onplayback_event (Event: {event: <35} Playing: {media})".format(
                event="{name} {args}".format(name=event, args=["", "args={0}".format(args)][args != ()]),
                media=["(none)", "Audio", "Video"][int(self.isPlayingAudio()) + (int(self.isPlayingVideo()) * 2)]),
            xbmc.LOGNOTICE
        )
        # on these event there is nothing to do
        if (event in ["onQueueNextItem", "onPlayBackPaused", "onPlayBackSeek", "onPlayBackSeekChapter"]):
            pass
        # on song change fetch lyrics
        elif (event == "onPlayBackStarted"):
            # log title and artist
            xbmc.log(
                u"{0: <36}(Title: {title!r: <36} Artist: {artist!r})".format(
                    "",
                    title=unicode(xbmc.getInfoLabel("MusicPlayer.Title"), "UTF-8"),
                    artist=unicode(xbmc.getInfoLabel("MusicPlayer.Artist"), "UTF-8")),
                xbmc.LOGNOTICE
            )
            # do we have any unsaved tagged lyrics
            if (self.use_gui):
                self._gui._save_user_tagged_lyrics(ask=True)
            # set new timer (we use this in case user is skipping thru playlist)
            self._fetch_timer = Timer(self.m_addon.getSetting("fetch_lyrics_delay") / 1000, self._fetch_lyrics)
            # start timer
            self._fetch_timer.start()
        # on resume from FF/RW we need to reset any timers
        elif (event == "onPlayBackResumed"):
            # update lyric if karaoke mode is enabled
            self._update_lyric()
        # on speedchanged?
        elif (event == "onPlayBackSpeedChanged"):
            # if speed==1 (resumed) we need to update lyrics
            if (args[0] == 1):
                self._update_lyric()
        # if music has ended we want to clear lyrics
        elif (event in ["onPlayBackStopped", "onPlayBackEnded"]):
            # give time for XBMC in case a glitch in a song fired the event
            # (only seems to happen with cross-fading enabled)
            # TODO: determine if this just needs to be hard coded
            xbmc.sleep(int(self.m_addon.getSetting("fetch_lyrics_delay")))
            # if we're still playing continue
            if (self.isPlaying()): return
            # finish up
            self.finish_up()

    def _set_properties(self, lyrics="", tags=list(), lrc_lyrics=False, message="", website="", status=True, prefetched=False):
        # set window properties
        self.set_properties(lyrics, tags, lrc_lyrics, message, website, status, prefetched)
        # only need to fill lyrics list control if lyrics exist, otherwise we just use textbox to display messages.
        if (self.song.m_song.lyrics is not None):
            # fill list if karaoke mode is enabled
            self._set_karaoke_lyrics()  #lyrics, tags)

    def _set_karaoke_lyrics(self):  #, lyrics, tags):
        # if no list control or not user preference skip
        if (self.listcontrol is None or
                not self.m_addon.getSetting("enable_karaoke_mode") or
                (not self.use_gui and not xbmc.getCondVisibility("Window.IsActive({id})".format(id=self.window_id)))):
            return
        # clear list
        self.listcontrol.reset()
        # add lyrics
        self.listcontrol.addItems(self.song.m_song.lyrics.splitlines())
        # select proper lyric
        self._update_lyric()

    def _update_lyric(self):
        # if no time tags, return
        if (not self.isPlaying() or not self.song.m_song.lyrics_tags or self.listcontrol is None or
                not self.m_addon.getSetting("enable_karaoke_mode") or
                (not self.use_gui and not xbmc.getCondVisibility("Window.IsActive({id})".format(id=self.window_id)))):
            return
        #FIXME: make sure this is necessary, I don't believe it is
        # cance only lyric timer
        self.cancel_timers(fetch=False)
        # get current time
        current = self.getTime()
        # get position
        pos = [count for count, tag in enumerate(self.song.m_song.lyrics_tags + [current + 1]) if (tag > current)][0]
        # select listitem
        self.listcontrol.selectItem(pos - 1)
        # return if no more lyrics
        if (pos == len(self.song.m_song.lyrics_tags)): return
        # calculate update time, additional time necessary to limit the number of repeat timer events
        update = self.song.m_song.lyrics_tags[pos] - current + 0.02
        # set new timer
        self._lyric_timer = Timer(update, self._update_lyric)
        # start timer
        self._lyric_timer.start()

    def cancel_timers(self, fetch=True):
        # if there's a timer cancel it
        if (self._lyric_timer is not None):
            self._lyric_timer.cancel()
        if (self._fetch_timer is not None and fetch):
            self._fetch_timer.cancel()

    def _fetch_lyrics(self):
        # set fetching lyrics message
        self._set_properties(
            message=self.m_addon.getLocalizedString(30800).format(
            title=unicode(xbmc.getInfoLabel("MusicPlayer.Title"), "UTF-8"))
        )
        # if prefetching failed, we go straight to song list
        songlist = self.prefetched_song is not None and not self.prefetched_song.m_song.status
        # fetch lyrics
        self.song.get_song_info(songlist=songlist)
        # set lyrics and messages
        self._set_properties(
            self.song.m_song.lyrics,
            self.song.m_song.lyrics_tags,
            self.song.m_song.lrc_lyrics,
            self.song.m_song.message,
            self.song.m_song.website,
            self.song.m_song.status,
            self.song.m_song.prefetched
        )
        # prefetch next song
        if (self.prefetched_song is not None and xbmc.getCondVisibility("MusicPlayer.HasNext")):
            # set new prefetch delay timer
            self._fetch_timer = Timer(
                self.PREFETCH_DELAY_TIME,
                self._prefetch_lyrics,
                (self.song.m_song.message, self.song.m_song.website, self.song.m_song.status, self.song.m_song.prefetched,)
            )
            # start timer
            self._fetch_timer.start()

    def _prefetch_lyrics(self, message, website, status, prefetched):
        # set prefetching message
        self.set_info_properties(
            message=self.m_addon.getLocalizedString(30805).format(
                title=unicode(xbmc.getInfoLabel("MusicPlayer.Offset(1).Title"), "UTF-8")),
            status=status,
            prefetching=True
        )
        # fetch next songs lyrics
        self.prefetched_song.get_song_info()
        # set previous properties
        self.set_info_properties(message, website, status, prefetched)

    def save_user_tagged_lyrics(self, lyrics):
        # set default saved lyrics message
        self.song.m_song.message = self.m_addon.getLocalizedString(30863)
        # set song's lyrics
        self.song.m_song.lyrics = lyrics
        # save lyrics
        self.song.save_lyrics()
        # set new message
        self._set_properties(lyrics=None, message=self.song.m_song.message)

    def finish_up(self):
        # cancel any timer
        self.cancel_timers()
        # close dialog
        if (self.use_gui):
            # close the GUI
            self._gui.close_dialog()
        else:
            # set to False so script will exit
            self._loop = False
            # close window
            xbmc.executebuiltin("Dialog.Close({id})".format(id=self.window_id))
        # clear existing properties
        self._set_properties()
        # log ended action
        self._log_addon_action("ended")


from cs50 import get_float

while True:
    owed = get_float("Change owed: ")
    if owed > 0:
        break

owed = int(owed*100)

coins = 0
for i in [25, 10, 5, 1]:
    while owed >= i:
        owed -= i
        coins += 1

print(coins)


from keras.models import Model
from keras import layers
from keras.layers import Dense, Input, BatchNormalization, Activation
from keras.layers import Conv2D, SeparableConv2D, MaxPooling2D, GlobalAveragePooling2D, GlobalMaxPooling2D
import keras
from keras.regularizers import l2
from keras.layers import GlobalAveragePooling2D, GlobalMaxPooling2D, Reshape, Dense, multiply, Permute, Concatenate, \
    Conv2D, Add, Activation, Lambda
import keras.backend as K

def cbam_block(cbam_feature, ratio=16):
    """Contains the implementation of Convolutional Block Attention Module(CBAM) block.
    As described in https://arxiv.org/abs/1807.06521.
    """

    cbam_feature = channel_attention(cbam_feature, ratio)  # 通道维度
    cbam_feature = spatial_attention(cbam_feature)  # 空间维度
    return cbam_feature

# 通道维度
def channel_attention(input_feature, ratio=8):
    # 获取当前的维度顺序

    channel = input_feature._keras_shape[-1]

    # shareMLP-W0
    shared_layer_one = Dense(channel // ratio,
                             activation='relu',
                             kernel_initializer='he_normal',
                             use_bias=True,
                             bias_initializer='zeros')
    # shareMLP-W1
    shared_layer_two = Dense(channel,
                             kernel_initializer='he_normal',
                             use_bias=True,
                             bias_initializer='zeros')
    # 经过全局平均池化
    avg_pool = GlobalAveragePooling2D()(input_feature)
    avg_pool = Reshape((1, 1, channel))(avg_pool)
    assert avg_pool._keras_shape[1:] == (1, 1, channel)  # [1:]分片操作，shape（1,1,1,channel）——>（1,1,channel）
    # assert断言操作，如果为false抛出异常

    # 经过W1
    avg_pool = shared_layer_one(avg_pool)
    assert avg_pool._keras_shape[1:] == (1, 1, channel // ratio)
    # 经过W2
    avg_pool = shared_layer_two(avg_pool)
    assert avg_pool._keras_shape[1:] == (1, 1, channel)

    # 经过全局最大池化
    max_pool = GlobalMaxPooling2D()(input_feature)
    max_pool = Reshape((1, 1, channel))(max_pool)
    assert max_pool._keras_shape[1:] == (1, 1, channel)
    # 经过W1
    max_pool = shared_layer_one(max_pool)
    assert max_pool._keras_shape[1:] == (1, 1, channel // ratio)
    # 经过W2
    max_pool = shared_layer_two(max_pool)
    assert max_pool._keras_shape[1:] == (1, 1, channel)

    # 逐元素相加，sigmoid激活
    cbam_feature = Add()([avg_pool, max_pool])
    cbam_feature = Activation('sigmoid')(cbam_feature)

    # 逐元素相乘，得到下一步空间操作的输入feature
    return multiply([input_feature, cbam_feature])

# 空间维度
def spatial_attention(input_feature):
    kernel_size = 7  # 卷积核7x7

    channel = input_feature._keras_shape[-1]  # 取最后一个元素（channel）
    cbam_feature = input_feature

    # 经过平均池化
    avg_pool = Lambda(lambda x: K.mean(x, axis=3, keepdims=True))(cbam_feature)
    # axis等于几，就理解成对那一维值进行压缩；二维矩阵（0为列1为行），x为四维矩阵（1,h,w,channel）所以axis=3，对矩阵每个元素求平均；
    # keepdims保持其矩阵二维特性
    assert avg_pool._keras_shape[-1] == 1  # 检验channel压缩为1

    # 经过最大池化
    max_pool = Lambda(lambda x: K.max(x, axis=3, keepdims=True))(cbam_feature)
    assert max_pool._keras_shape[-1] == 1

    # 从channel维度进行拼接
    concat = Concatenate(axis=3)([avg_pool, max_pool])
    assert concat._keras_shape[-1] == 2  # 检验channel为2

    # 进行卷积操作
    cbam_feature = Conv2D(filters=1,
                          kernel_size=kernel_size,
                          strides=1,
                          padding='same',
                          activation='sigmoid',
                          kernel_initializer='he_normal',
                          use_bias=False)(concat)
    assert cbam_feature._keras_shape[-1] == 1

    # 逐元素相乘，得到feature
    return multiply([input_feature, cbam_feature])

def Xception(img_rows, img_cols, channel, num_class):
    input_shape = (img_rows, img_cols, channel)
    input_img = Input(shape=input_shape)

    # block 1
    x = Conv2D(32, (3, 3), strides=(2, 2), use_bias=False)(input_img)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = Conv2D(64, (3, 3), use_bias=False)(x)
    x = BatchNormalization()(x)
    cbam_block(x,16)
    x = Activation('relu')(x)
    x_1 = x

    residual = Conv2D(128, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
    residual = BatchNormalization()(residual)

    # block 2
    x = SeparableConv2D(128, (3, 3), padding='same', use_bias=False)(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = SeparableConv2D(128, (3, 3), padding='same', use_bias=False)(x)
    x = BatchNormalization()(x)
    x = cbam_block(x, 16)

    x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)
    x = layers.add([x, residual])
    x_2 = x

    residual = Conv2D(256, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
    residual = BatchNormalization()(residual)

    # block 3
    x = Activation('relu')(x)
    x = SeparableConv2D(256, (3, 3), padding='same', use_bias=False)(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = SeparableConv2D(256, (3, 3), padding='same', use_bias=False)(x)
    x = BatchNormalization()(x)
    x = cbam_block(x, 16)

    x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)
    x = layers.add([x, residual])
    x_3 = x

    residual = Conv2D(728, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
    residual = BatchNormalization()(residual)

    # block 4
    x = Activation('relu')(x)
    x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False)(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False)(x)
    x = BatchNormalization()(x)
    x = cbam_block(x, 16)

    x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)
    x = layers.add([x, residual])
    x_4 = x

    x_concat_1 = keras.layers.AveragePooling2D((3, 3), strides=(2, 2), padding='same')(x_1)
    x_concat_12 = keras.layers.concatenate([x_concat_1, x_2], axis=-1)
    x_concat_12_res = keras.layers.AveragePooling2D((3, 3), strides=(2, 2), padding='same')(x_concat_12)
    x_concat_123 = keras.layers.concatenate([x_concat_12_res, x_3], axis=-1)
    x_concat_123_res = keras.layers.AveragePooling2D((3, 3), strides=(2, 2), padding='same')(x_concat_123)
    x_concat = keras.layers.concatenate([x_concat_123_res, x_4], axis=-1)
    #x_concat = Conv2D(2048, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x_concat)

    x_concat = GlobalAveragePooling2D()(x_concat)

    # 循环
    for i in range(8):
        residual = x

        x = Activation('relu')(x)
        x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False)(x)
        x = BatchNormalization()(x)
        x = Activation('relu')(x)
        x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False)(x)
        x = BatchNormalization()(x)
        x = Activation('relu')(x)
        x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False)(x)
        x = BatchNormalization()(x)
        x = cbam_block(x, 16)

        x = layers.add([x, residual])

    # ========EXIT FLOW============
    residual = Conv2D(1024, (1, 1), strides=(2, 2), padding='same', use_bias=False)(x)
    residual = BatchNormalization()(residual)

    x = Activation('relu')(x)
    x = SeparableConv2D(728, (3, 3), padding='same', use_bias=False)(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)
    x = SeparableConv2D(1024, (3, 3), padding='same', use_bias=False)(x)
    x = BatchNormalization()(x)
    x = cbam_block(x, 16)

    x = MaxPooling2D((3, 3), strides=(2, 2), padding='same')(x)
    x = layers.add([x, residual])

    x = SeparableConv2D(1536, (3, 3), padding='same', use_bias=False)(x)
    x = BatchNormalization()(x)
    x = Activation('relu')(x)

    x = SeparableConv2D(2048, (3, 3), padding='same', use_bias=False,name='separable')(x)
    x = BatchNormalization()(x)
    x = cbam_block(x, 16)
    x = Activation('relu')(x)

    x = GlobalAveragePooling2D(name='globave')(x)
    x = keras.layers.concatenate([x, x_concat], axis=-1)  #0
    x = Dense(2048, activation='relu', kernel_regularizer=l2(0.0001))(x)
    x = keras.layers.Dropout(0.7)(x)                       #1
    x = Dense(1024, activation='relu', kernel_regularizer=l2(0.0001))(x)
    x = keras.layers.Dropout(0.5)(x)
    x = Dense(num_class,kernel_initializer='he_normal',activation='softmax')(x)
    model = Model(input_img, x, name='xception_agg')

    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer=keras.optimizers.Adam(lr=0.00001, decay=0.000001), metrics=['accuracy'])
    return model


import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Activation
from keras.layers import Conv2D, MaxPooling2D
from keras.utils.vis_utils import plot_model
from keras.utils import np_utils
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('../data')

X_train, Y_train = mnist.train.images, mnist.train.labels
X_test, Y_test = mnist.test.images, mnist.test.labels

Y_train = np_utils.to_categorical(Y_train,num_classes=10)
Y_test = np_utils.to_categorical(Y_test,num_classes=10)

X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)

# Build LeNet-5
model = Sequential()
model.add(Conv2D(filters=6, kernel_size=(5, 5), padding='valid', input_shape=(28, 28, 1), activation='tanh')) # C1
model.add(MaxPooling2D(pool_size=(2, 2))) # S2
model.add(Conv2D(filters=16, kernel_size=(5, 5), padding='valid', activation='tanh')) # C3
model.add(MaxPooling2D(pool_size=(2, 2))) # S4
model.add(Flatten())
model.add(Dense(120, activation='tanh')) # C5
model.add(Dense(84, activation='tanh')) # F6
model.add(Dense(10, activation='softmax')) # output
model.summary()

model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
model.fit(X_train, Y_train, batch_size=500, epochs=10, verbose=1, validation_data=(X_test, Y_test))
model.save('cnn_fashion_mnist.h5')

loss, accuracy = model.evaluate(X_test, Y_test, verbose=0)
print('loss:', loss)
print('accuracy:', accuracy)


import pytest
import main
# import os
import logging

logger = logging.getLogger(__name__)

@pytest.fixture(autouse=True)
def set_env_vars(monkeypatch):
    with open('./tests/mocks/mock-creds.json', 'r') as f:
        fake_credentials = f.read()
    monkeypatch.setenv('GOOGLE_CREDS', fake_credentials)
    monkeypatch.setenv('GCP_PROJECT_ID', "fake-gcp-project")
    monkeypatch.setenv('INSTANCE_INTERVAL', '600')

# def test_create_costs_report(mocker, monkeypatch, tmp_path):

#     test_file = "platform-costs.pytest.md"

#     monkeypatch.setenv('OUTPUT_DIR', str(tmp_path))
#     monkeypatch.setenv('REPORT_FILE', test_file)

#     test_data = [
#         ['project-1-flex', 201905, 1.64],
#         ['project-1-flex', 201906, 0.37],
#         ['project-1-prod', 201905, 1.65],
#         ['project-1-prod', 201906, 0.37],
#         ['project-2-test', 201805, 2.51],
#         ['project-2-test', 201806, 4.96],
#         ['project-2-prod', 201807, 4.98],
#         ['project-2-prod', 201808, 4.77]
#     ]

#     df = pd.DataFrame(test_data)
#     df.columns = (['project', 'month', 'spend'])

#     stub_project_list = mocker.patch('main.list_projects')
#     stub_project_list.return_value = ['project-1-flex', 'project-1-prod']

#     main.create_costs_report(df)

#     f = open(tmp_path / test_file, "r")
#     result = f.read()
#     f.close()

#     assert "title: " in result
#     assert "Last Generated" in result
#     assert "weight: " in result

#     # these tests may be brittle if wording changes a lot - consider removing
#     assert "JLDP v1 Costs" in result
#     assert "version 1 platform runs" in result
#     assert "JLDP v2 Tenant Costs" in result
#     assert "GCP services outside" in result
#     assert "JLDP v2 Platform Costs" in result
#     assert "includes costs" in result
#     assert "Other JL Commerce Projects" in result
#     assert "not treated as JLDP projects" in result

# def test_create_cost_charts(mocker, monkeypatch, tmp_path):

#     monkeypatch.setenv('OUTPUT_DIR', str(tmp_path))

#     stub_project_list = mocker.patch('main.list_projects')
#     stub_project_list.return_value = ['project-1-flex', 'project-1-prod']

#     test_data = "./tests/mocks/raw_df.csv"
#     df = pd.read_csv(test_data, index_col=0)

#     main.create_cost_charts(df)

#     # Note that with this test we are not checking the content of the png is valid!
#     num_png_files = len([f for f in os.listdir(tmp_path)
#                          if f.endswith('.png') and os.path.isfile(os.path.join(tmp_path, f))])
#     # could turn out to be brittle - 4 sections in the SECTIONS static in main.py
#     assert num_png_files == 4

# def test_main_no_args(mocker):
#     mocker.patch('main.list_projects')
#     mocker.patch('main.query_monthly_spend')
#     mocker.patch('main.create_cost_charts')
#     mocker.patch('main.create_costs_report')

#     runner = CliRunner()
#     result = runner.invoke(main.main)

#     assert result.output == 'No project specified - reporting on all projects\n'

# def test_main_with_project(mocker):
#     mocker.patch('main.list_projects')
#     mocker.patch('main.query_monthly_spend')
#     mocker.patch('main.create_cost_charts')
#     mocker.patch('main.create_costs_report')

#     runner = CliRunner()
#     result = runner.invoke(main.main, ['--project', 'jl-platform-k8s-verify'])

#     assert result.output == 'Building report for jl-platform-k8s-verify project\n'

def test_init(mocker):
    # run wrapper validity: https://medium.com/opsops/how-to-test-if-name-main-1928367290cb
    mocker.patch.object(main, "main", return_value=42)
    mocker.patch.object(main, "__name__", "__main__")
    mocker.patch.object(main.sys, 'exit')
    main.init()
    assert main.sys.exit.call_args[0][0] == 42


from PIL import Image
import matplotlib.pyplot as plt

#%%
file_path = "/JSY/images/bichon02.jpg"
img = Image.open(file_path)
print(type(img))

plt.imshow(img)
plt.axis("off")
plt.show()


# This is a profit prediction calculator
# 091119
# CTI-110 P2T2 - Sales Prediction
# Ryan Cox

#get value of projected sales
totalSales = float(input('Enter projected sales:'))

#calculate profit
profit = totalSales * 0.23

#display projected profit
print('The profit is $', format(profit, ',.2f'))


import requests
import base64
import json
import sys
from csv import reader

if len(sys.argv) != 3:
    print("incorrect command format. Should be:\n" + sys.argv[0] + " <csv file location> <name of target kafka topic>")
    exit(1)

topic = sys.argv[2]
url = "http://localhost:8082/topics/" + str(topic)

headers = {
'Content-Type': 'application/vnd.kafka.json.v2+json',
'Accept': 'application/vnd.kafka.v2+json',
}

file_location = sys.argv[1]

with open(file_location, 'rt') as sourceFile:

    res = reader(sourceFile, delimiter=',', quotechar='"')

    csv_headers = next(res, None)

    row_values = {}

    for line in res:

        for i in range(len(csv_headers)):
            header = csv_headers[i]
            row_values[header] = line[i]

        payload = {"records":
               [{
                   "value":row_values
               }]
        }

        # Send the message
        r = requests.post(url, headers=headers, data=json.dumps(payload))
        if r.status_code != 200:
           print("An error ocurred")
           print("Status Code: " + str(r.status_code))
           print(r.text)

print("Finished uploading to kafka topic")


import tensorflow as tf
import cv2
import numpy as np
import model
import socket
import threading
import sys
import os
import struct

x, y, predict, loss, accuracy, merged, softmax = model.build_model()
saver = tf.train.Saver()
sess = tf.InteractiveSession()

saver.restore(sess, tf.train.latest_checkpoint("./persist_model_1/"))

def predict_value(type='image', image_path=None):

    if type == 'image':
        assert image_path is not None
        image = cv2.imread(image_path)
        if image.shape != (200, 200):
            image = cv2.resize(image, (200, 200))
        image = np.asarray(image, np.float32) / 255.
        image = np.reshape(image, (1, image.shape[0], image.shape[1], image.shape[2]))
        [predict_, probabilistic] = sess.run([predict, softmax], feed_dict={x: image})
        probabilistic = np.max(probabilistic)
        print("category: %d, prob: %.4f" % (predict, probabilistic))
        if predict_ == 0:
           return 2 #有毒垃圾
        elif predict_ == 1:
            return 1 #不可回收垃圾
        elif predict_ == 2:
            return 3 #厨余垃圾
        elif predict_ == 3:
            return 0 #可回收
        elif predict_ == 4:
            return 4 #空盒子
        elif predict_ == 5:
            return 0 # 可回收垃圾
        elif predict_ == 6:
            return 1 # 不可回收垃圾

    elif type == 'video':
        capture = cv2.VideoCapture(0)
        while True:
            ret, frame = capture.read()
            resize = cv2.resize(frame, (200, 200))
            x_ = np.asarray(resize, np.float32) / 255.
            x_ = np.reshape(x_, [1, x_.shape[0], x_.shape[1], x_.shape[2]])
            [predict_, probabilistic] = sess.run([predict, softmax], feed_dict={x: x_})
            probabilistic = np.max(probabilistic)
            if predict_ == 0:
                cv2.putText(frame, "electric probabilistic: %.4f" % probabilistic, (10, 50), cv2.FONT_HERSHEY_SIMPLEX,
                            1,
                            (0, 0, 255), 2, cv2.LINE_AA)
            elif predict_ == 1:
                cv2.putText(frame, "fruit probabilistic: %.4f" % probabilistic, (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1,
                            (99, 255, 255), 2, cv2.LINE_AA)
            elif predict_ == 2:
                cv2.putText(frame, "lajiao probabilistic: %.4f" % probabilistic, (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1,
                            (0, 12, 130), 2, cv2.LINE_AA)
            elif predict_ == 3:
                cv2.putText(frame, "yilaguan probabilistic: %.4f" % probabilistic, (10, 50), cv2.FONT_HERSHEY_SIMPLEX,
                            1,
                            (19, 15, 255), 2, cv2.LINE_AA)
            elif predict_ == 4:
                cv2.putText(frame, "void hezi probabilistic: %.4f" % probabilistic, (10, 50), cv2.FONT_HERSHEY_SIMPLEX,
                            1,
                            (255, 190, 255), 2, cv2.LINE_AA)
            elif predict_ == 5:
                cv2.putText(frame, "zhi probabilistic: %.4f" % probabilistic, (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1,
                            (255, 70, 13), 2, cv2.LINE_AA)
            elif predict_ == 6:
                cv2.putText(frame, "jiaobu probabilistic: %.4f" % probabilistic, (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1,
                            (255, 0, 100), 2, cv2.LINE_AA)

            cv2.imshow("recognized", frame)
            key = cv2.waitKey(1)
            if key == 27:
                break
        cv2.destroyAllWindows()
        capture.release()
        __close_session__(sess)

def __close_session__(sess):
    sess.close()

def socket_service():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(('0.0.0.0', 6666))
        s.listen(10)
    except socket.error as msg:
        print(msg)
        sess.close()
        sys.exit(1)
    print('Waiting connection...')

    while 1:
        conn, addr = s.accept()
        t = threading.Thread(target=deal_data, args=(conn, addr))
        t.start()

def deal_data(conn, addr):
    global predict
    print('Accept new connection from {0}'.format(addr))
    # conn.settimeout(500)
    conn.send('Hi, Welcome to the server!'.encode("utf-8"))

    while 1:
        fileinfo_size = struct.calcsize('128sl')
        buf = conn.recv(fileinfo_size)
        if buf:
            filename, filesize = struct.unpack('128sl', buf)
            fn = filename.strip(b"\x00").decode("utf-8")
            new_filename = os.path.join("./picturetest/test.jpg")
            print(new_filename, filesize)
            print('file new name is {0}, filesize if {1}'.format(new_filename, filesize))

            recvd_size = 0  # 定义已接收文件的大小
            fp = open(new_filename, 'wb')
            print('start receiving...')

            while not recvd_size == filesize:
                if filesize - recvd_size > 1024:
                    data = conn.recv(1024)
                    recvd_size += len(data)
                else:
                    data = conn.recv(filesize - recvd_size)
                    recvd_size = filesize
                fp.write(data)
            fp.close()
            print('end receive...')
        conn.send('已上传'.encode("utf-8"))
        try:
            print("进入识别函数")
            value = predict_value("image", "./picturetest/test.jpg")
            print("函数执行完成：", value)
            conn.send('识别结果：{0}'.format(value).encode("utf-8"))
        except Exception as e:
            print(e)
            sess.close()
            conn.send('识别失败'.encode("utf-8"))
        conn.close()
        break

if __name__ == '__main__':
    # predict_value("video")
    socket_service()