import time
import pandas as pd
import numpy as np

CITY_DATA = { 'chicago': 'chicago.csv',
              'new york city': 'new_york_city.csv',
              'washington': 'washington.csv' }

def get_filters():
    """
    Asks user to specify a city, month, and day to analyze.

    Returns:
        (str) city - name of the city to analyze
        (str) month - name of the month to filter by, or "all" to apply no month filter
        (str) day - name of the day of week to filter by, or "all" to apply no day filter
    """
    print('Hello! Let\'s explore some US bikeshare data!')
 # TO DO: get user input for city (chicago, new york city, washington). HINT: Use a while loop to handle invalid inputs
    city= input('choose a city name (chicago , new york city , washington ,\ninput:').lower()
    while city  not in CITY_DATA.keys():
         print('your input is wrong ')
         city= input('choose a city  (chicago , new york city , washington ,\n input:').lower()
    # TO DO: get user input for month (all, january, february, ... , june)
    months= ['january', 'february', 'march', 'april', 'may', 'june','all']
    while True:
         month= input('choose a month from list (january, february, march, april, may, june)\n or choose: all\n input:').lower()
         if month in months :
             break
         else:
             print("wrong entry")

    # TO DO: get user input for day of week (all, monday, tuesday, ... sunday)
    days=['saturday','sunday','monday','tuesday','wednesday','thursday','friday','all']
    while True:
       day= input('choose a day from list (saturday,sunday,monday,tuesday,wednesday,thursday,friday)\n or choose: all\n input:').lower()
       if day in days :
           break
       else:
           print("wrong entry")

    print('-'*40)
    return city, month, day

def load_data(city, month, day):
    """
    Loads data for the specified city and filters by month and day if applicable.

    Args:
        (str) city - name of the city to analyze
        (str) month - name of the month to filter by, or "all" to apply no month filter
        (str) day - name of the day of week to filter by, or "all" to apply no day filter
    Returns:
        df - Pandas DataFrame containing city data filtered by month and day
    """

# load data file into a dataframe
    df = pd.read_csv(CITY_DATA[city])

# convert the Start Time column to datetime
    df['Start Time'] = pd.to_datetime(df['Start Time'])

 # extract month and day of week from Start Time to create new columns
    df['month'] = df['Start Time'].dt.month
    df['day_of_week'] = df['Start Time'].dt.weekday_name
    # extract hour from the Start Time column to create an hour column
    df['start_hour'] = df['Start Time'].dt.hour
# filter by month if applicable
    if month != 'all':
        # use the index of the months list to get the corresponding int
        months = ['january', 'february', 'march', 'april', 'may', 'june']
        month = months.index(month) + 1

        # filter by month to create the new dataframe
        df = df[df['month'] == month]

    # filter by day of week if applicable
    if day != 'all':
        # filter by day of week to create the new dataframe
        df = df[df['day_of_week'] == day.title()]

    return df

def time_stats(df):
    """Displays statistics on the most frequent times of travel."""

    print('\nCalculating The Most Frequent Times of Travel...\n')
    start_time = time.time()

    # TO DO: display the most common month
    popular_month = df['month'].mode()[0]
    print('the most common month is:',popular_month)

    # TO DO: display the most common day of week

    popular_week = df['day_of_week'].mode()[0]
    print('the most common day of week is:',popular_week)
    # TO DO: display the most common start hour
    popular_hour = df['start_hour'].mode()[0]
    print('the most common start hour is:',popular_hour)

    print("\nThis took %s seconds." % (time.time() - start_time))
    print('-'*40)

def station_stats(df):
    """Displays statistics on the most popular stations and trip."""

    print('\nCalculating The Most Popular Stations and Trip...\n')
    start_time = time.time()

    # TO DO: display most commonly used start station
    start_station = df['Start Station'].mode()[0]
    print('most commonly used start station is ',start_station)

    # TO DO: display most commonly used end station
    end_station = df['End Station'].mode()[0]
    print('most commonly used end station is ',end_station)

    # TO DO: display most frequent combination of start station and end station trip
    df['most frequent combination route']=df['Start Station'] + "-" + df['End Station']
    print('most frequent combination trip is {}'.format(df['most frequent combination route'].mode()[0]))

    print("\nThis took %s seconds." % (time.time() - start_time))
    print('-'*40)

def trip_duration_stats(df):
    """Displays statistics on the total and average trip duration."""

    print('\nCalculating Trip Duration...\n')
    start_time = time.time()

    # TO DO: display total travel time
    total_duration_time=df['Trip Duration'].sum().round()
    print('total time of trips in second:',total_duration_time)
    # TO DO: display mean travel time
    mean_duaration_time=df['Trip Duration'].mean().round(2) #two decimal
    print('average time of tripsin seconds:',mean_duaration_time)

    print("\nThis took %s seconds." % (time.time() - start_time))
    print('-'*40)

def user_stats(df,city, month, day):
    """Displays statistics on bikeshare users."""

    print('\nCalculating User Stats...\n')
    start_time = time.time()
     # TO DO: Display counts of user types
    print(df.groupby(['User Type'])['User Type'].count())
    # load data file into a dataframe
    print('- -'*40)
    df = pd.read_csv(CITY_DATA[city])
    if city== 'washington':
        print('no available data about gender for washington city')
    else:

    # TO DO: Display counts of gender
        gender_count=df.groupby(['Gender'])['Gender'].count()
        print(df.groupby(['Gender'])['Gender'].count())

        print('- -'*40)
    # TO DO: Display earliest, most recent, and most common year of birth
        print('the earliest year of birth is       : ',int(df['Birth Year'].min()))
        print('the most recent year of birth is     : ',int(df['Birth Year'].max()))
        print('the most common year of birth is     : ',int(df['Birth Year'].mode()[0]))

    print("\nThis took %s seconds." % (time.time() - start_time))
    print('-'*40)

def Look_at(df):
    """look at  5 rows of the data at a time when user accept to view data"""
    print('\ Takeing a look at the first few rows ...\n')
    start_time = time.time()
    n=0
    view_input=input('would you like to view  5 row of data press (yes) or (no)').lower()
    if  view_input not in['yes','no']:
        print("wrong entry")
        view_input=input('would you like to view  5 row of data press (yes) or (no)').lower()
    elif  view_input!= 'yes':
        print('finished')
    else:

        n=0
        while n+5>=0:
            print(df[n:n+5])
            n = n+5
            view_input=input('would you like to view  5 row of data press (yes) or (no)').lower()
            if  view_input!= 'yes':
                break

    print("\nThis took %s seconds." % (time.time() - start_time))

    print('-'*40)

def main():
    while True:
        city, month, day = get_filters()
        df = load_data(city, month, day)

        time_stats(df)
        station_stats(df)
        trip_duration_stats(df)
        user_stats(df,city, month, day)
        Look_at(df)

        restart = input('\nWould you like to restart? Enter yes or no.\n')
        if restart.lower() != 'yes':
            print('finished all,thanks')
            print('-'*40)
            print('-'*40)
            print('-'*40)
            break

if __name__ == "__main__":
    main()


"""
1.아이디어
숫자 중복 횟수 세기
"""
from collections import Counter
arr=list(map(int,input().split()))
element = sorted(list(set(arr)))
arr = Counter(arr)
answer=[]

for num in element:
    cnt =  arr[num]
    if cnt!=1:
        answer.append(cnt)

if not answer:
    answer.append(-1)
print(answer)


import numpy as np
import math as m
from PIL import Image, ImageDraw

MAX_ITERATIONS = 75

def convert_in_ones(Y):
    #
    Y_new = Y
    for n in range(len(Y_new[0])):
        if 0 <= Y[0][n][0]:
            Y_new[0][n][0] = 1
        else:
            Y_new[0][n][0] = -1
    return Y_new

def if_equal(Y, X):
    for j in range(len(X)):
        k = 0
        for i in range(len(Y[0])):
            if Y[0][i][0] == X[j][i][0]:
                k = k + 1
        if k == len(Y[0]):
            return True
    return False

def draw_image(path, Y, SIZE):
    image = Image.new('1', (SIZE, SIZE), "white")
    draw = ImageDraw.Draw(image)
    index = 0
    for i in range(SIZE):
        for j in range(SIZE):
            if Y[index][0] < 0:
                clr = 0
            else:
                clr = 1
            index = index + 1
            draw.point((i, j), clr)
    image.save(path)
    image.show()

def activation_function(Y):
    for i in range(len(Y)):
        for j in range(len(Y[i])):
            Y[i][j] = th(Y[i][j])
    return Y

def sh(x):
    return m.exp(x) - m.exp(-x)

def ch(x):
    return m.exp(x) + m.exp(-x)

def th(x):
    return sh(x) / ch(x)

def transparent(X):
    return X.T

def get_weights(X, SIZE):
    W = np.zeros((SIZE**2, SIZE**2))
    for n in range(len(X)):
        ups = (W @ X[n] - X[n]) @ transparent(W @ X[n] - X[n])
        W = W + (ups / (transparent(X[n]) @ X[n] - transparent(X[n]) @ W @ X[n]))
    return W

def get_image(img_path, SIZE):
    X = []
    one = 1
    negative_one = -1
    for n in range(len(img_path)):
        index = 0
        image = Image.open(img_path[n])
        pixels = image.load()
        x = np.zeros((SIZE*SIZE, 1))
        for i in range(SIZE):
            for j in range(SIZE):
                if pixels[i, j][0] == 255:
                    required_pixel = one
                else:
                    required_pixel = negative_one
                x[index] = required_pixel
                index = index + one
        X.append(x)
    return X

def get_image_and_weights(img_path, SIZE):
    X = get_image(img_path, SIZE)
    W = get_weights(X, SIZE)
    return X, W

def while_cycle(X, W, SIZE):
    input_image = input("Введите название цифры которую будет распозновать: ")
    input_image_show = Image.open("curved_images/%s.png" % input_image)
    print("Открываю картинку цифры %s.." % input_image)
    input_image_show.show()
    Y = get_image(["curved_images/%s.png" % input_image], SIZE)

    iteration = 0
    flag = True

    while flag:
        if iteration >= MAX_ITERATIONS:
            print("Восстановить не удалось :(")
            break
        Y = [activation_function((W @ Y[0]))]
        Y_new = convert_in_ones(Y)
        if if_equal(Y_new, X):
            print("Распознал!")
            print("Восстановленное изображение: image_result/img.png")
            draw_image(f"output_images/img.png", Y[0], SIZE)
            flag = False
        iteration = iteration + 1
        pass

def main():
    SIZE = 30
    img_path = ["normal_images/0.png", "normal_images/1.png",
                "normal_images/2.png", "normal_images/3.png",
                "normal_images/4.png", "normal_images/5.png",
                "normal_images/6.png", "normal_images/7.png",
                "normal_images/8.png", "normal_images/9.png"]

    X, W = get_image_and_weights(img_path, SIZE)

    while_cycle(X, W, SIZE)

if __name__ == "__main__":
    main()


from sys import argv
from time import time

def __init__(length=3):
    """
    """
    if length <= 0:
        raise Exception("What you talkin' about?")

    palindrome = ""
    # start time
    start = time()

    hl = round(length / 2)
    if length % 2:
        if length != 1:
            maximum = int('9' * length)
            palinprime = maximum
            while not palindrome:
                palinprime -= 1
                composidrome = int(str(palinprime) + str(palinprime)[::-1])
                i = int(composidrome ** .5)
                while composidrome / i < maximum:
                    if composidrome // i == composidrome / i:
                        palindrome = str(composidrome)
                        break;
                    r = i % 10
                    if r in {1, 3, 9}:
                        i -= 2
                    elif r in {4, 5, 6, 7, 8}:
                        i -= (r - 3)
                    else:
                        i -= 1
        else:
            palindrome = '9'
    else:
        palindrome += '9' * hl
        palindrome += '0' * hl
        palindrome += palindrome[::-1]
    # end time
    end = time()

    delta_time = end - start
    print("time:", delta_time)
    print("palindrome:", palindrome)
    return palindrome, delta_time

if __name__ == '__main__':
    if len(argv) == 2:
        __init__(argv[1])
    else:
        __init__(5)


from flask import Flask, render_template
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData

import config

naming_convention = {
    "ix": 'ix_%(column_0_label)s',
    "uq": "uq_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(table_name)s_%(column_0_name)s",
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
    "pk": "pk_%(table_name)s"
}
db = SQLAlchemy(metadata=MetaData(naming_convention=naming_convention))
migrate = Migrate()

def page_not_found(e):
    return render_template('404.html'), 404

def create_app():
    app = Flask(__name__)
    app.config.from_object(config)

    #app.run(host='0.0.0.0', port=5000)

    db.init_app(app)
    if app.config['SQLALCHEMY_DATABASE_URI'].startswith("sqlite"):
        migrate.init_app(app, db, render_as_batch=True)
    else:
        migrate.init_app(app, db)

    from . import models
    from .views import main_views, board_views, auth_views, comment_views, guide_views, chart_views, check_views, flask_upload, test
    app.register_blueprint(main_views.bp)
    app.register_blueprint(board_views.bp)
    app.register_blueprint(auth_views.bp)
    app.register_blueprint(comment_views.bp)
    app.register_blueprint(guide_views.bp)
    app.register_blueprint(chart_views.bp)
    app.register_blueprint(check_views.bp)
    app.register_blueprint(flask_upload.bp)
    app.register_blueprint(test.bp)

    from .filter import format_datetime
    app.jinja_env.filters['datetime'] = format_datetime

    app.register_error_handler(404, page_not_found)

    return app


from inputs import get_gamepad
from json import load
import subprocess
import inputs
import sys

"""
Buttons:
BTN_SOUTH
BTN_NORTH
BTN_WEST
BTN_EAST
BTN_SELECT
BTN_START
BTN_THUMBR
BTN_THUMBL
BTN_TR
BTN_TL
ABS_HAT0Y  # Up and Down
ABS_HAT0X  # Left and Right
"""

def main():
    json_content = load(open("input.json", "r"))
    while 1:
        events = get_gamepad()
        for e in events:
            if e.state == 1:
                if e.code not in ["ABS_RY", "ABS_RX", "ABS_Y", "ABS_X", "SYN_REPORT"]:
                    if e.code in json_content:
                        for i in json_content[e.code]:
                            if i.startswith("(@PY)"):
                                eval(i[5:])
                            else:
                                command = subprocess.Popen(i, shell=True, stdout=sys.stdout)
                                command.wait()

if __name__ == "__main__":
    main()


import math
import re

def candidates(N):
    s=str(N)
    cands=[]
    for d in s:
        if s.count(d)>1:
            idx=[i for i,x in enumerate(s) if x==d]

            tmp=s
            for i in idx:
                tmp=insert_string(tmp,i)
                if tmp not in cands:
                    cands.append(tmp)
            tmp=s
            for i in idx[::-1]:
                tmp=insert_string(tmp,i)
                if tmp not in cands:
                    cands.append(tmp)

    return cands

def check_lens(strs):
    for t in strs:
        if len(t.lstrip('0'))!=len(t):
            return False
    return True

def check_cands(cands,N):
    for n in cands:
        tmp=[]
        for i in range(0,10):
            p=re.sub('-',str(i),n)
            if isPrime(int(p)):
                tmp.append(p)
        if len(tmp)>=N and check_lens(tmp):
            return tmp
    return []

def insert_string(s,i):
    return s[:i]+'-'+s[i+1:]

def check_digits(N):
    if len(str(N))!=len(set(str(N))):
        return True
    return False

def isPrime(N):
    for i in range(2,int(math.sqrt(N))+1):
        if N % i == 0:
            return False
    return True

def main():
    N=8
    for p in range(10**4,10**6):
        if check_digits(p) and isPrime(p):
            pout=check_cands(candidates(p),N)
            if len(pout)>0:
                return pout
    return []

if __name__=="__main__":
    print(main())


from automagica import *

"""
Opens a template Word document, replaces a template with content and saves as a new file.
"""

document = OpenWordDocument('example.docx')

new_document = ReplaceText(document, text='[template]', replace_with='invoice 123456')

new_document.save('result.docx')

"""
Opens the new file and saves it as PDF (all in the background)
This only works on Windows with Microsoft Office installed!
"""

import os

full_path_word_file = os.path.join(os.getcwd(), 'result.docx')

full_path_pdf_file = full_path_word_file.replace('.docx', '.pdf')

ConvertWordToPDF(word_filename=full_path_word_file, pdf_filename=full_path_pdf_file)


from random import shuffle
import random
import numpy as np
import time

from spielplan import Spielplan

class SpielplanVorrunde(Spielplan):
	def __init__(self, config):
		super().__init__(config)
		self.startzeit = self.str_to_time(config.get("startzeit"))
		self._preferred_groupsize = config.get("gewuenschte_gruppengroesse")
		self.spielzeit_vorrunde = config.get("spielzeit_vorrunde")
		self.pause_vorrunde = config.get("pause_vorrunde")
		self.message = False
		self.images = []

	def get_teams(self, print_=False):
		self.teams = self.read_csv("teams.csv")
		anzahl_teams = len(self.teams["Team"])
		number_groups = int(anzahl_teams / self._preferred_groupsize)
		anzahl_dritte = (self.finale-number_groups)*2
		if print_:
			self.message = f"Es gibt {anzahl_teams} Teams und {number_groups} Gruppen.\n Damit kommen die besten {anzahl_dritte} Dritten weiter."
		return anzahl_dritte

	def get_toepfe(self):
		""" Lostoepfe - es gibt so viele Toepfe wie die max_i(len(group_i));
		der erste Topf darf höchstens ein Element mehr haben als jeder andere und nicht weniger """

		self.toepfe = {}
		team_list = self.teams["Team"]
		topf_list = self.teams["Topf"]
		for i, team in enumerate(team_list):
			topf = self.teams
			topf_name = 'Topf ' + str(topf_list[i])
			self.toepfe.setdefault(topf_name, []).append(team)

	def generate_groups(self):
		""" Erstelle die Gruppen """
		self.groups = {}
		i = 0
		np.random.seed(42)
		random.seed(42)
		toepfe_keys = list(self.toepfe.keys())

		while len(self.toepfe[toepfe_keys[0]])>0:
			i += 1
			group_name = 'Gruppe ' + str(i)
			size_randoms = 0
			for key in toepfe_keys:
				if len(self.toepfe[key]) > 0:
					size_randoms += 1
			randoms = [np.random.randint(len(self.toepfe[toepfe_keys[j]])) for j in range(size_randoms)]
			group = []
			for k, random_num in enumerate(randoms):
				group.append(self.toepfe[toepfe_keys[k]].pop(random_num))
			self.groups[group_name] = group
		self.write_csv("groups.csv", self.groups)

	def determine_spielplan_vorrunde(self):
		self.load_groups()
		pairings = {}
		for group_name, group in self.groups.items():
			pairings[group_name] = []
			teams_1_played  = []
			for team1 in group:
				teams_1_played.append(team1)
				for team2 in group:
					if team2 not in teams_1_played:
						pairing = [team1, team2]
						pairings[group_name].append(pairing)

		for group_name in pairings:
			shuffle(pairings[group_name])

		pairings_sorted = []

		condition = True
		i = 0
		while condition:
			condition = False
			for group_name, group_pairings in pairings.items():
				if len(group_pairings) > i:
					pairings_sorted.append(pairings[group_name][i])
					condition = True
			i += 1

		aktuelle_zeit = self.startzeit
		spielplan_vorrunde = {}
		spielplan_vorrunde_table = {}

		for i, game in enumerate(pairings_sorted):
			zeit = time.asctime(time.localtime(aktuelle_zeit * 60)).split(" ")[-2]
			spielplan_vorrunde.setdefault(zeit, []).append(game)
			aktueller_platz = i % self.plaetze + 1
			spielplan_vorrunde_table.setdefault("Platz", []).append(aktueller_platz)
			if aktueller_platz == self.plaetze:
				aktuelle_zeit += self.spielzeit_vorrunde + self.pause_vorrunde

		for zeit, spiele in spielplan_vorrunde.items():
			for spiel in spiele:
				spielplan_vorrunde_table.setdefault("Uhrzeit", []).append(zeit[:-3])
				spielplan_vorrunde_table.setdefault("Heim", []).append(spiel[0])
				spielplan_vorrunde_table.setdefault("Gast", []).append(spiel[1])
		self.images.append(self.create_table(spielplan_vorrunde_table, "Spielplan Vorrunde"))
		ergebnisse_vorrunde = spielplan_vorrunde_table
		ergebnisse_vorrunde["Punkte Heim"] = []
		ergebnisse_vorrunde["Punkte Gast"] = []
		self.write_csv("ergebnisse_vorrunde.csv",ergebnisse_vorrunde)

	def determine_table(self):
		""" Ergebnisse und Tabellen """

		self.load_groups()
		self.vorrunde_ergebnisse = self.read_csv("ergebnisse_vorrunde.csv")
		anzahl_dritte = self.get_teams()
		results = {}
		if not all([key in self.vorrunde_ergebnisse.keys() for key in ["Punkte Heim", "Punkte Gast"]]):
			return
		for i in range(len(self.vorrunde_ergebnisse["Uhrzeit"])):
			if not (self.vorrunde_ergebnisse["Punkte Heim"][i]== "" or self.vorrunde_ergebnisse["Punkte Gast"][i]==""):
				team1 = self.vorrunde_ergebnisse["Heim"][i]
				team2 = self.vorrunde_ergebnisse["Gast"][i]
				diff_team1 = int(self.vorrunde_ergebnisse["Punkte Heim"][i])-int(self.vorrunde_ergebnisse["Punkte Gast"][i])
				if diff_team1 == 0:
					pts_team1 = 1
				else:
					pts_team1 = (diff_team1>0)*2
				for group_name, group in self.groups.items():
					if team1 in group:
						if not group_name in results.keys():
							results[group_name] = {}
							results[group_name][team1] = {"Punkte": pts_team1, "Differenz": diff_team1}
							results[group_name][team2] = {"Punkte": 2-pts_team1, "Differenz": -diff_team1}
						else:
							if not team1 in results[group_name].keys():
								results[group_name][team1] = {"Punkte": pts_team1, "Differenz": diff_team1}
							else:
								results[group_name][team1]["Punkte"] += pts_team1
								results[group_name][team1]["Differenz"] += diff_team1
							if not team2 in results[group_name].keys():
								results[group_name][team2] = {"Punkte": 2-pts_team1, "Differenz": -diff_team1}
							else:
								results[group_name][team2]["Punkte"] += 2-pts_team1
								results[group_name][team2]["Differenz"] -= diff_team1

		results_sorted = {}
		table = {}
		for group_name, group_results in results.items():
			table[group_name] = {}
			group_results_sorted = {key: value for key, value in reversed(sorted(group_results.items(), key=lambda item: (item[1]["Punkte"], item[1]["Differenz"])))}
			results_sorted[group_name] = group_results_sorted
			i = 0
			for team, team_results in group_results_sorted.items():
				i+=1
				table[group_name].setdefault("Platz", []).append(i)
				table[group_name].setdefault("Team", []).append(team)
				table[group_name].setdefault("Punkte", []).append(team_results["Punkte"])
				table[group_name].setdefault("Differenz", []).append(team_results["Differenz"])

		die_dritten = {}
		for group_name in results_sorted:
			if len(results_sorted[group_name]) >= 3:
				die_dritten[list(results_sorted[group_name])[2]] = results_sorted[group_name][list(results_sorted[group_name])[2]]

		die_dritten_sorted = {key: value for key, value in reversed(sorted(die_dritten.items(), key=lambda item: (item[1]["Punkte"], item[1]["Differenz"])))}
		beste_dritte = list(die_dritten_sorted)[:anzahl_dritte]

		gruppen_mit_bd = [self.get_group(team) for team in beste_dritte]
		gruppen_ohne_bd = [self.get_group(team) for team in self.teams]
		if beste_dritte != []:
			table_dritte = {}
			for i, team in enumerate(die_dritten_sorted):
				table_dritte.setdefault("Platz", []).append(i+1)
				table_dritte.setdefault("Team", []).append(team)
				self.images.append(self.create_table(table_dritte, "Platzierungen der Gruppendritten"))

			gruppen_ohne_bd = [group for group in self.groups if not group in gruppen_mit_bd]
		if not table=={}:
			data = []
			for group_name in self.groups:
				if group_name in table.keys():
					images.append(self.create_table(table[group_name], "Tabelle "+group_name))

		self.images.append(self.create_table(self.vorrunde_ergebnisse, "Ergebnisse Vorrunde"))
		return results_sorted, gruppen_mit_bd, gruppen_ohne_bd

	def spielplan_pause(self):
		spielplan = self.read_csv("ergebnisse_vorrunde.csv")
		teams = self.read_csv("teams.csv")["Team"]
		spielzeiten = set([self.str_to_time(spielzeit) for spielzeit in spielplan["Uhrzeit"]])
		spielzeiten = [time.asctime(time.localtime(zeit * 60)).split(" ")[-2][:-3] for zeit in sorted(spielzeiten)]
		spielzeiten_pause = {}
		spielzeiten_pause["Uhrzeit"] = spielzeiten
		for team in teams:
			spielzeiten_pause[team] = [0 for zeit in spielzeiten]

		for i, team in enumerate(spielplan["Heim"]):
			zeit = spielplan["Uhrzeit"][i]
			j = spielzeiten.index(zeit)
			spielzeiten_pause[team][j] += 1
		for i, team in enumerate(spielplan["Gast"]):
			zeit = spielplan["Uhrzeit"][i]
			j = spielzeiten.index(zeit)
			spielzeiten_pause[team][j] += 1

		self.write_csv("spielzeiten_pause.csv", spielzeiten_pause)

		pause = {"Typ Pause": ["Minimum Pause", "Maximum Pause"]}
		for team in teams:
			min_pause = len(spielzeiten)
			max_pause = 0
			aktuelle_pause = 0
			for i, spiel in enumerate(spielzeiten):
				if spielzeiten_pause[team][i] == 0:
					aktuelle_pause += 1
				else:
					min_pause = min(min_pause, aktuelle_pause)
					if spielzeiten_pause[team][i] == 2:
						min_pause = -1
					max_pause = max(max_pause, aktuelle_pause)
					aktuelle_pause = 0
			pause[team] = [min_pause, max_pause]

		self.write_csv("pause_team.csv", pause)

		#for i, spiel in spielzeiten:


# 나이브 베이즈는 분류기를 만들 수 있는 간단한 기술로써
# 단일 알고리즘을 통한 훈련이 아닌 일반적인 원칙에 근거한 여러 알고리즘들을 이용하여 훈련된다.
# 모든 나이브 베이즈 분류기는 공통적으로 모든 특성 값은 서로 독립임을 가정한다.
# 예를 들어, 특정 과일을 사과로 분류 가능하게 하는 특성들 (둥글다, 빨갛다, 지름 10cm)은
# 나이브 베이즈 분류기에서 특성들 사이에서 발생할 수 있는 연관성이 없음을 가정하고
# 각각의 특성들이 특정 과일이 사과일 확률에 독립적으로 기여 하는 것으로 간주한다.

# 조건부 확률 :feature가 발생했다는 가정하에 label이 발생할 확률
# P(Label:feature)=P(Feature|Label) * P(label) / P(Feature)
from sklearn.naive_bayes import GaussianNB
import numpy as np
from sklearn import metrics

x=np.array([1,2,3,4,5])
x=x[:,np.newaxis] #newaxis: 차원확장
print(x)
y=np.array([1,3,5,7,9])

model=GaussianNB().fit(x,y)
pred=model.predict(x)
print('분류정확도: ', metrics.accuracy_score(y,pred))

# 새로운 값으로 예측
new_x=np.array([[0.1],[0.5],[5],[12]])
new_pred=model.predict(new_x)
print(new_pred)

#.....


from __future__ import annotations
from ipaddress import IPv4Address, IPv4Network
from validators import ValidatorIpV4

class CalcSubnetIpv4:
    """
    Класс калькулятора подсети
    """
    def __init__(self):
        self.validator = ValidatorIpV4()

    def run(self, file: str) -> tuple:
        """
        Основной метод.
        Достаёт список ip-адресов из файла, вызывает валидации и находит подсеть
        """
        with open(file) as ips_file:
            ips_list = ips_file.read().splitlines()
            result_validating = self.validator.validating(ips_list)
            if result_validating[0]:
                return result_validating[0], self.calc_subnet(ips_list)
            return result_validating

    def calc_subnet(self, ips_list: list[str]) -> IPv4Network:
        """
        Метод расчёта подсети для списка ip-адресов
        """
        ips_list = [IPv4Address(ip) for ip in ips_list]
        min_ip = min(ips_list)
        max_ip = max(ips_list)
        ip_range = 0
        net = IPv4Network(f'{min_ip}/32', strict=False)
        while max_ip not in net:
            ip_range += 1
            net = IPv4Network(f'{min_ip}/{32 - ip_range}', strict=False)
        return net


import logging

from pyramid.view import view_config
from pyramid.events import ApplicationCreated
from pyramid.events import subscriber

from . import registration
from .appenv import Node

log = logging.getLogger(__name__)

@view_config(route_name='services', renderer='json')
def services(request):
    web_apps_dir = request.registry.settings['web_apps_dir']
    node = Node(web_apps_dir)

    return node.repo_data

@view_config(route_name='tag', renderer='json')
def tag(request):
    web_apps_dir = request.registry.settings['web_apps_dir']
    node = Node(web_apps_dir)
    apps = [s.strip() for s in request.POST['apps'].split(',')]
    return node.tag_apps(
        apps,
        request.POST['tag'],
        request.POST['description'])

@view_config(route_name='mark_as_deployed', renderer='json')
def mark_as_deployed(request):
    web_apps_dir = request.registry.settings['web_apps_dir']
    node = Node(web_apps_dir)
    apps = [s.strip() for s in request.POST['apps'].split(',')]

    return node.mark_as_deployed(apps, request.POST['tag'])

@subscriber(ApplicationCreated)
def register_me(event):
    """
    Register this Bambino node with Doula.
    """
    settings = event.app.registry.settings

    machine_info = Node.get_machine_info()
    machine_info['url'] = 'http://%s:%s' % (
        machine_info['ip'], settings['port'])

    registration.register_bambino(
        machine_info,
        settings['register_url'],
        settings['registration_interval'])


"""
В данном приложении реализован конвейер, обрабатывающий данные из csv

взаимодействие осуществляется через функцию data_cleaner(*args), на вход которой подается путь к файлу.

Осуществляются следующие этапы:

    1. Чтение файла и загрузга кадра данных
    2. Удаление дубликатов
    3. Обработка пропущенных значений
    4. Обработка выбросов
    5. Сохранение обработанных данных по указаному адресу.

"""
import pandas as pd
import numpy as np
import os

from fill_data_gaps import fill_data_gaps_mean, fill_data_gaps_median, fill_data_gaps_nearest, fill_data_gaps_max_likelihood
from fill_data_gaps import MEAN, MEDIAN, NEAREST_NEIGHBOR, MAX_LIKELIHOOD

from data_dropouts_processing import MAX, MIN, replace_dropouts

def delete_NaN(data: pd.DataFrame, critical_value: float) -> pd.DataFrame:
    """
    Функция реализует удаление столбцов, количеством пропущенных значений
    в которых превышает заданное максимальное значение.

    Столбцы с большим количеством пропусков не информативны и лишь только испортят работу.

    Аргументы:
        data, pd.DataFrame - кадр данных, который нужно очистить от неиформативных столбцов.
        critical_value, float - величина критической доли пропущенных значений от количества строк.

    Возвращаемое значение:
        new_data, pd.DataFrame - кадр данных без неинформативных столбцов.
    """
    # скопируем датафрейм, чтобы не навредить исходным данным
    new_data = data.copy()

    # получаем список заголовком столбцов
    columns = new_data.columns

    # пробежимся во всем столбцам
    for column in columns:
        # посчитаем количество пустых значений для текущего столбца
        nulls = new_data[column].isnull().sum()

        # расчитаем долю пропущенных значений
        ratio = nulls / new_data.shape[0]

        # если доля пропущенных значений больше критического значения
        # столбец не информативен - выбрасываем его
        if ratio > critical_value:
            new_data = new_data.drop(columns = column)

    return new_data

def fill_gaps(data: pd.DataFrame, method=MEAN):
    """
    Функция - коммутатор. Вызывает нужную функцию из пакета fill_data_gaps.py в
    соответствии с указанным методом заполнения пропущенных значений.

    Аргументы:
        data, pd.DataFrame - датафрейм, в котором нужно заполнить пропуски.
        method, str - метод заполнения пропущенных значений, принимает начения:
                        'mean' - заполнение средним значением,
                        'median' - заполнение медианным значением,
                        'nearest_neighbor' - ближайшее значение,
                        'max_likelihood' - заполнение методом максимизации функции правдоподобия (в разработке)
    """
    if method == MEAN:
        return fill_data_gaps_mean(data)
    elif method == MEDIAN:
        return fill_data_gaps_median(data)
    elif method == NEAREST_NEIGHBOR:
        return fill_data_gaps_nearest(data)
    elif method == MAX_LIKELIHOOD:
        return fill_data_gaps_max_likelihood(data)

def data_cleaner(data=None, data_path=None, column_drop_critical_value=0.25, fill_gaps_method=MEAN, dropout_method=MIN,
                 dropout_critical_difference=None, save_path='/cleaned_dataframe', save_file_name='out.csv'):
    """
    Функция - конвейер очистки данных.

    Реализует следуюшщие этапы:
        1. Чтение файла и загрузга кадра данных
        2. Удаление дубликатов
        3. Обработка пропущенных значений
        4. Обработка выбросов
        5. Сохранение обработанных данных по указаному адресу.

    Аргументы:
        data, pd.DataFrame - датафрейм, который нужно обработать
        data_path, str - путь к файлу для чтения в формате csv
        column_drop_critical_value, float - критическое значение доли пропущенных значений в столбце,
                                            чтобы исключить столбец,
                                            принимает значение от 0 до 1.
        fill_gaps_method, str - метод заполнения пропущенных значений, принимает следующие значения:
                                'mean' - заполнение средним значением,
                                'median' - заполнение медианным значением,
                                'nearest_neighbor' - ближайшее значение,
                                'max_likelihood' - заполнение методом максимизации функции правдоподобия (в разработке).
        dropout_method, str - метод замены выбросов, принимает следующие значения:
                              'min' - замена минимальным значением из невыбросов,
                              'max' - замена максимальным значением из невыбросов,
                              'mean' - замена средним значением из невыбросов,
                              'median' - заполнение медианным значением из невыбросов.
        dropout_critical_difference, float - максимальная величина отклонения от медианного значения, определяющая выброс.

    Возвращаемое значение:
        dataframe, pd.DataFrame - датафрейм очищенный.

    """

    if data is None and data_path is not None:
    # читаем данные
        data = pd.read_csv(data_path)
    elif data is None and data_path is None:
        raise Exception('Введите либо датафрейм или путь к файлу с данными')

    dataframe = data
    # выбрасываем дубликаты
    dataframe = dataframe.drop_duplicates()

    # удаление неинформативных строк
    dataframe = delete_NaN(data=dataframe, critical_value=column_drop_critical_value)

    # обработка пропущенных значений
    dataframe = fill_gaps(data=dataframe, method=fill_gaps_method)

    # обработка выбросов
    dataframe = replace_dropouts(data=dataframe, method=dropout_method, critical_distance=dropout_critical_difference)

    # создаем каталог, если существует, ничего не произойдет
    os.makedirs(save_path, exist_ok=True)

    # загружаем в файл
    dataframe.to_csv(save_path + '/' + save_file_name)
    return dataframe

## TODO: needs further fixing

def remove_duplicates(data: pd.DataFrame, method: str, keep='first') -> list:
    """
    methods = ['grid', 'fast]

    keep = ['first', 'last', False]
    """
    """
    O(n^2)
    """
    new_data = pd.DataFrame(columns=data.columns)
    if method == 'grid':
        for i in range(data.shape[0]):
            if i == 0:
                new_data = pd.concat([new_data, data.iloc[[i]]])
            else:
                equality = 0
                is_equal = False
                for j in range(i, new_data.shape[0]):
                    for column in data.columns:
                        if data.iloc[i][column] == new_data.iloc[j][column]:
                            equality += 1
                    if equality == len(data.shape[-1]):
                        is_equal = True
                        break
                if is_equal == False:
                    new_data = pd.concat([new_data, data.iloc[[i]]])

        return new_data


#!/usr/bin/env python3
""" mean and cov of data set """
import numpy as np

def mean_cov(X):
    """ calcs mean and covariance of a data set
        X: np ndarray (n, d)
          n: number of points, d: number of dimensions of each data point
        Returns: mean, cov
    """
    if type(X) != np.ndarray or len(X.shape) != 2:
        raise TypeError("X must be a 2D numpy.ndarray")
    if X.shape[0] < 2:
        raise ValueError("X must contain multiple data points")
    n = X.shape[0]
    d = X.shape[1]
    mean = np.mean(X, axis=0, keepdims=True)
    cov = (1 / (n - 1)) * np.matmul(X.T - mean.T, X - mean)
    return (mean, cov)


from pyswip import Prolog
from command import Command
import re

command_list = [
    Command(
        r'^Кто дружит с (.+)\?$',
        'Запрос: «Кто дружит с [Игрок]?»',
        "friend('{0}',X)",
        ('X'),
        lambda players: 'Игкрок дружит с '+", ".join(players) + '.'
    ),
    Command(
        r'^(.+) дружит с (.+)\?$',
        'Запрос: «[Игрок А] дружит с [Игрок Б]?»',
        "friend('{0}','{1}')",
        None,
        lambda res: "Да!" if res else "Нет:("
    ),
    Command(
        r'^(.+) может играть с (.+)\?$',
        'Запрос: «[Игрок А] может играть с [Игрок Б]?»',
        "can_play_together('{0}','{1}')",
        None,
        lambda res: "Да!" if res else "Нет:("
    ),
    Command(
        r'^Какой ранг у (.+)\?$',
        'Запрос: «Какой ранг у [Игрок]?»',
        "player_rank('{0}',X)",
        ('X'),
        lambda rank: 'Непонятно какой ранг.' if not rank else 'Игрок достиг ранг ' + "".join(rank) + '.'
    ),
    Command(
        r'^С кем может играть игрок (.+)\?$',
        'Запрос: «С кем может играть игрок [Игрок]?»',
        "can_play_with('{0}',X), X \= '{0}'",
        ('X'),
        lambda players:
            'Нет игроков с таким же рангом, игроку не с кем играть(' if not players
            else 'Игрок может играсть с этими игроками: ' + ", ".join(players) + '.'
    ),
    Command(
        r'^Кто потенциальный друг (.+)\?$',
        'Запрос: «Кто потенциальный друг [Игрок]?»',
        r"potential_friends('{0}',X)",
        ('X'),
        lambda players:
            'Нет потенциальных друзей.' if not players
            else 'Список потенциальных друзией: ' + ", ".join(players) + '.'
    ),
    Command(
        r'^Какие реальные имена друзей игрока (.+)\?$',
        'Запрос: «Какие реальные имена друзей игрока [Игрок]?»',
        r"friends_real_name('{0}',X)",
        ('X'),
        lambda players:
            'Нет друзей.' if len(players) == 0
            else f'Список реальных имен друзией: ' + ", ".join(players) + '.'
    ),
]

def help_messege():
    print("Используйте команду 'help', чтобы получить списко доступных запросов")
    for command in command_list:
        print(command.help)

def init():
    try:
        prolog = Prolog()
        prolog.consult('lab-1.pl')
        return prolog
    except:
        print("Ошибка чтения базы знаний, некорректный путь!")
    return

def read_request():
    while True:
        s = input("request-for-kb>>")

        if s == "exit":
            return

        if s == "help":
            help_messege()
            continue

        if s == "":
            continue

        yield s

def parse_request(req: str):
    req = re.sub(r'\s+', ' ',req.strip())

    for i in command_list:
        match = re.search(i.regex, req, re.IGNORECASE)
        if match:
            return i, match

    print("Проверьте корректность запроса!")
    return None

def query_in_kb(command, values, prolog: Prolog):
    result = []
    prolog = Prolog()
    prolog.consult('lab-1.pl')
    string_query = command.query.format(*values)

    solutions = prolog.query(string_query)

    for sol in solutions:
        if command.vars != None:
            result.append(sol[command.vars])
        else:
            result.append(sol)

    return result

def print_result(command, res):
    print(command.answer(res))
    return

def main():
    prolog = init()
    help_messege()

    for com in read_request():
        try:
            command, match = parse_request(com)
            result = query_in_kb(command=command, values=match.groups(), prolog=prolog)
            print_result(command=command, res=result)
        except:
            print("Возникла ошибка!")
            continue
main()


import socket
import select
import errno

header_tam = 10
ip = "192.168.0.13"
porta = 31817

my_username = input("Username: ")

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((ip, porta))
client_socket.setblocking(False)

username = my_username.encode('utf-8')
username_header = f"{len(username):<{header_tam}}".encode('utf-8')

client_socket.send(username_header + username)

while True:
    #mensagem = input(f"{my_username} >")
    mensagem = ""

    if mensagem:
        mensagem = mensagem.encode('utf-8')
        mensagem_header = f"{len(mensagem) :< {header_tam}}".encode('utf-8')
        client_socket.send(mensagem_header + mensagem)

    try:
        while True:
            username_header = client_socket.recv(header_tam)
            if not len(username_header):
                print("Conexão com servidor fechada")
                #sys.exit()
            username_tam = int(username_tam.decode('utf-8').strip())
            username = client_socket.recv(username_tam).decode('utf-8')

            mensagem_header = client_socket.recv(header_tam)
            mensagem_tam = int(mensagem_header.decode('utf-8').strip())
            mensagem = client_socket.recv(mensagem_tam).decode('utf-8')

            print(f"{username} > {mensagem}")

    except IOError as e:
        if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
            print("Erro", str(e))

        continue
    except Exception as e:
        print("Erro", str(e))
        pass


"""
Letter Finder
Name : Min Soo (Mike) HWANG
Github ID : Delivery_KiKi
"""

from typing import TextIO
from io import StringIO
from itertools import combinations

def a_finder(filename: str, letter: str) -> None:
    """ Open a text file, preprocess the data, and find probability that a set of letters contains the certain letter.

    :precondition: the functions in a_finder must be correctly operated
    :postcondition: open a text file, process the data, and find probability that
                    a set of letters among the second line of text contains the certain letter
    :return: nothing
    """
    with open(filename) as file_object:
        text_list = process_data(file_object)
    calculate_probability(letter, text_list)

def process_data(file_object: TextIO) -> list:
    """ Take the text file, split a line of text by a space, and store the value to a list.

    :param file_object: an object of the text file.
    :precondition: each line of text must be separated by space and each line must be separated by <Enter> key
    :postcondition: make a list of the lists that contain the information of each line of text separating by a space
    :return: a list of lists that contains the information of each line of text

    >>> text_file = StringIO('')
    >>> process_data(text_file)
    []
    >>> text_file = StringIO('\\n\\n\\n\\n\\n')
    >>> process_data(text_file)
    [[''], [''], [''], [''], ['']]
    >>> text_file = StringIO('1.3 3.4\\n2 4.2\\n-1 1\\n')
    >>> process_data(text_file)
    [['1.3', '3.4'], ['2', '4.2'], ['-1', '1']]
    >>> text_file = StringIO('4\\na a b c\\n2\\n')
    >>> process_data(text_file)
    [['4'], ['a', 'a', 'b', 'c'], ['2']]
    """
    text_list = [line.replace('\n', '').split(' ') for line in file_object]
    return text_list

def calculate_probability(letter: str, text_list: list) -> None:
    """ Find the probability that the sequence of letters contains the certain letter.

    :param letter: a letter that will be used for calculating the probability
    :param text_list: a list of the lists that contain the information of each row of the text file
    :precondition: letter can be any letters but spaces
    :precondition: the length of text_list must be 3
    :precondition: text_list[0] must be a string of a number between 1 to 10 inclusive
    :precondition: the length of text_list[1] must be the same as the numerical value of text_list[0]
                   and made up of any characters but spaces
    :precondition: text_list[1] must be a string of a number between 1 to the numerical value of text_list[0] inclusive
    :postcondition: print the probability that sequence of letters in text_list[1] contains letter
    :return: nothing

    >>> string_to_find = 'a'
    >>> line_list = [['4'], ['a', 'a', 'b', 'c'], ['2']]
    >>> calculate_probability(string_to_find, line_list)
    0.8333 probability that a pair of items selected will contain one or more 'a'
    >>> string_to_find = 'b'
    >>> line_list = [['1'], ['a'], ['1']]
    >>> calculate_probability(string_to_find, line_list)
    0.0 probability that a pair of items selected will contain one or more 'b'
    >>> string_to_find = 'c'
    >>> line_list = [['5'], ['c', 'b', 'a', 't', 'a'], ['2']]
    >>> calculate_probability(string_to_find, line_list)
    0.4 probability that a pair of items selected will contain one or more 'c'
    >>> string_to_find = '&'
    >>> line_list = [['4'], ['&', '&', 'a', 't'], ['2']]
    >>> calculate_probability(string_to_find, line_list)
    0.8333 probability that a pair of items selected will contain one or more '&'
    >>> string_to_find = 'A'
    >>> line_list = [['4'], ['A', 'A', 'a', 't'], ['2']]
    >>> calculate_probability(string_to_find, line_list)
    0.8333 probability that a pair of items selected will contain one or more 'A'
    >>> string_to_find = 'Z'
    >>> line_list = [['4'], ['Z', 'Z', 'a', 't'], ['2']]
    >>> calculate_probability(string_to_find, line_list)
    0.8333 probability that a pair of items selected will contain one or more 'Z'
    >>> string_to_find = '0'
    >>> line_list = [['4'], ['0', '0', 'a', 't'], ['2']]
    >>> calculate_probability(string_to_find, line_list)
    0.8333 probability that a pair of items selected will contain one or more '0'
    >>> string_to_find = '9'
    >>> line_list = [['4'], ['9', '9', 'a', 't'], ['2']]
    >>> calculate_probability(string_to_find, line_list)
    0.8333 probability that a pair of items selected will contain one or more '9'
    >>> string_to_find = '1234567890'
    >>> line_list = [['4'], ['1234567890', '1234567890', 'a', 't'], ['2']]
    >>> calculate_probability(string_to_find, line_list)
    0.8333 probability that a pair of items selected will contain one or more '1234567890'
    """
    try:
        letters = text_list[1]
        n_list = list(range(len(letters)))
        number_k = int(text_list[2][0])
        result = set()
        combination_list = list(combinations(n_list, number_k))
        for index in combination_list[:]:
            for number in index:
                if letters[number] == letter:
                    result.add(index)
        probability = round(len(result) / len(combination_list), 4)
        print(f"{probability} probability that a pair of items selected will contain one or more '{letter}'")
    except ZeroDivisionError:
        print('CHECK THE TEXT FILE.')
        print("The second line in the text file must include letters divided by a space.")
    except IndexError:
        print('CHECK THE TEXT FILE.')
        print("The third line in the text file must include an integer.")

def main() -> None:
    """
    Drives the program.
    """
    # import doctest
    # doctest.testmod(verbose=True)
    a_finder('find_probability.txt', 'a')

if __name__ == "__main__":
    main()


import sys
import os
PROJECT_ROOT = os.path.abspath(os.path.join(
                  os.path.dirname(__file__),
                  os.pardir)
)
sys.path.append(PROJECT_ROOT)

from RFEM.Loads.freeLoad import FreeLoad
from RFEM.enums import *
from RFEM.initModel import Model
from RFEM.BasicObjects.material import Material
from RFEM.BasicObjects.thickness import Thickness
from RFEM.BasicObjects.node import Node
from RFEM.BasicObjects.line import Line
from RFEM.BasicObjects.surface import Surface
from RFEM.TypesForNodes.nodalSupport import NodalSupport
from RFEM.LoadCasesAndCombinations.staticAnalysisSettings import StaticAnalysisSettings
from RFEM.LoadCasesAndCombinations.loadCase import LoadCase

if Model.clientModel is None:
    Model()

def test_free_load():

    Model.clientModel.service.delete_all()
    Model.clientModel.service.begin_modification()

    Material(1, 'S235')

    Node(1, 0.0, 0.0, 0.0)
    Node(2, 10.0, 0.0, 0.0)
    Node(3, 10.0, 10.0, 0.0)
    Node(4, 0.0, 10.0, 0.0)
    Node(5, 0.0, 0.0, 10.0)
    Node(6, 0.0, 10.0, 10.0)

    Line(1, '1 2')
    Line(2, '2 3')
    Line(3, '3 4')
    Line(4, '4 1')

    Thickness(1, 'Dicke', 1, 0.05)
    Surface(1, '1-4', 1)

    NodalSupport(1, '1', NodalSupportType.HINGED)
    NodalSupport(2, '2', NodalSupportType.HINGED)
    NodalSupport(3, '3', NodalSupportType.HINGED)
    NodalSupport(4, '4', NodalSupportType.HINGED)

    StaticAnalysisSettings(1, 'Geometrisch-linear', StaticAnalysisType.GEOMETRICALLY_LINEAR)

    LoadCase(1 , 'Einzell- u. Linienlast')
    LoadCase(2 , 'Rechtecklast 1')
    LoadCase(3 , 'Rechtecklast 2')
    LoadCase(4 , 'Kreislast')
    LoadCase(5 , 'Polygonlast')

    # Prüfung der freien Einzellasten
    FreeLoad.ConcentratedLoad(1, 1, load_parameter= [5000, 4, 2])
    FreeLoad.ConcentratedLoad(2, 1, load_parameter= [50, 8, 8], load_type= FreeConcentratedLoadLoadType.LOAD_TYPE_MOMENT, load_direction= FreeConcentratedLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Y)

    # Prüfung der freien Linienlasten
    FreeLoad.LineLoad(3, 1, '1',
                        FreeLineLoadLoadDistribution.LOAD_DISTRIBUTION_UNIFORM,
                        FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                        FreeLineLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                        [5000, 2, 2, 4, 4])

    # Prüfung der freien Rechtecklasten

    ##  LOAD_LOCATION_RECTANGLE_CORNER_POINTS
    FreeLoad.RectangularLoad(1, 2, '1',
                             FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_UNIFORM,
                             FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                             FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                             [5000],
                             FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CORNER_POINTS,
                             [1, 8, 3, 10, 0])

    FreeLoad.RectangularLoad(2, 2, '1',
                            FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_LINEAR_FIRST,
                            FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                            FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                            [5000, 2000],
                            FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CORNER_POINTS,
                            [4, 8, 6, 10, 0])

    FreeLoad.RectangularLoad(3, 2, '1',
                            FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_LINEAR_SECOND,
                            FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                            FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                            [5000, 2000],
                            FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CORNER_POINTS,
                            [7, 8, 9, 10, 0])

    FreeLoad.RectangularLoad(4, 2, '1',
                             FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_VARYING_IN_Z,
                             FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                             FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                             [5000],
                             FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CORNER_POINTS,
                             [1, 5, 3, 7, [[-3, 0.3], [-1, 0.4], [0, 1]]])

    FreeLoad.RectangularLoad(5, 2, '1',
                            FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_VARYING_ALONG_PERIMETER,
                            FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                            FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                            [5000],
                            FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CORNER_POINTS,
                            [4, 5, 6, 7, [5, 7, 0], [5, 9, 2], 0, [[0, 0.5], [90, 1.75], [180, 1.25], [270, 1], [360, 0.5]]])

    FreeLoad.RectangularLoad(6, 2, '1',
                            FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_VARYING_IN_Z_AND_ALONG_PERIMETER,
                            FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                            FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                            [5000],
                            FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CORNER_POINTS,
                            [7, 5, 9, 7, [[-3, 0.3], [-1, 0.4], [0, 1]], [5, 7, 0], [5, 9, 2], 0, [[0, 0.5], [90, 1.75], [180, 1.25], [270, 1], [360, 0.5]]])

    ##  LOAD_LOCATION_RECTANGLE_CENTER_AND_SIDES
    FreeLoad.RectangularLoad(1, 3, '1',
                             FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_UNIFORM,
                             FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                             FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                             [5000],
                             FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CENTER_AND_SIDES,
                             [2, 9, 2, 2, 0])

    FreeLoad.RectangularLoad(2, 3, '1',
                            FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_LINEAR_FIRST,
                            FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                            FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                            [5000, 2000],
                            FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CENTER_AND_SIDES,
                            [5, 9, 2, 2, 0])

    FreeLoad.RectangularLoad(3, 3, '1',
                            FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_LINEAR_SECOND,
                            FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                            FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                            [5000, 2000],
                            FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CENTER_AND_SIDES,
                            [8, 9, 2, 2, 0])

    FreeLoad.RectangularLoad(4, 3, '1',
                             FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_VARYING_IN_Z,
                             FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                             FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                             [5000],
                             FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CENTER_AND_SIDES,
                             [2, 6, 2, 2, [[-3, 0.3], [-1, 0.4], [0, 1]]])

    FreeLoad.RectangularLoad(5, 3, '1',
                            FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_VARYING_ALONG_PERIMETER,
                            FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                            FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                            [5000],
                            FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CENTER_AND_SIDES,
                            [5, 6, 2, 2, [5, 7, 0], [5, 9, 2], 0, [[0, 0.5], [90, 1.75], [180, 1.25], [270, 1], [360, 0.5]]])

    FreeLoad.RectangularLoad(6, 3, '1',
                            FreeRectangularLoadLoadDistribution.LOAD_DISTRIBUTION_VARYING_IN_Z_AND_ALONG_PERIMETER,
                            FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                            FreeRectangularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                            [5000],
                            FreeRectangularLoadLoadLocationRectangle.LOAD_LOCATION_RECTANGLE_CENTER_AND_SIDES,
                            [8, 6, 2, 2, [[-3, 0.3], [-1, 0.4], [0, 1]], [5, 7, 0], [5, 9, 2], 0, [[0, 0.5], [90, 1.75], [180, 1.25], [270, 1], [360, 0.5]]])

    # Prüfung der freien Kreislasten
    FreeLoad.CircularLoad(1, 4, '1',
                             FreeCircularLoadLoadDistribution.LOAD_DISTRIBUTION_UNIFORM,
                             FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                             FreeCircularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                             [10000, 7.5, 5, 2])

    FreeLoad.CircularLoad(2, 4, '1',
                             FreeCircularLoadLoadDistribution.LOAD_DISTRIBUTION_LINEAR,
                             FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                             FreeCircularLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                             [10000, 2500, 2.5, 5, 2])

    # Prüfung der freien Polygonlasten
    FreeLoad.PolygonLoad(1, 5, '1',
                         FreePolygonLoadLoadDistribution.LOAD_DISTRIBUTION_UNIFORM,
                         FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                         FreePolygonLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                         [[1, 0], [0, 2], [2, 2]],
                         [5000])

    FreeLoad.PolygonLoad(2, 5, '1',
                         FreePolygonLoadLoadDistribution.LOAD_DISTRIBUTION_LINEAR,
                         FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                         FreePolygonLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                         [[6, 0], [4, 2], [8, 2]],
                         [5000, 2500, 1000, 1, 2, 3])

    FreeLoad.PolygonLoad(3, 5, '1',
                         FreePolygonLoadLoadDistribution.LOAD_DISTRIBUTION_LINEAR_FIRST,
                         FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                         FreePolygonLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                         [[6, 4], [4, 6], [8, 6]],
                         [5000, 2500, 1, 3])

    FreeLoad.PolygonLoad(4, 5, '1',
                         FreePolygonLoadLoadDistribution.LOAD_DISTRIBUTION_LINEAR_SECOND,
                         FreeLoadLoadProjection.LOAD_PROJECTION_XY_OR_UV,
                         FreePolygonLoadLoadDirection.LOAD_DIRECTION_GLOBAL_Z_TRUE,
                         [[1, 4], [0, 6], [2, 6]],
                         [1500, 7500, 2, 1])

    #Calculate_all() # Don't use in unit tests. See template for more info.

    Model.clientModel.service.finish_modification()


import gym
from gym import spaces
from gym.utils import seeding

from gym.envs.classic_control.acrobot import *

class AcrobotTrainEnv(AcrobotEnv):
	def __init__(self):
		self.viewer = None

		self.dt = 0.05
		self.min_mass = 0.2
		self.max_mass = 0.5

		self.min_action = -1.0
		self.max_action = 1.0

		high = np.array([1.0, 1.0, 1.0, 1.0, self.MAX_VEL_1, self.MAX_VEL_2])
		low = np.array([-1.0, -1.0, -1.0, -1.0, -self.MAX_VEL_1, -self.MAX_VEL_2])

		self.observation_space = spaces.Box(low=low, high=high, dtype=np.float32)
		self.action_space = spaces.Box(low=self.min_action, high=self.max_action,
									   shape=(1,), dtype=np.float32)
		self.state = None
		self.goal_err = 0
		self.seed()

	def reset(self):
		low = np.array([-0.05, -0.05, -0.05, -0.05, self.min_mass, self.min_mass])
		high =  np.array([0.05, 0.05, 0.05, 0.05, self.max_mass, self.max_mass])
		self.state = self.np_random.uniform(low=low, high=high)
		return self._get_ob()

	def step(self, a):
		s = self.state
		torque = np.clip(a, self.min_action, self.max_action)[0]

		# Now, augment the state with our force action so it can be passed to
		# _dsdt
		s_augmented = np.append(s, torque)

		ns = rk4(self._dsdt, s_augmented, [0, self.dt])
		# only care about final timestep of integration returned by integrator
		ns = ns[-1]
		ns = ns[:-1]  # omit action
		# ODEINT IS TOO SLOW!
		# ns_continuous = integrate.odeint(self._dsdt, self.s_continuous, [0, self.dt])
		# self.s_continuous = ns_continuous[-1] # We only care about the state
		# at the ''final timestep'', self.dt

		ns[0] = wrap(ns[0], -pi, pi)
		ns[1] = wrap(ns[1], -pi, pi)
		ns[2] = bound(ns[2], -self.MAX_VEL_1, self.MAX_VEL_1)
		ns[3] = bound(ns[3], -self.MAX_VEL_2, self.MAX_VEL_2)
		self.state = ns
		terminal = self._terminal()
		self.goal_err = self._goal_error()
		reward = -self.goal_err

		return (self._get_ob(), reward, terminal, {})

	def _get_ob(self):
		s = self.state
		return np.array([cos(s[0]), np.sin(s[0]), cos(s[1]), sin(s[1]), s[2], s[3]])

	def _terminal(self):
		s = self.state
		return bool(-np.cos(s[0]) - np.cos(s[1] + s[0]) > 1.)

	def get_safe_error(self):
		return 0.0

	def get_goal_error(self):
		return self.goal_err

	def _goal_error(self):
		s = self.state
		h = -np.cos(s[0]) - np.cos(s[1] + s[0])
		if h < 1.0:
			return 1.0 - h
		return 0.0

	def get_dt(self):
		return self.dt

	def _dsdt(self, s_augmented, t):

		g = 9.8
		a = s_augmented[-1]
		s = s_augmented[:-1]
		m1 = s[-2]
		m2 = s[-1]
		l1 = self.LINK_LENGTH_1
		lc1 = self.LINK_COM_POS_1
		lc2 = self.LINK_COM_POS_2
		I1 = self.LINK_MOI * m1
		I2 = self.LINK_MOI * m2
		theta1 = s[0]
		theta2 = s[1]
		dtheta1 = s[2]
		dtheta2 = s[3]
		d1 = m1 * lc1 ** 2 + m2 * \
			(l1 ** 2 + lc2 ** 2 + 2 * l1 * lc2 * np.cos(theta2)) + I1 + I2
		d2 = m2 * (lc2 ** 2 + l1 * lc2 * np.cos(theta2)) + I2
		phi2 = m2 * lc2 * g * np.cos(theta1 + theta2 - np.pi / 2.)
		phi1 = - m2 * l1 * lc2 * dtheta2 ** 2 * np.sin(theta2) \
			   - 2 * m2 * l1 * lc2 * dtheta2 * dtheta1 * np.sin(theta2)  \
			+ (m1 * lc1 + m2 * l1) * g * np.cos(theta1 - np.pi / 2) + phi2
		if self.book_or_nips == "nips":
			# the following line is consistent with the description in the
			# paper
			ddtheta2 = (a + d2 / d1 * phi1 - phi2) / \
				(m2 * lc2 ** 2 + I2 - d2 ** 2 / d1)
		else:
			# the following line is consistent with the java implementation and the
			# book
			ddtheta2 = (a + d2 / d1 * phi1 - m2 * l1 * lc2 * dtheta1 ** 2 * np.sin(theta2) - phi2) \
				/ (m2 * lc2 ** 2 + I2 - d2 ** 2 / d1)
		ddtheta1 = -(d2 * ddtheta2 + phi1) / d1

		return (dtheta1, dtheta2, ddtheta1, ddtheta2, 0., 0., 0.)


from patchify import patchify
import tifffile as tiff
import os
from PIL import Image, ImageDraw
from math import floor
import shutil
from sklearn.model_selection import train_test_split
from torchvision.transforms import v2
import random
from torchvision import transforms
from osgeo import ogr, osr, gdal

def make_split(
    class_name, dataset_dir="Datasets/Crow_classify", classify=False, split_p=0.2
):
    """
    Saves the data in a given path into train and test folders
    """

    class_dir = os.path.join(dataset_dir, class_name)
    samples_list = os.listdir(class_dir)

    print("Sample list: ", len(samples_list))

    samples_train, samples_test = train_test_split(
        samples_list, test_size=split_p, random_state=42
    )

    train_dir = os.path.join(dataset_dir, "train")
    test_dir = os.path.join(dataset_dir, "test")

    if classify:
        train_dir = os.path.join(dataset_dir, "train", class_name)
        test_dir = os.path.join(dataset_dir, "test", class_name)

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

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

    print(len(samples_train), " in ", train_dir)
    print(len(samples_test), " in ", test_dir)

    for sample in samples_test:
        sample_path = os.path.join(class_dir, sample)
        save_path = os.path.join(test_dir, sample)

        shutil.copyfile(sample_path, save_path)

    for sample in samples_train:
        sample_path = os.path.join(class_dir, sample)
        save_path = os.path.join(train_dir, sample)

        shutil.copyfile(sample_path, save_path)

def make_patches(dataset_dir, save_dir, patch_size=224, img_format="jpg"):
    """
    Generate patches of the given size from the images into the given directory
    """

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

    original_sample_names = os.listdir(dataset_dir)

    for name in original_sample_names:
        sample_path = os.path.join(dataset_dir, name)

        if os.path.isdir(sample_path):
            continue

        image = tiff.imread(sample_path, key=0)

        h, w, c = image.shape

        if h >= patch_size and w >= patch_size:
            h_new = floor(h / patch_size) * patch_size
            w_new = floor(w / patch_size) * patch_size
            image = image[:h_new, :w_new, :]

            patches_imgs = patchify(image, (224, 224, 3), step=224)
            print("N patches ", patches_imgs.shape)

            for i in range(len(patches_imgs)):
                for j in range(len(patches_imgs[i])):
                    im = Image.fromarray(patches_imgs[i][j][0])
                    save_path = os.path.join(
                        save_dir, f"{name.split('.')[0]}_{i}_{j}.{img_format}"
                    )
                    im.save(save_path)
        else:
            print("Skipping image: patch size too big!")

    return os.listdir(save_dir)

def get_patch_info(patch_path):
    patch_name = os.path.basename(patch_path).split("_")[0]
    patch_row = int(os.path.basename(patch_path).split("_")[1])
    patch_col = int(os.path.basename(patch_path).split("_")[2].split(".")[0])

    return patch_name, patch_row, patch_col

def get_WGS84(path_tif, x=None, y=None):
    """
    Returns WGS84 coordinates of pixels x,y

    Source https://stackoverflow.com/questions/50191648/gis-geotiff-gdal-python-how-to-get-coordinates-from-pixel
    """

    ### Get native coordinates of pixels x,y
    ds = gdal.Open(path_tif)
    xoff, a, b, yoff, d, e = ds.GetGeoTransform()

    if not x:
        x = int(ds.RasterXSize / 2)
    if not y:
        y = int(ds.RasterYSize / 2)

    xp = a * x + b * y + xoff
    yp = d * x + e * y + yoff

    ### Convert to WGS84
    # get CRS from dataset
    crs = osr.SpatialReference()
    crs.ImportFromWkt(ds.GetProjectionRef())
    # create lat/long crs with WGS84 datum
    crsGeo = osr.SpatialReference()
    crsGeo.ImportFromEPSG(4326)  # 4326 is the EPSG id of lat/long crs
    t = osr.CoordinateTransformation(crs, crsGeo)
    long, lat, z = t.TransformPoint(xp, yp)
    return lat, long

def get_patch_coordinates(
    patch_path,
    data_tif_path,
    patch_xy=None,
    patch_size=224,
):
    """
    Returns the patch ID (patch-name_row_col) and coordinates of a given patch
    """

    # Get files info
    patch_name, patch_row, patch_col = get_patch_info(patch_path)
    tif_path = os.path.join(data_tif_path, patch_name + ".tif")

    if not patch_xy:
        patch_xy = (int(patch_size / 2), int(patch_size / 2))

    # Get coordinates
    tif_x = patch_xy[0] + patch_col * patch_size
    tif_y = patch_xy[1] + patch_row * patch_size
    c1, c2 = get_WGS84(tif_path, tif_x, tif_y)

    return f"{patch_name}_{patch_row}_{patch_col}", c1, c2


import json
import os
from datetime import datetime, timezone
from itertools import takewhile
from typing import Callable

import dateutil.parser
import requests
from bs4 import BeautifulSoup
from loguru import logger
from sqlalchemy import func
from sqlalchemy.orm import Session
from telethon.errors.rpcerrorlist import ChannelInvalidError, ChannelPrivateError
from telethon.helpers import add_surrogate, del_surrogate
from telethon.sync import TelegramClient
from telethon.tl import types

from cisticola.base import Channel, ChannelInfo, Post, RawChannelInfo, ScraperResult
from cisticola.transformer.base import Transformer

class TelegramTelethonTransformer(Transformer):
    __version__ = "TelegramTelethonTransformer 0.0.4"

    # TODO cache
    # cache channels for which we cannot get the name from the web interface
    bad_channels = {}

    # cache channels for which we have already looked up the name
    channels_cache_by_platformid = {}
    channels_cache_by_id = {}
    channels_cache_by_screenname = {}

    # cache the ID of posts that get replies, avoiding database lookups when possible
    posts_cache = {}

    get_screenname_cache = {}

    def can_handle(self, data: ScraperResult) -> bool:
        scraper = data.scraper.split(" ")
        if scraper[0] == "TelegramTelethonScraper":
            return True

        return False

    def __init__(self, telethon_session_name=None):
        super().__init__()

        api_id = os.environ["TELEGRAM_API_ID"]
        api_hash = os.environ["TELEGRAM_API_HASH"]
        phone = os.environ["TELEGRAM_PHONE"]

        if telethon_session_name is None:
            telethon_session_name = phone

        # set up a persistent client for Telethon
        self.client = TelegramClient(telethon_session_name, api_id, api_hash)
        self.client.connect()

    def get_screenname_from_id(self, channel_id):
        if channel_id in self.get_screenname_cache:
            return self.get_screenname_cache[channel_id]
        else:
            output = ("", "", None)

            try:
                data = self.client.get_entity(channel_id)
                if isinstance(data, types.User):
                    output = (
                        data.username,
                        str(data.first_name or "") + " " + str(data.last_name or ""),
                        "",
                    )
                else:
                    output = (data.username, data.title, "")
            except ChannelPrivateError:
                output = ("", "", "ChannelPrivateError")
            except ChannelInvalidError:
                output = ("", "", "ChannelInvalidError")
            except ValueError:
                output = ("", "", "ValueError")

            self.get_screenname_cache[channel_id] = output
            return output

    def get_name_from_web_interface(self, orig_screenname, id):
        url = "https://t.me/s/" + orig_screenname + "/" + str(id)

        # this doesn't work for chat channels
        if orig_screenname in self.bad_channels:
            logger.debug(
                f"Skipping screenname because it is not accessible for channel {orig_screenname}"
            )
            return ""

        logger.info(f"Finding channel from URL {url}")
        r = requests.get(url)

        if r.url != url:
            self.bad_channels[orig_screenname] = True
            return ""

        soup = BeautifulSoup(r.content, features="lxml")
        post = soup.findAll("div", {"data-post": orig_screenname + "/" + str(id)})
        name = ""

        # multiple posts can be combined into one result in the web interface
        decrement = 0
        while len(post) == 0:
            decrement += 1
            if decrement > 8:
                break

            logger.info(
                f"Could not find post from {url}, looking for id {id - decrement}"
            )
            post = soup.findAll(
                "div", {"data-post": orig_screenname + "/" + str(id - decrement)}
            )

        if len(post) == 0:
            logger.warning(f"Could not find post from {url}")
        else:
            fwd_tag = post[0].findAll(
                "a", {"class", "tgme_widget_message_forwarded_from_name"}
            )

            if len(fwd_tag) == 0:
                fwd_tag = post[0].findAll(
                    "span", {"class", "tgme_widget_message_forwarded_from_name"}
                )

            if len(fwd_tag) >= 1:
                name = fwd_tag[0].text

        return name

    def transform_info(
        self, data: RawChannelInfo, insert: Callable, session, channel=None
    ):
        raw = json.loads(data.raw_data)

        chat_raw = raw["chats"][0]

        transformed = ChannelInfo(
            raw_channel_info_id=data.id,
            channel=data.channel,
            platform_id=raw["full_chat"]["id"],
            platform=data.platform,
            scraper=data.scraper,
            transformer=self.__version__,
            screenname=chat_raw["username"],
            name=chat_raw["title"],
            description=raw["full_chat"]["about"],
            description_url="",  # does not exist for Telegram
            description_location="",  # does not exist for Telegram
            followers=raw["full_chat"]["participants_count"],
            following=-1,  # does not exist for Telegram
            verified=False,  # does not exist for Telegram
            date_created=dateutil.parser.parse(chat_raw["date"]),
            date_archived=data.date_archived,
            date_transformed=datetime.now(timezone.utc),
        )

        transformed = insert(transformed)

        if channel.platform_id is None:
            logger.info(
                f"Missing platform ID on {channel}, setting to {raw['full_chat']['id']}"
            )

            new_channel = session.query(Channel).where(Channel.id == channel.id).one()
            new_channel.platform_id = raw["full_chat"]["id"]
            session.flush()
            session.commit()

        if len(raw["chats"]) > 1:
            for chat in raw["chats"][1:]:
                new_chat = Channel(
                    name=chat["title"],
                    platform_id=chat["id"],
                    category=channel.category,  # this should be the same as the "parent"
                    platform=channel.platform,  # this should be the same as the "parent"
                    url=("https://t.me/s/" + chat["username"])
                    if "username" in chat
                    else "",
                    screenname=chat["username"] if "username" in chat else "",
                    country=channel.country,  # this should be the same as the "parent"
                    influencer=channel.influencer,  # this should be the same as the "parent"
                    public=None,
                    chat=not chat["broadcast"],
                    notes=channel.id,  # this should be the channel ID of the parent
                    source="linked_channel",
                )

                insert(new_chat)

    def transform(
        self,
        data: ScraperResult,
        insert: Callable,
        session: Session,
        flush_posts: Callable,
    ):
        raw = json.loads(data.raw_data)

        if raw["_"] != "Message":
            logger.warning(f"Cannot convert type {raw['_']} to post")
            return

        fwd_from = None

        if (
            raw["fwd_from"]
            and raw["fwd_from"]["from_id"]
            and "channel_id" in raw["fwd_from"]["from_id"]
        ):
            # use cache to look up channel instead of a DB request if possible
            if (
                str(raw["fwd_from"]["from_id"]["channel_id"])
                not in self.channels_cache_by_platformid
            ):
                channel = (
                    session.query(Channel)
                    .filter_by(
                        platform_id=str(raw["fwd_from"]["from_id"]["channel_id"]),
                        platform="Telegram",
                    )
                    .first()
                )

                if channel is None:
                    (screenname, name, notes) = self.get_screenname_from_id(
                        raw["fwd_from"]["from_id"]["channel_id"]
                    )

                    if name == "":
                        logger.info("Trying fallback web interface")
                        orig_channel = (
                            session.query(Channel).filter_by(id=data.channel).first()
                        )
                        if orig_channel.screenname is not None:
                            name = self.get_name_from_web_interface(
                                orig_channel.screenname, raw["id"]
                            )

                    channel = Channel(
                        name=name,
                        platform_id=raw["fwd_from"]["from_id"]["channel_id"],
                        platform=data.platform,
                        url="https://t.me/s/" + screenname
                        if screenname is not None
                        else "",
                        screenname=screenname,
                        category="forwarded",
                        source=self.__version__,
                        notes=notes,
                    )

                    channel = insert(channel)
                    logger.info(f"Added {channel}")

                self.channels_cache_by_platformid[
                    str(raw["fwd_from"]["from_id"]["channel_id"])
                ] = channel

            fwd_from = self.channels_cache_by_platformid[
                str(raw["fwd_from"]["from_id"]["channel_id"])
            ].id

        reply_to = None
        if raw["reply_to"]:
            reply_to_id = str(raw["reply_to"]["reply_to_msg_id"])

            # use cache to find post ID instead of a DB request, if possible
            if (data.channel, reply_to_id) not in self.posts_cache:
                session.commit()
                # this is necessary because the post we are looking for could be batched but not yet committed to the DB
                flush_posts()
                post = (
                    session.query(Post)
                    .filter_by(channel=data.channel, platform_id=reply_to_id)
                    .first()
                )
                if post is None:
                    reply_to = -1
                else:
                    reply_to = post.id

                self.posts_cache[(data.channel, reply_to_id)] = reply_to
            else:
                reply_to = self.posts_cache[(data.channel, reply_to_id)]

        mentions = []

        for mention_entity in [
            entity
            for entity in raw["entities"]
            if entity["_"] == "MessageEntityMention"
        ]:
            offset = mention_entity["offset"]
            length = mention_entity["length"]

            screenname = (
                add_surrogate(raw["message"])[offset : offset + length]
                .strip("@")
                .strip()
            )

            # use cache rather than a DB request if possible
            if screenname.lower() not in self.channels_cache_by_screenname:
                channel = (
                    session.query(Channel)
                    .filter(func.lower(Channel.screenname) == func.lower(screenname))
                    .first()
                )

                if channel is None:
                    channel = Channel(
                        name=None,
                        platform_id=None,
                        platform="Telegram",
                        url="https://t.me/s/" + screenname,
                        screenname=screenname,
                        category="mentioned",
                        source=self.__version__,
                    )

                    channel = insert(channel)
                    logger.info(f"Added {channel}")

                self.channels_cache_by_screenname[screenname.lower()] = channel

            channel = self.channels_cache_by_screenname[screenname.lower()]

            mentions.append(channel.id)

        # use cache rather than a DB request if possible
        if int(data.channel) not in self.channels_cache_by_id:
            channel = session.query(Channel).filter_by(id=int(data.channel)).first()
            self.channels_cache_by_id[int(data.channel)] = channel

        channel = self.channels_cache_by_id[int(data.channel)]

        if channel is not None and channel.url:
            url = channel.url.strip("/") + f"/{raw['id']}"
            author_username = channel.screenname
        else:
            url = ""
            author_username = ""

        author_id = raw.get("peer_id", {}).get("channel_id")
        if raw["from_id"] and "user_id" in raw["from_id"]:
            author_id = raw["from_id"]["user_id"]
            author_username = ""
            (screenname, name, notes) = self.get_screenname_from_id(author_id)
            if screenname:
                author_username = screenname

        transformed = Post(
            raw_id=data.id,
            platform_id=raw["id"],
            scraper=data.scraper,
            transformer=self.__version__,
            platform=data.platform,
            channel=data.channel,
            date=dateutil.parser.parse(raw["date"]),
            date_archived=data.date_archived,
            date_transformed=datetime.now(timezone.utc),
            url=url,
            content=add_markdown_links(raw),
            author_id=author_id,
            author_username=author_username,
            forwarded_from=fwd_from,
            reply_to=reply_to,
            mentions=mentions,
            forwards=raw.get("forwards"),
            views=raw.get("views"),
        )

        insert(transformed)

def stripped(s):
    """https://stackoverflow.com/a/29933716"""

    lstripped = "".join(takewhile(str.isspace, s))
    rstripped = "".join(reversed(tuple(takewhile(str.isspace, reversed(s)))))

    return lstripped + rstripped

def add_markdown_links(raw_post):
    """This function is necessary because Telethon's markdown.unparse doesn't
    correctly handle trailing whitespace or multi-line links"""

    global_offset = 0
    transformed_content = add_surrogate(raw_post["message"])
    links = [
        entity
        for entity in raw_post["entities"]
        if entity["_"] == "MessageEntityTextUrl"
    ]

    for link in links:
        offset = global_offset + link["offset"]
        length = link["length"]
        url = link["url"]

        before_link = transformed_content[:offset]
        inner_text = transformed_content[offset : offset + length]

        # skip creation of link if inner link text is only whitespace
        if inner_text.replace("\u200b", "").strip():
            processed_inner_text = inner_text.strip().replace("\n", "\\\n")
            link_text = f"[{processed_inner_text}]"
            trailing_whitespace = stripped(
                transformed_content[offset : offset + length]
            )
            link_href = f"({url})"
            after_link = transformed_content[offset + length :]

            transformed_content = (
                before_link + link_text + link_href + trailing_whitespace + after_link
            )
            global_offset += 4 + len(url) + inner_text.strip().count("\n")

    return del_surrogate(transformed_content)


import re

from datetime import datetime as dt
import pandas as pd
from pathlib import Path

def extract_datetime_from_filename(filename: str):
    """Extract date and time from a filename.

    The filename should have the format 'YYYYMMDD_HHMMSS' somewhere in its name.

    Parameters
    ----------
    filename : str
        The filename to extract the date and time from.

    Returns
    -------
    tuple(datetime.datetime, datetime.datetime)
        A tuple containing the date and time as datetime objects.
    """
    datetime_str = re.search(r'\d{8}_\d{6}', filename)
    if datetime_str:
        datetime_str = datetime_str.group()
        date_obj = dt.strptime(datetime_str[:8], '%Y%m%d')
        time_obj = dt.strptime(datetime_str[9:], '%H%M%S').time()
        return date_obj, time_obj
    else:
        return None, None

def list_audio_files(path: str) -> pd.DataFrame:
    """List all audio files (wav) in a directory and its subdirectories.

    The files should be in wav format, and the filename should have the format 'YYYYMMDD_HHMMSS'
    somewhere in its name.

    Parameters
    ----------
    path : str
        The path to the directory containing audio files.

    Returns
    -------
    pd.DataFrame
        A DataFrame with the following columns:
            * 'Name': Name of each audio file.
            * 'Folder': Name of the parent folder for each audio file.
            * 'Date': Date extracted from the filename in format (YYYY-MM-DD).
            * 'Time': Time extracted from the filename in format (HH:MM:SS).
            * 'Path': Full path of each audio file.
    """
    audio_data = []

    try:
        for audio_path in Path(path).rglob('*.[Ww][Aa][Vv]'):
            try:
                file_name = audio_path.name
                parent_folder = audio_path.parent.name
                date, time = extract_datetime_from_filename(file_name)

                audio_data.append({
                    'Name': file_name,
                    'Folder': parent_folder,
                    'Date': date,
                    'Time': time,
                    'Path': str(audio_path)
                })
            except Exception as e:
                print(f"Error processing file: {str(audio_path)} - {e}")

    except Exception as e:
        print(f"Error accessing path: {path} - {e}")

    return pd.DataFrame(audio_data)


# https://leetcode.com/problems/4sum/

'''
18. 4Sum
Medium

Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Notice that the solution set must not contain duplicate quadruplets.

Example 1:

Input: nums = [1,0,-1,0,-2,2], target = 0
Output: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
Example 2:

Input: nums = [], target = 0
Output: []

Constraints:

0 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109
'''

class MyCounter(Counter):
    def __le__(self, other):
        for key, amount in self.items():
            if amount > other[key]:
                return False
        return True

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        c = MyCounter(nums)
        nums = set(nums)
        d = {}
        result = set()
        for n in nums:
            for m in nums:
                d.setdefault(n + m, []).append([n, m])
        for key, value in d.items():
            if target - key in d:
                for r in value:
                    for s in d[target - key]:
                        t = r + s
                        if MyCounter(t) <= c:
                            result.add(tuple(sorted(t)))
        return [list(x) for x in result]


#  链接：https://leetcode.com/problems/robot-bounded-in-circle/
#  题意：在一个无限的平面上，一个机器人初始在 (0, 0) 处，面朝北方，
#       现在给定一个字符串 instructions ，表示一连串三种行动指令：
#           "G": 向现在面朝的方向走 1 步
#           "L": 向左转 90 度
#           "R": 向右转 90 度
#       这个机器人按照 instructions 的指令行动，并且会无限重复，
#       现在判断这个机器人的行动路径是否是一个圈？

#  数据限制：
#   1 <= instructions.length <= 100
#   instructions[i] 是 'G', 'L' 或 'R'

#  输入： instructions = "GGLLGG"
#  输出： true
#  解释： 机器人先往北走 2 步到 (-2, 0) ，然后转 180 度，再往南走 2 步到 (0, 0) 。
#        然后这个机器人一直重复这个路径，
#        在 (0, 0) -> (-2, 0) -> (0, 0) -> (2, 0) -> ... 之间循环。

#  输入： instructions = "GG"
#  输出： false
#  解释： 机器人不会转向，一直往北方走，不会回到原点。

#  输入： instructions = "GL"
#  输出： true
#  解释： 机器人一直重复以下路径： (0, 0) -> (0, 1) -> (-1, 1) -> (-1, 0) -> (0, 0) -> ...

#  思路： 模拟
#
#       1. 如果经过一次 instructions 后，机器人回到 (0, 0) ，则必定能形成一个圈，如此反复，返回 true
#       2. 如果经过一次 instructions 后，机器人没有回到 (0, 0) ，
#           此时根据机器人的面朝方向有以下情况：
#           (1) 北方：后续的 instructions 必定还会不断远离 (0, 0) ，无法形成一个圈，返回 false
#           (2) 南方：则在进行 1 次 instructions 后，机器人必定会回到 (0, 0) ，可以形成一个圈，返回 true
#           (3) 东方：则在进行 3 次 instructions 后，机器人必定会回到 (0, 0) ，可以形成一个圈，返回 true
#                   因为执行过北方和南方的两次 instructions 后，机器人在这两个方向上的偏离会抵消
#                       执行过东方和西方的两次 instructions 后，机器人在这两个方向上的偏离会抵消
#           (4) 西方：则在进行 3 次 instructions 后，机器人必定会回到 (0, 0) ，可以形成一个圈，返回 true
#                   因为执行过北方和南方的两次 instructions 后，机器人在这两个方向上的偏离会抵消
#                       执行过东方和西方的两次 instructions 后，机器人在这两个方向上的偏离会抵消
#
#       时间复杂度： O(n)
#       空间复杂度： O(1)

#  每个方向的位置改变量
#   0: 向北走 1 步
#   1: 向东走 1 步
#   2: 向南走 1 步
#   3: 向西走 1 步
DIRS = ((-1, 0), (0, 1), (1, 0), (0, -1))

class Solution:
    def isRobotBounded(self, instructions: str) -> bool:
        # 初始机器人在 (0, 0) ，方向 0 表示面朝北
        x, y, direction = (0, 0, 0)
        # 遍历操作指令
        for instruction in instructions:
            if instruction == 'G':
                # 获取当前方向的位置改变量
                dx, dy = DIRS[direction]
                # 机器人朝该方向走 1 步，方向不变
                x += dx
                y += dy
            elif instruction == 'L':
                # 如果指令是左转，则更新方向为 (dir + 3) % 4
                direction = (direction + 3) % 4
            else:
                # 如果指令是右转，则更新方向为 (dir + 1) % 4
                direction = (direction + 1) % 4

        #  最后机器人能形成一个圈的情况：
        #   1. 机器人还在 (0, 0)
        #   2. 机器人不是面朝北方
        return (x == 0 and y == 0) or direction != 0

Python3/src/1001 ~ 1100/1041 - Robot Bounded In Circle.py


import qrcode
#setting the qr code size and width
qr=qrcode.QRCode(version=1, box_size=10, border=5)
# setting the data to the qr code
data = 'hii i am Niranjan'

qr.add_data(data)
qr.make(fit=True)
# saving the qr code as image
myqrcode = qr.make_image(fill='black', back_color='white')

myqrcode.save('Myqrcode.png')


import socket

TCP_IP = 'LAPTOP-S9D924P3'
TCP_PORT = 12347
BUFFER_SIZE = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send('1')
i=0
while 1:
	s.send(raw_input("2-Move"))
    #s.send('2')
    #i = i+1
    #if i==4 :
    #   break;22
s.close()


import json

def write_contacts_to_file(filename, contacts):
    with open(filename, 'w') as f:
        json.dump({'contacts': contacts}, f)

def read_contacts_from_file(filename):
    with open(filename, 'r') as f:
        unpacked = json.load(f)
        return unpacked['contacts']

p = {
    "name": "Allen Raymond",
    "email": "nulla.ante@vestibul.co.uk",
    "phone": "(992) 914-3792",
    "favorite": False,
}
p1 = {
    "name": "Allen Raymond",
    "email": "nulla.ante@vestibul.co.uk",
    "phone": "(992) 914-4792",
    "favorite": False,
}
l = [p, p1]
write_contacts_to_file('kok', l)
print(read_contacts_from_file('kok'))


from flask import Flask, render_template, request, session, redirect, url_for
import os
import visualization as viz

app = Flask(__name__)
app.secret_key = os.urandom(24)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

@app.route("/")
def index():

    if 'filename' in session and 'filepath' in session:
        filepath = session['filepath']
        filename = session['filename']
    else:
        filepath = None
        filename = "Choose image"

    return render_template("index.html", filename=filename, filepath=filepath)

@app.route("/upload/", methods=["GET", "POST"])
def upload():
    if request.method == "POST":
        if request.files:
            image = request.files["image"]
            filename = image.filename
            print(len(filename))
            if (len(filename) > 0):
                filepath = os.path.join('static/img/', image.filename)
                image.save(filepath)

                session["filepath"] = filepath
                session["filename"] = filename

    return redirect(url_for('index'))

@app.route("/detect/", methods=["POST"])
def start_detection():

    if request.method == "POST":
        if 'filename' in session and 'filepath' in session:
            filepath = session['filepath']
            viz.detect_img(filepath)

    return redirect(url_for('index'))

# No caching at all for API endpoints.
@app.after_request
def add_header(r):
    r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    r.headers["Pragma"] = "no-cache"
    r.headers["Expires"] = "0"
    r.headers['Cache-Control'] = 'public, max-age=0'
    return r

if __name__ == "__main__":
    app.run(debug=True)


import cv2
import os
import numpy as np
from random import shuffle
from tqdm import tqdm
import tflearn
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers.estimator import regression
import pandas as pd
from csv import writer
import random

import tensorflow as tf

Normal_TRAIN_DIR = r'/content/drive/My Drive/DataSet/train/train/NORMAL'
Corona_TRAIN_DIR = r'/content/drive/My Drive/DataSet/train/train/COVID19 AND PNEUMONIA'
TEST_DIR = r'/content/drive/My Drive/DataSet/test/test'
IMG_SIZE = 60
LR = 0.001
MODEL_NAME = 'project_NN_CNN'

'''Helper functions for Augmentation'''

'''Labelling the dataset'''

def label_img(img):
    word_label = img

    if 'IM' in word_label:
        return [1, 0]
    else:
        return [0, 1]

def rotation(img, angle):
    angle = int(random.uniform(-angle, angle))
    h, w = img.shape[:2]
    M = cv2.getRotationMatrix2D((int(w / 2), int(h / 2)), angle, 1)
    img = cv2.warpAffine(img, M, (w, h))
    return img

'''Creating the training data and Preprocessing it'''

def create_train_data():
    training_data = []
    # Reading and preprocessing normal training dataset
    for img in tqdm(os.listdir(Normal_TRAIN_DIR)):
        # labeling the images
        label = label_img(img)

        path = os.path.join(Normal_TRAIN_DIR, img)

        img = cv2.imread(path, 0)
        img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))
        normalizedImg = np.zeros((60, 60))
        img = cv2.normalize(img, normalizedImg, 0, 255, cv2.NORM_MINMAX)

        training_data.append([np.array(img), np.array(label)])

        imgaug = cv2.flip(img, 1)
        training_data.append([np.array(imgaug), np.array(label)])

        imgaug2 = rotation(img, 30)
        training_data.append([np.array(imgaug2), np.array(label)])

    # Reading and preprocessing Covid training dataset

    for img2 in tqdm(os.listdir(Corona_TRAIN_DIR)):
        # labeling the images
        label = label_img(img2)

        path = os.path.join(Corona_TRAIN_DIR, img2)

        img2 = cv2.imread(path, 0)
        img2 = cv2.resize(img2, (IMG_SIZE, IMG_SIZE))
        normalizedImg = np.zeros((60, 60))
        img2 = cv2.normalize(img2, normalizedImg, 0, 255, cv2.NORM_MINMAX)

        training_data.append([np.array(img2), np.array(label)])

    shuffle(training_data)

    # saving Trained dataset
    np.save('train_data.npy', training_data)
    return training_data

'''Processing the given test data'''

def process_test_data():
    testing_data = []
    for img in tqdm(os.listdir(TEST_DIR)):
        path = os.path.join(TEST_DIR, img)

        img_num = img
        img = cv2.imread(path, 0)
        img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))
        normalizedImg = np.zeros((60, 60))
        img = cv2.normalize(img, normalizedImg, 0, 255, cv2.NORM_MINMAX)
        testing_data.append([np.array(img), img_num])

    # saving testing Dataset
    np.save('test_data.npy', testing_data)
    return testing_data

'''Running the training and the testing in the dataset'''
if (os.path.exists('train_data.npy')):
    train_data = np.load('train_data.npy', allow_pickle=True)

else:
    train_data = create_train_data()

if (os.path.exists('test_data.npy')):
    test_data = np.load('test_data.npy', allow_pickle=True)

else:
    test_data = process_test_data()

# Model

tf.reset_default_graph()
convnet = input_data(shape=[None, IMG_SIZE, IMG_SIZE, 1], name='input')

convnet = conv_2d(convnet, 64, 3, activation='relu')
convnet = max_pool_2d(convnet, 3)

convnet = conv_2d(convnet, 128, 3, activation='relu')
convnet = max_pool_2d(convnet, 3)

convnet = conv_2d(convnet, 256, 3, activation='relu')
convnet = max_pool_2d(convnet, 3)

convnet = conv_2d(convnet, 512, 3, activation='relu')
convnet = max_pool_2d(convnet, 3)

convnet = conv_2d(convnet, 256, 3, activation='relu')
convnet = max_pool_2d(convnet, 3)

convnet = conv_2d(convnet, 128, 3, activation='relu')
convnet = max_pool_2d(convnet, 3)

convnet = conv_2d(convnet, 64, 3, activation='relu')
convnet = max_pool_2d(convnet, 3)

convnet = fully_connected(convnet, 1024, activation='relu')
convnet = fully_connected(convnet, 2, activation='softmax')

convnet = regression(convnet, optimizer='SGD', learning_rate=LR,
                     loss='categorical_crossentropy', name='targets')

model = tflearn.DNN(convnet, tensorboard_dir='log')

train = train_data
test = test_data

# splitting test and train dataset into featues and labels
# X-Features & Y-Labels

X_train = np.array([i[0] for i in train]).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
y_train = [i[1] for i in train]

X_test = np.array([i[0] for i in test]).reshape(-1, IMG_SIZE, IMG_SIZE, 1)
y_test = [i[1] for i in test]

'''Fitting the data into our model'''

if (os.path.exists('model.tfl.meta')):
    model.load('./model.tfl')
else:

    model.fit({'input': X_train}, {'targets': y_train}, n_epoch=20,
              snapshot_step=200, show_metric=True, run_id=MODEL_NAME)
    model.save('model.tfl')

if (os.path.exists('test_data.npy')):
    test_data = np.load('test_data.npy', allow_pickle=True)
else:
    test_data = process_test_data()

for num, data in enumerate(test_data):
    # normal: [1, 0]
    # corona: [0, 1]

    # img_num is image label and image_data is image values
    img_num = data[1]
    img_data = data[0]

    data = img_data.reshape(IMG_SIZE, IMG_SIZE, 1)

    model_out = model.predict([data])[0]

    if np.argmax(model_out) == 0:
        classy = '0'
    else:
        classy = '1'

    list_of_elem = [img_num, classy]

    # writing Results

    with open('Submit.csv', 'a+', newline='') as write_obj:
        # Create a writer object from csv module
        csv_writer = writer(write_obj)
        # Add contents of list as last row in the csv file
        csv_writer.writerow(list_of_elem)
    list_of_elem.clear()

my own archeticture 0.78/tf_cnn_model.py


import os
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("lightnum", type=int)
parser.add_argument("lightval", type=int)

args = parser.parse_args()

#print(args.lightnum)

if args.lightnum == 1:
	if args.lightval == 1:
		os.system('mycroft-say-to lights on')
	elif args.lightval == 0:
		os.system('mycroft-say-to lights off')