#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Jul 15 15:07:50 2018

@author: ajdavis
"""

import json
import urllib.request
import pandas as pd
import requests
from bs4 import BeautifulSoup
import re
import seaborn as sns
import statsmodels.api as sm
import matplotlib.pyplot as plt
from statsmodels.graphics.gofplots import ProbPlot
import patsy
from diagnostic_plots import diagnostic_plots
import numpy as np
import geocoder
import itertools
import seaborn as sns
from sklearn.linear_model import LinearRegression
from sklearn import metrics
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
from sklearn.cross_validation import train_test_split
from sklearn.cross_validation import KFold
from sklearn.cross_validation import cross_val_score
from sklearn.model_selection import learning_curve

import warnings
warnings.filterwarnings('ignore')

## Helper functions
def trans_price(row):
    if row['two_grams'] != 0:
        return row['two_grams']/2
    elif row['eighth'] !=0:
        return row['eighth']/3.5
    elif row['quarter'] !=0:
        return row['quarter']/7
    elif row['half_ounce'] !=0:
        return row['half_ounce']/14
    elif row['ounce'] !=0:
        return row['half_ounce']/28
    else:
        return row['gram']

def get_gcs(list_names):
    gcs = []
    for name in list_names:
        g = geocoder.google(name)
        gc = g.latlng
        gcs.append(gc)
        gcs = list(map(str, gcs))
        gcs = [gc.replace('[', '') for gc in gcs]
        gcs = [gc.replace(']', '') for gc in gcs]
        gcs = [gc.replace(', ', ',') for gc in gcs]
        gcs = [i for i in gcs if i != 'None']
    return gcs

def get_disp_names(gc):
    url = 'https://api-g.weedmaps.com/wm/v2/location?include%5B%5D=regions.listings&latlng={}'.format(gc)
    req = urllib.request.urlopen(url)
    data = json.loads(req.read().decode('utf-8'))
    lst = data['data']['regions']['dispensary']['listings']
    disp_df = pd.DataFrame()
    for d in lst:
        df = pd.DataFrame.from_dict(d)
        disp_df= disp_df.append(df)
    return list(disp_df['slug'].unique())

def menu_to_df(disp_names):
    url = 'https://api-g.weedmaps.com/wm/web/v1/listings/{}/menu?type=dispensary'.format(disp_names)
    req = urllib.request.urlopen(url)
    data = json.loads(req.read().decode('utf-8'))
    try:
        m_dict = { k:[d[k] for d in data['categories']] for k in data['categories'][0] }
    except:
        print("Error")
    weed_df = pd.DataFrame()
    try:
        for d in m_dict['items']:
            df = pd.DataFrame.from_dict(d)
            weed_df = weed_df.append(df)
            weed_df = weed_df[['prices', 'body', 'license_type', 'category_name']]
    except:
        print("Error")
    return weed_df

def munge_df(df):
    df[['THC','CBD']] = df['body'].str.split('THC', 1, expand = True)
    df['CBD'] = pd.to_numeric(df['CBD'].str.split('%').str[0].fillna(0), errors = 'coerce')
    df['THC'] = pd.to_numeric(df['THC'].str.split('%').str[0].fillna(0), errors = 'coerce')
    df['prices'] = df['prices'].astype(str)
    df["prices"] = df["prices"].apply(lambda x : dict(eval(x)) )
    tmp = df["prices"].apply(pd.Series )
    df = pd.concat([df, tmp], axis=1)
    df['price'] = df.apply(trans_price, axis=1)
    df = df[['price', 'THC', 'CBD', 'license_type', 'category_name']]
    df['ln_price'] = np.log(df['price'] + .000000001)
    df['sqrt_price'] = np.sqrt(df['price'])
    df = df[(df != 0).all(1)]
    df = df.dropna()
    df = pd.get_dummies(df)
    return df


import copy

import cv2
from matplotlib import pyplot as plt, font_manager, rcParams

N = 9

def correction(arr):
    for row in range(9):
        temp = []
        for col in range(9):
            if arr[row][col] not in temp:
                temp.append(arr[row][col])
            else:
                grid[row][col] = 0

    for col in range(9):
        temp = []
        for row in range(9):
            if arr[row][col] not in temp:
                temp.append(arr[row][col])
            else:
                grid[row][col] = 0

def printing(arr):
    for i in range(N):
        for j in range(N):
            print(arr[i][j], end=" ")
        print()

def isSafe(grid, row, col, num):
    for x in range(9):
        if grid[row][x] == num:
            return False

    for x in range(9):
        if grid[x][col] == num:
            return False

    startRow = row - row % 3
    startCol = col - col % 3

    for i in range(3):
        for j in range(3):
            if grid[i + startRow][j + startCol] == num:
                return False
    return True

def solveSuduko(grid, row, col):
    if row == N - 1 and col == N:
        return True

    if col == N:
        row += 1
        col = 0

    if grid[row][col] > 0:
        return solveSuduko(grid, row, col + 1)

    for num in range(1, N + 1, 1):
        if isSafe(grid, row, col, num):
            grid[row][col] = num

            if solveSuduko(grid, row, col + 1):
                return True
        grid[row][col] = 0
    return False

grid = []
with open("grid.txt", "r") as text_file:
    temp = []
    for i in range(0, 9):
        line = text_file.readline()
        for ele in line[:-1]:
            temp.append(int(ele))
        grid.append(temp)
        temp = []
_grid = copy.deepcopy(grid)
correction(grid)
#print(grid)
if (solveSuduko(grid, 0, 0)):
    printing(grid)
else:
    print("Reupload Image")

image_orig = cv2.imread('output_grid.PNG')
image = copy.copy(image_orig)
font = cv2.FONT_HERSHEY_SIMPLEX

color_green = (0, 107, 56) #006B38FF
color_black = (16,24,32) #101820FF
x = 60
y = 60
org = (60, 60)
fontScale = 1
thickness = 2

#print(_grid)

for i in range(0, 9):
    for j in range(0,9):
        org = (x, y)
        if _grid[j][i] > 0:
            image = cv2.putText(image, str(grid[j][i]), org, font, fontScale, color_black, thickness, cv2.LINE_AA)
        else:
            image = cv2.putText(image, str(grid[j][i]), org, font, fontScale, color_green, thickness, cv2.LINE_AA)
        y += 75
    x += 75
    y = 60

cv2.imwrite("output_sudoku" + ".jpg", image)

#plt.imshow(image)
#plt.show()


data = {}
with open('catalog_full.csv', 'r') as f:
	line = f.readline()
	while line:
		items = line.split(",")
		gender = items[5]
		money = float(items[6][0:-1])
		gender_data = data.get(gender)
		if gender_data is None:
			small_data = [money, 1]
			data[gender] = small_data
		else:
			small_data = [data[gender][0]+money, data[gender][1]+1]
			data[gender] = [data[gender][0]+money, data[gender][1]+1]

		line = f.readline()

for k in data:
	total = data[k][0]
	number = data[k][1]
	del data[k][1]
	average = total/number
	data[k][0] = average

for k, v in data.items():
	print("Средната печалба на категория за пола ",k," е ", round(v[0], 2))


from datetime import *  # 살아온 날 계산
import pandas as pd
df = pd.read_excel('1급기밀-뽀국민 사찰 자료.xlsx')  # 엑셀파일 불러오기
df = df.drop_duplicates(['이름'])  # 중복 제거
kill = df[(df['평균 답장 시간(분)'] > df['평균 답장 시간(분)'].mean())
          & (df['좋아하는 아이돌'] != '빅뱅')]  # 범죄자 색출 (빅뱅팬 제외)
year, month, day = map(int, input('오늘 날짜를 입력해주세요:').split('.'))
today = date(year, month, day)

def count_days(day):
    y, m, d = map(int, day.split('.'))
    lifetime = date(y, m, d)
    return (today-lifetime).days

kill['일생'] = kill['생년월일'].map(count_days)
kill = kill.sort_values(by='평균 답장 시간(분)')  # 답장 시간 순으로 정렬
kill.reset_index(drop=True, inplace=True)  # 인덱스 초기화
young = []  # 촉법소년
cnt = 1
for row in kill['일생']:
    if row >= 3000:
        young.append(f'징역 {cnt}년형')
        cnt += 1
    else:
        young.append('촉법소년')
kill['형량'] = young
kill = kill.drop(['일생'], axis=1)
kill.to_excel('범죄자 명단.xlsx')


from turtle import Turtle
TEXT_ALIGNMENT='center'
FONT=('Arial', 18, 'normal')
class Score(Turtle):

    def __init__(self):
        super().__init__()
        self.score = 0
        self.penup()
        self.color("white")
        self.setpos(0, 270)
        self.hideturtle()
        self.printScore()
    def printScore(self):
        self.write(f"score: {self.score}", move=False, align=TEXT_ALIGNMENT, font=FONT)
    def updateScore(self):
        self.score +=1
        self.clear()
        self.printScore()

    def game_over(self):
        self.home()
        self.write(f"GAME OVER", move=False, align=TEXT_ALIGNMENT, font=FONT)


import pandas as pd
from math import *
from random import randint
from itertools import permutations
from pandas import *
from time import *
"""
Module à import : math et random
Le programme prend trois fonctions, une fonction angramme, une fonction maths, une fonction exe
La fonction anagramme prend en argument un chaine de caractère, et trouve le mot correct en y incluant une base de donnée.
"""
def verification(c):
    c=c.lower()
    listing=pd.read_csv("Lexique383.csv")
    searching=listing[(listing["1_ortho"] == c)]
    if len(searching)>0:
        return True
    return False

def verification_txt(c):
    c=c.lower()
    fichier=open("pli07.txt","r")
    l=[]
    for i in fichier:
        i=i.replace('\n',"")
        i=i.lower()
        l.append(i)
    if c in l:
        return True
    return False

def search_word():
    listing=pd.read_csv("Lexique383.csv")
    index=len(listing["1_ortho"])
    word_rand=randint(0,index+1)
    word=listing["1_ortho"][word_rand]
    return word

def search_word_txt():
    fichier=open("pli07.txt","r")
    l=[]
    for i in fichier:
        i=i.replace('\n',"")
        i=i.lower()
        l.append(i)
    word_rand=randint(0,len(l)+1)
    word=l[word_rand]
    if len(word)>10:
        search_word_txt()
    return word

def math():
    #lvl=int(input("Niveau de difficulté des calcul entre 1 et 10"))
    a=randint(0,10)
    b=randint(0,10)
    return a,b

def arrangement(c):
    """Prend en argument une chaine de caractère et retourne le nombre d'arangement possible de ce mot"""
    factorielle = lambda n: n * factorielle(n-1) if n != 0 else 1
    return factorielle(len(c))

#print(arrangement("bonjour"))

def anagramme(c):
    debut=time()
    """Prend en argument une chaine de caractère et retourne le mot existant dans le bon ordre."""
    c=c.lower()
    print(f"Le nombre de combinaison possible du mot est : {arrangement(c)}")
    print(f"Le mot à {len(c)} lettres")
    a=[''.join(p) for p in permutations(c)]
    ana_rand=randint(1,len(a))
    #print(f"ana_rang : {ana_rand}")
    anag=a[ana_rand-1]

    if verification_txt(c)==False:
        print("Le mot est absent de la base de donnée!")
        return None
    print("Le mot est présent dans la base de donnée !")

    i=0
    mem=[] #Memoire des lettres trouvés
    while i!=len(c):
        x,y=math()
        res=int(input(f"Veuillez rentrer de resultat de {x}x{y} :"))
        if res==x*y:
            mem.append(anag[i])
            print(f"Lettre trouvé : {anag[i]}")
            i+=1
        else:
            print(f"Perdu, le résultat était {x*y}")
            return None
    print("Bravo voici les lettres trouvées :",end=" ")
    for i in range(len(anag)):
        print(anag[i],end="")
    print("")
    mot=input("Quel est le mot mystere ? : ")

    if mot==c:
        print("Vous avez gagné ! Félicitation !")
        return None
    print(f"Dommage vous avez perdu, le mot était {c}")
    fin=time()
    print(f"Essai effectué en {floor(fin-debut)} secondes")

anagramme(search_word_txt())


import time
import DFL168A
SuccessFresh=False
def refresh():
    global SuccessFresh
    if not DFL168A.DigitalCommand('FEE8'):
        SuccessFresh=False
        return False
    Temp=DFL168A.HandleResponse(DFL168A.ReturnStr)
    DFL168A.ReturnStr=Temp
    SuccessFresh=True
    return True
def getAltitude():
    global SuccessFresh
    if not SuccessFresh:
        return False,0.0
    temp=DFL168A.ReturnStr[14:16]+DFL168A.ReturnStr[12:14]
    temp=int(temp,16)
    if temp>0xfaff:
        return False,0.0
    Altitude=temp*0.125-2500.0
    return True, Altitude
def getNavBasedSpeed():
    global SuccessFresh
    if not SuccessFresh:
        return False,0.0
    temp=DFL168A.ReturnStr[6:8]+DFL168A.ReturnStr[4:6]
    temp=int(temp,16)
    if temp>0xfaff:
        return False,0.0
    BasedSpeed=temp/256.0
    return True, BasedSpeed


import os
from pathlib import Path
from dotenv import dotenv_values

BASE_DIR = Path(__file__).resolve().parent.parent

ENV_PATH = BASE_DIR / ".env"
BOT_TOKEN = dotenv_values(ENV_PATH)['TOKEN_TG']
admins = [
    1260426275
]

ip = dotenv_values(ENV_PATH)["IP"]

aiogram_redis = {
    'host': '188.72.209.127',
}

redis = {
    'address': ('188.72.209.127', 6379),
    'encoding': 'utf8'
}


class Computer:#class name
    def __init__(self,cpu,ram):#CONSTRUCTOR
        self.cpu= cpu
        self.ram= ram
    def Specification(self,):
        print("The config cpu:{},and ram:{}".format(self.cpu,self.ram))
com1=Computer("i5",10)#OBJECT
com2= Computer("Mac",50)

com1.Specification()#CALLING METHODS FROM obJECT
com2.Specification()


# app.py
from fungsi import kuadrat, akar

test_data = []
with open("data.txt", "r") as file:
    test = file.readlines()
    for row in test:
        test_data.append(int(row))

if __name__ == "__main__":
    for bilangan in test_data :
        power = kuadrat(bilangan)
        root = akar(bilangan)
        print(f"Kuadrat dari {bilangan} adalah {power}, adapun akarnya adalah {root}.")


from typing import List
class MergeTwoSortedArray:
    def __init__(self,array1,array2) -> None:
        self.array1 = array1
        self.array2 = array2
        self.m=m
        self.n=n

    def merge(self):
        mergedArray = []
        if len(self.array1) == 0:
            return self.array2
        if len(self.array2) == 0:
            return self.array1
        i = 0
        j = 0
        while i < len(self.array1) and j< len(self.array2):
            if self.array1[i] <= self.array2[j]:
                mergedArray.append(self.array1[i])
                i+=1
            elif self.array2[j] <= self.array1[i]:
                mergedArray.append(self.array2[j])
                j+=1
        return mergedArray+self.array1[i:]+self.array2[j:]

def mergeinplace(nums1: List[int], m: int, nums2: List[int], n: int) -> None:
    """
    Do not return anything, modify nums1 in-place instead.
    """
        # Initialize nums1's index
    i = m - 1
    # Initialize nums2's index
    j = n - 1
    # Initialize a variable k to store the last index of the 1st array...
    k = m + n - 1
    while j >= 0:
        if i >= 0 and nums1[i] > nums2[j]:
            nums1[k] = nums1[i]
            k -= 1
            i -= 1
        else:
            nums1[k] = nums2[j]
            k -= 1
            j -= 1

if __name__=="__main__":
    array1 = [1,3,4,6,20]
    array2 = [2,3,4,5,6,9,11,76]
    mtsa = MergeTwoSortedArray(array1,array2)
    print(mtsa.merge())

    nums1 = [1,2,3,0,0,0]
    nums2 = [2,5,6]
    m = 3
    n = 3
    mergeinplace(nums1, m, nums2, n)
    nums1 = [1]
    m = 1
    nums2 = []
    n = 0
    mergeinplace(nums1, m, nums2, n)


class Solution:
    """
    @param n: An integer
    @return: the nth prime number as description.
    """
    def nthUglyNumber(self, n):
        # write your code here
        if n == 1:
            return 1

        import heapq
        heap = []
        heapq.heappush(heap,1)
        visited = set()
        visited.add(1)
        for i in range(n):
            val = heapq.heappop(heap)
            for multi in [2,3,5]:
                if val * multi not in visited:
                    visited.add(val*multi)
                    heapq.heappush(heap,val* multi)

        return val

lintcode algo ladder/4. Ugly Number II.py


import numpy as np

def Sekantenverfahren(f, a, b, delta, n):
    list = [a,b]
    #while n != 0 and delta <= abs((b-a)):
    while n-2:
        denominator = f(b) - f(a)
        if(denominator == 0):
            break
        m = b-(b-a)/denominator*f(b)
        a=b
        b=m
        list.append(m)
        n -= 1
    return list


# Django
from django.utils.html import format_html
from django.contrib import messages

# Models
from community.apps.posts.models.index import Post

# Bases
from community.bases.admin import Admin
from django.contrib import admin

@admin.register(Post)
class PostAdmin(Admin):
    list_display = ('thumbnail_media_tag', 'user', 'title', 'community',
                    'visit_count', 'comment_count', 'like_count',
                    'is_active', 'web_url')
    search_fields = ('user__username', 'title', 'community__title')
    list_filter = ('community',)

    fieldsets = (
        ("1. 정보", {"fields": ('community', 'board', 'title', 'content', 'web_url')}),
        ("2. 이미지", {"fields": ('thumbnail_media_tag', 'thumbnail_media_url')}),
        ("3. 유저", {"fields": ('user', 'profile')}),
        ("4. 통계", {"fields": ('point', 'like_count', 'dislike_count', 'comment_count', 'bookmark_count', 'visit_count',
                              'reported_count', 'share_count')}),
        ("5. 활성화 유무", {"fields": ('is_active',)}),
        ('6. 생성일', {'fields': ('created', 'achieved_20_points_at')}),
    )

    readonly_fields = ('achieved_20_points_at', 'thumbnail_media_tag', 'thumbnail_media_url',
                       'like_count', 'dislike_count', 'comment_count', 'bookmark_count', 'visit_count', 'reported_count',
                       'share_count', 'web_url')
    summernote_fields = ('content',)
    # inline_actions = ['create_post_like', 'create_post_dislike']

    def get_readonly_fields(self, request, obj=None):
        return self.readonly_fields

    def thumbnail_media_tag(self, obj):
        if obj.thumbnail_media_url:
            return format_html('<img src="{}" width="100px;"/>'.format(obj.thumbnail_media_url))

    thumbnail_media_tag.short_description = '썸네일'

    # 어드민 사이트에서 유저 필드 넣는 함수
    def save_model(self, request, obj, form, change):
        if not obj.user:
            obj.user = request.user
        super(PostAdmin, self).save_model(request, obj, form, change)

    # def create_post_like(self, request, obj, parent_obj=None):
    #     obj.create_post_like()
    #     messages.success(request, '포스트 좋아요가 생성됐습니다.')
    #
    # def create_post_dislike(self, request, obj, parent_obj=None):
    #     obj.create_post_dislike()
    #     messages.success(request, '포스트 싫어요가 생성됐습니다.')


import random

def adjetivo(nivel: int):
    if not isinstance(nivel, int):
        raise TypeError("nivel deve ser um inteiro")

    adjetivos = []
    if nivel == 1:
        adjetivos = ["tolo", "fracassado", "idiota", "imbecil", "pateta", "desajeitado", "ingênuo"]
    elif nivel == 2:
        adjetivos = ["medíocre aventureiro", "típico aventureiro", "aventureiro comum", "destemido", "corajoso"]
    elif nivel >= 3:
        adjetivos = ["incrível aventureiro", "herói", "excelente aventureiro", "grande aventureiro", "ousado",
                     "intrépido"]
    return random.choice(adjetivos)

def list_to_string(list: list):
    if len(list) <= 1:
        return ''.join(list)
    else:
        return ', '.join(list[:-1]) + ' e ' + list[-1]


#!/usr/bin/python
# -*- coding: UTF-8 -*-
'''
@author RenMeng
@version 1.0
@since 2021-08-31
'''
import random
class Solution:
    def singleNumber(self, nums) -> int:
        left = 0
        right = len(nums) - 1
        while left < right:
            k = random.randint(left, right)
            nums[right], nums[k] = nums[k], nums[right]
            low, high = left, right - 1
            while low <= high:
                while low < right and nums[low] <= nums[right]:
                    low += 1
                while high >= left and nums[high] > nums[right]:
                    high -= 1
                if low < high:
                    nums[low], nums[high] = nums[high], nums[low]
                    low += 1
                    high -= 1
            nums[right], nums[low] = nums[low], nums[right]
            pre_half = low - left + 1
            if pre_half % 3 == 1:
                right = low
            else:
                left = low + 1
        return nums[left]


import logging
import numpy as np
import os
import tensorflow as tf
from tensorflow.python.training.summary_io import SummaryWriterCache

class EnvRunner(object):
    def __init__(self, env=None,
                 test_env=None,
                 agent=None,
                 observation_adapter=None,
                 action_adapter=None,
                 epoch_n=None,
                 batch_n=None,
                 step_n=16,
                 test_after_epoch=True,
                 train=True,
                 restore=False,
                 logdir=None):
        self._env = env
        self._test_env = test_env
        self._agent = agent
        self._obs_adapter = observation_adapter
        self._act_adapter = action_adapter
        self._epoch_n = epoch_n
        self._batch_n = batch_n
        self._step_n = step_n
        self._test_after_epoch = test_after_epoch
        self._obs = None
        self._train = train
        self._summary_writer = None
        self._saver = tf.train.Saver()
        self._logdir = logdir
        if logdir:
            if not os.path.isdir(logdir):
                os.makedirs(logdir)
            self._summary_writer = SummaryWriterCache.get(logdir)
        if restore or not train:
            self._saver.restore(
                self._agent._sess, tf.train.latest_checkpoint(logdir))

    def run(self, *args, **kwargs):
        if self._train:
            self._obs = self._env.reset()
        for epoch in range(self._epoch_n):
            if self._train:
                for batch in range(self._batch_n):
                    logging.info("epoch:%d,batch:%d" % (epoch, batch))
                    self._batch()
                checkpoint = self._logdir + '/%d.ckpt' % epoch
                self._saver.save(self._agent._sess, checkpoint)
            if self._test_after_epoch:
                total_reward = self._test()
                logging.info("epoch:%d,reward:%d" % (epoch, total_reward))
                self._record(step=epoch, reward=total_reward)

    def _batch(self):
        # train batch
        ## todo refactor
        obs = []
        func_calls = []
        acts = None
        for _ in range(self._step_n):
            obs.append(self._obs)
            state = self._obs_adapter.transform(self._obs, state_only=True)
            funcs_or_acts = self._agent.step(state=state, obs=self._obs)
            if isinstance(funcs_or_acts[0], tuple):
                function_calls = funcs_or_acts
                func_calls.extend(function_calls)
            else:
                if not acts:
                    acts = [[] for _ in range(len(funcs_or_acts))]
                for c, e in zip(acts, funcs_or_acts):
                    c.append(e)
                function_calls = self._act_adapter.reverse(funcs_or_acts)
            self._obs = self._env.step([(f,) for f in function_calls])
        obs.append(self._obs)

        (states, next_states,
         rewards, dones, timestamps) = self._obs_adapter.transform(obs)

        if not acts:
            acts = self._act_adapter.transform(func_calls)
        else:
            acts = [np.concatenate(c, axis=0) for c in acts]
        batch = (states, acts,
                 next_states, rewards, dones, timestamps)
        summary, step = self._agent.update(*batch)
        self._record(summary=summary, step=step)

    def _test(self):
        obs = self._test_env.reset()
        total_reward = 0
        while not obs[0].last():
            state = self._obs_adapter.transform(obs, state_only=True)
            action = self._agent.step(state=state, evaluate=True)
            function_calls = self._act_adapter.reverse(action)
            obs = self._test_env.step([(f,) for f in function_calls])
            total_reward += obs[0].reward
        return total_reward

    def _record(self, step=None, summary=None, **kwargs):
        if not self._train or not self._summary_writer:
            return
        if summary:
            self._summary_writer.add_summary(summary, step)
        for tag, value in kwargs.items():
            summary = tf.Summary()
            summary.value.add(tag=tag, simple_value=np.mean(value))
            self._summary_writer.add_summary(summary, step)


#!/usr/bin/env python

import importlib
import os
import sys
import datetime

from lib.attachment_events_reader import AttachmentEventsReader
from lib.config import Config
from lib.imap import Mailbox
# from lib.processed import Processed
from lib.processed import Processed
from lib.receipts import receipts

# 0. error handling: add date+time to output
def exception_add_datetime(exctype, value, traceback):
    sys.stderr.write("[ERROR][" + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "] \n")
    sys.__excepthook__(exctype, value, traceback)
sys.excepthook = exception_add_datetime

app_path = os.path.dirname(os.path.realpath(__file__))

# 1. connect to mailbox
config = Config(app_path + '/.env')
mailbox = Mailbox(config)

# 2. fetch emails with a csv attachment
messages = mailbox.messages(attachment_suffix_filter='csv')
if messages is None:
    sys.exit(0)

# 3. turn attachments into timelines events
db_dir = app_path + '/storage/processed'
if config.get('timelines_events_duplicate_detection'):
    processed = Processed('timelines_events', db_dir)
    reader = AttachmentEventsReader(processed)
else:
    processed = None

# 4. process messages
backend_module = importlib.import_module(config.get('backend_module'))
backend_class = getattr(backend_module, config.get('backend_class'))
backend = backend_class()
for message in messages:
    # try:
    reader = AttachmentEventsReader()
    # read all relevant attachments
    for attachment in message['attachments']:
        reader.add(message, attachment_payload=attachment['payload'])
    # deliver events to backend
    delivery_status_lines_list = []
    for event in reader.events:
        project_id = event.project_id()
        if project_id is not None and project_id != '':
            event.delivery_status_lines = backend.deliver_timelines_event(event)
        if processed is not None:
            processed.now(event)
    # send configured receipts
    if config.get('receipt_to_sender') or config.get('receipt_copy_to_addresses') != '':
        receipts(config).send(message, reader.events)

# 5. move successfully processed emails to processed folder
if config.get('imap_move_processed_messages'):
    mailbox.move_to_processed_folder(messages)

# 6. disconnect from mailbox
mailbox.close()


import requests
import json
import streamlit as st

st.title(" ☕☕ List of coffees ☕☕ ")
type_of_coffee = st.selectbox("type of coffee?",["hot","iced"])
filtertitle = st.text_input("filter?")

if type_of_coffee:
    url = "https://api.sampleapis.com/coffee/" + type_of_coffee + "/?title_like=" + filtertitle
    st.text(f"Fetching: {url} ")
    response = requests.get(url)
    coffees =  json.loads(response.content)
    #st.table(coffees)
    for coffee in coffees:
        st.text(coffee["title"])
        st.image(coffee["image"])


# This program adds two number

num1 = 1.5
num2 = 6.3
# Add num1 and num2
#hello python

# Add two numbers
sum = num1 + num2

# Display the sum
print('The sum of {0} and {1} is {2}'.format(num1, num2, sum))


import os.path
import math
import json
from typing import List, Optional

# 3rd
import ROOT

# ours
import metaoptions
import validationcomparison
import validationpath
from validationfunctions import strip_ext, index_from_revision, get_style
import json_objects
from validationrootobject import RootObject

# todo: [Ref, low prio, medium work] Refactor into class with uniform interface
#   and subclasses implementing actual functionality for Plot/Tuple etc.
#   /klieret
class Plotuple:

    """!
    A Plotuple is either a Plot or an N-Tuple

    @var work_folder: the work folder containing the results and plots
    @var root_objects: A list of Root-objects which belong
        together (i.e. should be drawn into one histogram or one table)
    @var revisions: The list of revisions
    @var warnings: A list of warnings that occured while creating the
        plots/tables for this Plotuple object
    @var reference: The reference RootObject for this Plotuple
    @var elements: The elements (RootObject of different revisions) for this
        Plotuple
    @var newest: The newest element in elements
    @var key: The key of the object within the corresponding ROOT file
    @var type: The type of the elements (TH1, TH2, TNtuple)
    @var description: The description of this Plotuple object
    @var check: Hint how the Plotuple object should look like
    @var contact: The contact person for this Plotuple object
    @var package: The package to which this Plotuple object belongs to
    @var rootfile: The rootfile to which the Plotuple object belongs to
    @var chi2test_result: The result of the Chi^2-Test. By default, there is no
        such result. If the Chi^2-Test has been performed, this variable holds
        the information between which objects it has been performed.
    @var pvalue: The p-value that the Chi^2-Test returned
    @var file: The file, in which the histogram or the HMTL-table (for
        n-tuples) are stored (without the file extension!)
    """

    def __init__(
        self,
        root_objects: List[RootObject],
        revisions: List[str],
        work_folder: str,
    ):
        """!
        The default constructor for a Plotuple-object.
        @param root_objects: A list of Root-objects which belong
            together (i.e. should be drawn into one histogram or one table)
        @param revisions: The list of revisions (Duh!)
        """

        # the work folder containing the results and plots
        self._work_folder = work_folder

        # The list of Root objects in this Plotuple-object
        self._root_objects = root_objects

        # The list of revisions
        self._revisions = revisions

        # A list of all problems that occured with this Plotuple,
        # e.g. missing reference object, missing meta-information...
        self.warnings: List[str] = []

        # Find the reference element. If we can't find one, set it to 'None'
        # The reference-object for this Plotuple object
        self._reference: Optional[RootObject] = None
        for root_object in self._root_objects:
            if root_object.is_reference:
                self._reference = root_object
                break

        # If we couldn't find a reference element, add that to warnings
        if self._reference is None:
            self.warnings = ["No reference object"]

        # All elements of the Plotuple that are not the reference-object
        # Get the elements, i.e. all RootObjects except for the
        # reference object. May be either histograms or n-tuples.
        # Note that the reference doesn't have a date set (and if we only plot
        # the reference, then is_reference is probably not set), so we have
        # to be careful of how to sort
        self._elements = [ro for ro in root_objects if not ro.is_reference]
        self._elements.sort(
            key=lambda ro: ro.date if ro.date else 0, reverse=True
        )

        # The newest element, i.e. the element belonging the revision
        # whose data were created most recently.
        # Should always be self.element[0], except if there is only a
        # reference object
        if self._elements:
            self._newest = self._elements[0]
        else:
            self._newest = self._reference

        # All available meta-information about the plotuple object:

        # The key (more precisely: the name of the key) that all elements of
        # this Plotuple object share
        self.key = self._newest.key

        # The type of the elements in this Plotuple object
        self.type = self._newest.type

        if self.type == "TNamed":
            # Sometimes, we use TNamed to encode extra information about the
            # ROOT file. In order to avoid that this will be plotted, we
            # catch it here and assign it the type 'Meta'
            meta_fields = ["description"]
            if self._newest.object.GetName().lower().strip() in meta_fields:
                self.type = "meta"

        # The description of the histogram/n-tuple which this Plotuple object
        # will yield
        self._description = self._newest.description

        # The 'Check for ...'-guideline for the histogram/n-tuple which this
        # Plotuple object will yield
        self._check = self._newest.check

        # A contact person for the histogram/n-tuple which this Plotuple object
        # will yield
        self._contact = self._newest.contact

        # MetaOptionParser for the meta-options for this Plotuple object
        self._mop = metaoptions.MetaOptionParser(self._newest.metaoptions)

        # The package to which the elements in this Plotuple object belong
        self.package = self._newest.package

        # The root file to which the elements in this Plotuple object belong
        self.rootfile = self._newest.rootfile

        # The result of the Chi^2-Test. By default, there is no such result.
        # If the Chi^2-Test has been performed, this variable holds between
        # which objects it has been performed.
        self._comparison_result_long = "n/a"

        self.comparison_result = "not_compared"

        # The json file, in which the ntuple information is stored
        self._file: Optional[str] = None

        self._html_content: Optional[str] = None

        #: width of the plotted image in pixels, will be set by the draw
        #: function
        self._width: Optional[int] = None

        #: height of the plotted image in pixels, will be set by the draw
        #: function
        self._height: Optional[int] = None

        # Deal with incomplete information
        if self._description == "" or self._description is None:
            self._description = "n/a"
            self.warnings.append("No description")
        if self._check == "" or self._check is None:
            self._check = "n/a"
            self.warnings.append("No Check")
        if self._contact == "" or self._contact is None:
            self._contact = "n/a"
            self.warnings.append("No Contact Person")

        #: The folder in which the plots will be found. Note that this should
        #: be relative to the ``html`` directory, because this is the string
        #: that will be used for the JavaScript queries to get the files
        self._plot_folder = os.path.join(
            validationpath.get_html_plots_tag_comparison_folder(
                work_folder, tags=revisions
            ),
            self.package,
        )
        os.makedirs(self._plot_folder, exist_ok=True)

    def has_reference(self):
        """!
        @return True if a reference file is found for this plotuple
        """
        return self._reference is not None

    def create_plotuple(self):
        """!
        Creates the histogram/table/image that belongs to this Plotuble-object.
        """

        if self.type == "TH1" or self.type == "TEfficiency":
            self.create_histogram_plot("1D")
        elif self.type == "TGraph":
            self.create_graph_plot()
        elif self.type == "TH2":
            self.create_histogram_plot("2D")
        # used to store HTML user content
        elif self.type == "TNamed":
            self.create_html_content()
        elif self.type == "TASImage":
            self.create_image_plot()
        elif self.type == "TNtuple":
            self.create_ntuple_table_json()
        elif self.type == "meta":
            pass
        else:
            raise ValueError(
                "Tried to create histogram/n-tuple, but received" "invalid type"
            )

    def is_expert(self):
        """!
        @return Returns true if this plotuple has the expert option
        """
        return not self._mop.has_option("shifter")

    def perform_comparison(self):
        """!
        Takes the reference (self.reference.object) and the newest revision
        (self.newest.object) and a canvas. Performs a comparison of the
        two objects.
        @return: None
        """

        tester = validationcomparison.get_comparison(
            self._reference.object, self._newest.object, self._mop
        )

        self._comparison_result_long = tester.comparison_result_long.format(
            revision1=self._reference.revision, revision2=self._newest.revision
        )
        self.comparison_result = tester.comparison_result

    def _set_background(self, canvas):

        # kRed         #FF0000 Red
        # kRed - 9     #FF9999 Sweet pink

        # kOrange + 1  #FF9832 Sun
        # kOrange - 9  #FFCC9A Manhattan

        # kGreen - 3   #33CC33 Lime green
        # kGreen - 10  #CCFFCC Chinook

        # kAzure       #0032FE Medium blue
        # kAzure - 2   #3265FE Medium slate blue
        # kAzure - 9   #98CBFF Jordy blue

        colors = {
            "error": ROOT.kRed,
            "warning": ROOT.kOrange + 1,
            "equal": ROOT.kGreen - 3,
            "not_compared": ROOT.kAzure - 2,
        }
        colors_expert = {
            "error": ROOT.kRed - 9,
            "warning": ROOT.kOrange - 9,
            "equal": ROOT.kGreen - 10,
            "not_compared": ROOT.kAzure - 9,
        }

        if self.is_expert():
            color = colors_expert[self.comparison_result]
        else:
            color = colors[self.comparison_result]

        canvas.SetFillColor(color)
        canvas.GetFrame().SetFillColor(ROOT.kWhite)

    def _draw_ref(self, canvas):
        """!
        Takes the reference RootObject (self.reference.object)
        and a (sub)canvas and plots it with the correct line-style etc.
        @param canvas: Reference to the canvas on which we will draw the
            reference object.
        @return. None
        """
        self._remove_stats_tf1(self._reference.object)

        # Line is thick and black
        self._reference.object.SetLineColor(ROOT.kBlack)
        self._reference.object.SetLineWidth(2)
        self._reference.object.SetLineStyle(1)

        # Area under the curve is solid gray
        self._reference.object.SetFillColor(ROOT.kGray)
        self._reference.object.SetFillStyle(1001)

        # Draw the reference on the canvas
        self._draw_root_object(
            self.type,
            self._reference.object,
            self._reference.object.GetOption(),
        )
        canvas.Update()
        canvas.GetFrame().SetFillColor(ROOT.kWhite)

    @staticmethod
    def _remove_stats_tf1(obj):
        # removed TF1s which might have been added by validation scripts
        # in tracking/scripts/tracking/validation/plot.py:1597
        tf1 = obj.FindObject("FitAndStats")
        if tf1:
            function_list = obj.GetListOfFunctions()
            function_list.Remove(tf1)

    # TODO: is this actually used or can it be removed ?
    def create_image_plot(self):
        """!
        Creates image plot for TASImage-objects.
        @return: None
        """

        # Create a ROOT canvas on which we will draw our histograms
        self._width = 700
        if len(self._elements) > 4:
            canvas = ROOT.TCanvas("", "", 700, 1050)
            self._height = 1050
        else:
            canvas = ROOT.TCanvas("", "", 700, 525)
            self._height = 525

        # Split the canvas into enough parts to fit all image_objects
        # Find numbers x and y so that x*y = N (number of histograms to be
        # plotted), and x,y close to sqrt(N)

        if len(self._root_objects) == 1:
            x = y = 1
        elif len(self._root_objects) == 2:
            x = 2
            y = 1
        else:
            x = 2
            y = int(math.floor((len(self._root_objects) + 1) / 2))

        # Actually split the canvas and go to the first pad ('sub-canvas')
        canvas.Divide(x, y)
        pad = canvas.cd(1)
        pad.SetFillColor(ROOT.kWhite)

        # If there is a reference object, plot it first
        if self._reference is not None:
            self._draw_ref(pad)

        # Now draw the normal plots
        items_to_plot_count = len(self._elements)
        for plot in reversed(self._elements):

            # Get the index of the current plot
            index = index_from_revision(plot.revision, self._work_folder)
            style = get_style(index, items_to_plot_count)

            self._remove_stats_tf1(plot.object)

            # Set line properties accordingly
            plot.object.SetLineColor(style.GetLineColor())
            plot.object.SetLineWidth(style.GetLineWidth())
            plot.object.SetLineStyle(style.GetLineStyle())

            # Switch to the correct sub-panel of the canvas. If a ref-plot
            # exists, we have to go one panel further compared to the
            # no-ref-case
            if self._reference is not None:
                i = 2
            else:
                i = 1

            pad = canvas.cd(self._elements.index(plot) + i)
            pad.SetFillColor(ROOT.kWhite)

            # Draw the reference on the canvas
            self._draw_root_object(
                self.type, plot.object, plot.object.GetOption()
            )
            pad.Update()
            pad.GetFrame().SetFillColor(ROOT.kWhite)

            # Write the title in the correct color
            title = pad.GetListOfPrimitives().FindObject("title")
            if title:
                title.SetTextColor(style.GetLineColor())

        # Save the plot as PNG and PDF
        canvas.Print(os.path.join(self._plot_folder, self.get_png_filename()))
        canvas.Print(os.path.join(self._plot_folder, self.get_pdf_filename()))

        self._file = os.path.join(
            self._plot_folder,
            "{}_{}".format(strip_ext(self.rootfile), self.key),
        )

    def get_png_filename(self):
        return "{}_{}.png".format(strip_ext(self.rootfile), self.key)

    def get_pdf_filename(self):
        return "{}_{}.pdf".format(strip_ext(self.rootfile), self.key)

    @staticmethod
    def _draw_root_object(typ, obj, options):
        """
        Special handling of the ROOT Draw calls, as some
        ROOT objects have a slightly differen flavour.
        """

        if typ == "TEfficiency" or typ == "TGraph":
            # TEff does not provide DrawCopy
            obj.Draw(options)
        else:
            obj.DrawCopy(options)

    def create_histogram_plot(self, mode):
        """!
        Plots all histogram-objects in this Plotuple together in one histogram,
        which is then given the name of the key.
        @param mode: Determines whether it is a one- or
        two-dimensional histogram.
            Accepted values are '1D' and '2D'
        @return: None
        """

        # If we don't get a valid 'mode', we can stop right here
        if mode not in ["1D", "2D"]:
            return

        # Create a ROOT canvas on which we will draw our histograms
        self._width = 700
        if mode == "2D" and len(self._elements) > 4:
            self._height = 1050
        else:
            self._height = 525
        canvas = ROOT.TCanvas("", "", self._width, self._height)

        # Create a ROOT Legend
        legend = ROOT.TLegend(0.01, 0.01, 0.53, 0.06)
        legend.SetNColumns(3)
        legend.SetTextSize(0.02)

        # Allow possibility to turn off the stats box
        if self._mop.has_option("nostats"):
            ROOT.gStyle.SetOptStat("")
        else:
            ROOT.gStyle.SetOptStat("nemr")

        # If there is a reference object, and the list of plots is not empty,
        # perform a Chi^2-Test on the reference object and the first object in
        # the plot list:
        if (
            self._reference is not None
            and self._newest
            and not self._reference == self._newest
        ):
            self.perform_comparison()

        # A variable which holds whether we
        # have drawn on the canvas already or not
        # (only used for the 1D case)
        drawn = False

        # Now we distinguish between 1D and 2D histograms
        # If we have a 1D histogram
        if mode == "1D":

            if not self._mop.has_option("nogrid"):
                canvas.SetGrid()
            if self._mop.has_option("logx"):
                canvas.SetLogx()
            if self._mop.has_option("logy"):
                canvas.SetLogy()

            # If there is a reference object, plot it first
            if self._reference is not None:
                self._draw_ref(canvas)
                drawn = True

        # If we have a 2D histogram
        elif mode == "2D":

            # Split the canvas into enough parts to fit all histogram_objects
            # Find numbers x and y so that x*y = N (number of histograms to be
            # plotted), and x,y close to sqrt(N)

            if len(self._root_objects) == 1:
                x = y = 1
            elif len(self._root_objects) == 2:
                x = 2
                y = 1
            else:
                x = 2
                y = int(math.floor((len(self._root_objects) + 1) / 2))

            # Actually split the canvas and go to the first pad ('sub-canvas')
            canvas.Divide(x, y)
            pad = canvas.cd(1)
            pad.SetFillColor(ROOT.kWhite)

            # If there is a reference object, plot it first
            if self._reference is not None:
                self._draw_ref(pad)

        items_to_plot_count = len(self._elements)

        # Now draw the normal plots
        for plot in reversed(self._elements):

            # Get the index of the current plot
            index = index_from_revision(plot.revision, self._work_folder)
            style = get_style(index, items_to_plot_count)

            self._remove_stats_tf1(plot.object)

            # Set line properties accordingly
            plot.object.SetLineColor(style.GetLineColor())
            plot.object.SetLineWidth(style.GetLineWidth())
            plot.object.SetLineStyle(style.GetLineStyle())

            # If we have a one-dimensional histogram
            if mode == "1D":
                if not drawn:
                    # Get additional options for 1D histograms
                    # (Intersection with self.metaoptions)
                    additional_options = ["C"]
                    additional_options = [
                        option
                        for option in additional_options
                        if self._mop.has_option(option)
                    ]
                    options_str = plot.object.GetOption() + " ".join(
                        additional_options
                    )
                    drawn = True
                else:
                    options_str = "SAME"

                legend.AddEntry(plot.object, plot.revision)

                self._draw_root_object(self.type, plot.object, options_str)

                # redraw grid ontop of histogram, if selected
                if not self._mop.has_option("nogrid"):
                    canvas.RedrawAxis("g")

                canvas.Update()
                canvas.GetFrame().SetFillColor(ROOT.kWhite)

            # If we have a two-dimensional histogram
            elif mode == "2D":
                # Switch to the correct sub-panel of the canvas. If a ref-plot
                # exists, we have to go one panel further compared to the
                # no-ref-case
                if self._reference is not None:
                    i = 2
                else:
                    i = 1

                pad = canvas.cd(self._elements.index(plot) + i)
                pad.SetFillColor(ROOT.kWhite)

                # Get additional options for 2D histograms
                additional_options = ""
                for _ in ["col", "colz", "cont", "contz", "box"]:
                    if self._mop.has_option(_):
                        additional_options += " " + _

                # Draw the reference on the canvas
                self._draw_root_object(
                    self.type,
                    plot.object,
                    plot.object.GetOption() + additional_options,
                )
                pad.Update()
                pad.GetFrame().SetFillColor(ROOT.kWhite)

                # Write the title in the correct color
                title = pad.GetListOfPrimitives().FindObject("title")
                if title:
                    title.SetTextColor(style.GetLineColor())

        if self._newest:
            # if there is at least one revision
            self._set_background(canvas)

        canvas.GetFrame().SetFillColor(ROOT.kWhite)

        # Add reference legend entry last for neatness
        if self._reference is not None:
            legend.AddEntry(self._reference.object, 'reference')

        legend.Draw()

        # Save the plot as PNG and PDF
        canvas.Print(os.path.join(self._plot_folder, self.get_png_filename()))
        canvas.Print(os.path.join(self._plot_folder, self.get_pdf_filename()))

        self._file = os.path.join(
            self._plot_folder,
            "{}_{}".format(strip_ext(self.rootfile), self.key),
        )

    def create_graph_plot(self):
        """!
        Plots as TGraph/TGraphErrors
        @return: None
        """

        # Create a ROOT canvas on which we will draw our plots
        self._width = 700
        self._height = 525
        canvas = ROOT.TCanvas("", "", self._width, self._height)

        # Allow possibility to turn off the stats box
        if self._mop.has_option("nostats"):
            ROOT.gStyle.SetOptStat("")
        else:
            ROOT.gStyle.SetOptStat("nemr")

        # If there is a reference object, and the list of plots is not empty,
        # perform a Chi^2-Test on the reference object and the first object in
        # the plot list:
        if (
            self._reference is not None
            and self._newest
            and not self._reference == self._newest
        ):
            self.perform_comparison()

        if not self._mop.has_option("nogrid"):
            canvas.SetGrid()
        if self._mop.has_option("logx"):
            canvas.SetLogx()
        if self._mop.has_option("logy"):
            canvas.SetLogy()

        # A variable which holds whether we
        # have drawn on the canvas already or not
        drawn = False

        # If there is a reference object, plot it first
        if self._reference is not None:
            self._draw_ref(canvas)
            drawn = True

        items_to_plot_count = len(self._elements)
        # Now draw the normal plots
        for plot in reversed(self._elements):

            # Get the index of the current plot
            index = index_from_revision(plot.revision, self._work_folder)
            style = get_style(index, items_to_plot_count)

            # self.remove_stats_tf1(plot.object)

            # Set line properties accordingly
            plot.object.SetLineColor(style.GetLineColor())
            plot.object.SetLineWidth(style.GetLineWidth())
            plot.object.SetLineStyle(style.GetLineStyle())

            # If we have a one-dimensional histogram
            if not drawn:

                # todo: refactor like in plot hist
                # Get additional options for 1D histograms
                additional_options = ""
                for _ in ["C"]:
                    if self._mop.has_option(_):
                        additional_options += " " + _

                # Draw the reference on the canvas
                self._draw_root_object(
                    self.type,
                    plot.object,
                    plot.object.GetOption() + additional_options,
                )
                drawn = True
            else:
                self._draw_root_object(self.type, plot.object, "SAME")

            # redraw grid ontop of histogram, if selected
            if not self._mop.has_option("nogrid"):
                canvas.RedrawAxis("g")

            canvas.Update()
            canvas.GetFrame().SetFillColor(ROOT.kWhite)

        if self._newest:
            # if there is at least one revision
            self._set_background(canvas)

        # Save the plot as PNG and PDF
        canvas.Print(os.path.join(self._plot_folder, self.get_png_filename()))
        canvas.Print(os.path.join(self._plot_folder, self.get_pdf_filename()))

        self._file = os.path.join(
            self._plot_folder,
            "{}_{}".format(strip_ext(self.rootfile), self.key),
        )

    def create_html_content(self):

        # self.elements
        self._html_content = ""

        for elem in self._elements:
            self._html_content += (
                "<p>" + elem.revision + "</p>" + elem.object.GetTitle()
            )

        # there is no file storing this, because it is directly in the json
        # file
        self._file = None

    def get_meta_information(self):
        assert self.type == "meta"
        key = self._newest.object.GetName().strip().lower()
        value = self._newest.object.GetTitle()
        return key, value

    def create_ntuple_table_json(self):
        """!
        If the Plotuple-object contains n-tuples, this will create the
        a JSON file, which is later converted to HTML by the javascript
        function fillNtupleTable.
        """

        json_nutple = {}

        # The dictionary will have the following form
        # {
        #     "reference (if exist)": [
        #         ('variable 1', 'reference value for variable 1'),
        #         ('variable 2', 'reference value for variable 2'),
        #         ...
        #     ],
        #     "revision": [
        #         ...
        #     ]
        # }

        precision = self._mop.int_value("float-precision", default=4)
        format_str = f"{{0:.{precision}f}}"

        def value2str(obj):
            # assuming that I have a float
            return format_str.format(obj)

        colum_names = []
        for key in list(self._newest.object.keys()):
            colum_names.append(key)

        # If there is a reference object, print the reference values as the
        # first row of the table
        if self._reference and "reference" in self._revisions:
            json_nutple["reference"] = []

            key_list = list(self._reference.object.keys())
            for column in colum_names:
                if column in key_list:
                    value_str = value2str(self._reference.object[column])
                    json_nutple["reference"].append((column, value_str))
                else:
                    json_nutple["reference"].append((column, None))

        # Now print the values for all other revisions
        for ntuple in self._elements:
            if ntuple.revision not in json_nutple:
                json_nutple[ntuple.revision] = []

            for column in colum_names:
                if column in ntuple.object:
                    value_str = value2str(ntuple.object[column])
                    json_nutple[ntuple.revision].append((column, value_str))
                else:
                    json_nutple[ntuple.revision].append((column, None))

        json_ntuple_file = os.path.join(
            self._plot_folder,
            "{}_{}.json".format(strip_ext(self.rootfile), self.key),
        )

        with open(json_ntuple_file, "w+") as json_file:
            json.dump(json_nutple, json_file)

        self._file = json_ntuple_file

    def get_plot_title(self):
        if self._file:
            return os.path.basename(self._file).replace(".", "_").strip()
        else:
            # this is for html content which is not stored in any file
            return self.key

    def create_json_object(self):
        if self.type == "TNtuple":
            return json_objects.ComparisonNTuple(
                title=self.get_plot_title(),
                description=self._description,
                contact=self._contact,
                check=self._check,
                is_expert=self.is_expert(),
                json_file_path=os.path.relpath(
                    self._file,
                    validationpath.get_html_folder(self._work_folder),
                ),
            )
        elif self.type == "TNamed":
            return json_objects.ComparisonHtmlContent(
                title=self.get_plot_title(),
                description=self._description,
                contact=self._contact,
                check=self._check,
                is_expert=self.is_expert(),
                html_content=self._html_content,
            )
        elif self.type == "meta":
            return None
        else:
            return json_objects.ComparisonPlot(
                title=self.get_plot_title(),
                comparison_result=self.comparison_result,
                comparison_text=self._comparison_result_long,
                description=self._description,
                contact=self._contact,
                check=self._check,
                height=self._height,
                width=self._width,
                is_expert=self.is_expert(),
                plot_path=os.path.relpath(
                    self._plot_folder,
                    validationpath.get_html_folder(self._work_folder),
                )
                + "/",
                png_filename=self.get_png_filename(),
                pdf_filename=self.get_pdf_filename(),
                warnings=self.warnings,
            )


'''
References:
    https://www.ritchieng.com/machine-learning-evaluate-classification-model/
    https://datatofish.com/logistic-regression-python/
    https://stackabuse.com/gradient-descent-in-python-implementation-and-theory/
'''

from sklearn.linear_model import LogisticRegression
import pandas as pd

#import data
x_train = pd.read_csv(r'C:/Users/Berto/data for homework 3/Problem 6_data_trainx.csv')
y_train = pd.read_csv(r'C:/Users/Berto/data for homework 3/Problem 6_data_trainy.csv')

x_test = pd.read_csv(r'C:/Users/Berto/data for homework 3/Problem 6_data_testx.csv')
y_test = pd.read_csv(r'C:/Users/Berto/data for homework 3/Problem 6_data_testy.csv')

#combine data
frames_train = [x_train, y_train]
df_train = pd.concat(frames_train, axis=1, join='inner')

frames_test = [x_test, y_test]
df_test = pd.concat(frames_test, axis=1, join='inner')

#separate data
X_train = df_train[['x1', 'x2']]
y_train = df_train['y1']

X_test = df_test[['x1', 'x2']]
y_test = df_test['y1']

#convert dataframe to array
X_train, y_train = X_train.to_numpy(), y_train.to_numpy()
X_test, y_test = X_test.to_numpy(), y_test.to_numpy()

'''
#visualize decision boundary
fig, axes = plt.subplots(1, 2, figsize=(10, 3))

for model, ax in zip([LinearSVC(), LogisticRegression()], axes):
    clf = model.fit(X_train, y_train)
    mglearn.plots.plot_2d_separator(clf, X_train, fill=False, eps=0.5, ax=ax, alpha=.7)
    mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train, ax=ax)
    ax.set_title("{}".format(clf.__class__.__name__))
    ax.set_xlabel("Feature 0")
    ax.set_ylabel("Feature 1")
axes[0].legend()

#determining strength of the regularization called C --> a higher values of c corresponds to
#less regularization. in other words using a high value for parameter C, the functions try to
#fit the training set as best as possible, while with low values of parameter C, the model puts
#more emphasis on finding a coefficient vector (w) that is close to zero
mglearn.plots.plot_linear_svc_regularization()
'''

#accuracy = opposite of error --> 1 - accuracy = error
#here C=1 is default --> C=100 equals higher accuracy while C=0.01 equals lower accuracy
logreg = LogisticRegression(C=1).fit(X_train, y_train)
print("Training set error rate: {:.3f}".format(1 - logreg.score(X_train, y_train)))
print("Test set error rate    : {:.3f}".format(1 - logreg.score(X_test, y_test)))

'''
logreg100 = LogisticRegression(C=100).fit(X_train, y_train)
print("Training set score, C=100 : {:.3f}".format(logreg100.score(X_train, y_train)))
print("Test set score, C=100     : {:.3f}".format(logreg100.score(X_test, y_test)))

logreg001 = LogisticRegression(C=0.01).fit(X_train, y_train)
print("Training set score, C=0.01 : {:.3f}".format(logreg001.score(X_train, y_train)))
print("Test set score, C=0.01     : {:.3f}".format(logreg001.score(X_test, y_test)))
'''

print("weights      : {}".format(logreg.coef_))
print("intercept (b): {}".format(logreg.intercept_))


from nose.plugins.attrib import attr
from w3af.plugins.tests.helper import PluginTest, PluginConfig

class TestFingerGoogle(PluginTest):

    base_url = 'http://www.w3af.org/'

    _run_configs = {
        'cfg': {
            'target': base_url,
            'plugins': {'infrastructure': (PluginConfig('finger_google'),)}
        }
    }

    @attr('ci_fails')
    def test_fuzzer_user(self):
        cfg = self._run_configs['cfg']
        self._scan(cfg['target'], cfg['plugins'])

        emails = self.kb.get('emails', 'emails')

        self.assertEqual(len(emails), 3, emails)

        users = [em['user'] for em in emails]
        self.assertNotIn('x3d', users)


import numpy as np
import cvxpy as cvx
import sklearn as sk
from phi import phi
from powerset import powerset

class DWGCS:

    def DWKMM(Mdl,xtr,xte):

        n = xtr.shape[0]
        t = xte.shape[0]
        x = np.concatenate((xtr,xte), axis=0)
        epsilon_ = 1-1/(np.sqrt(n))
        B = 1000

        # K=np.zeros((n+t,n+t))
        # for i in range(n+t):
        #    K[i,i] = 0.5
        #    for j in range(i+1, n+t):
        #        K[i,j] = np.exp(-np.linalg.norm(x[i,:]-x[j,:])**2/(2*Mdl.sigma_**2))
        # K = K+K.T

        K = sk.metrics.pairwise.rbf_kernel(x,x,1/(2*Mdl.sigma_**2))

        # Define the variables of the opt. problem
        beta_ = cvx.Variable((n,1))
        alpha_ = cvx.Variable((t,1))
        # Define the objetive function
        objective = cvx.Minimize(cvx.quad_form(cvx.vstack([beta_/n, -alpha_/t]), cvx.psd_wrap(K)))
        # Define the constraints
        constraints = [
            beta_ >= np.zeros((n,1)),
            beta_ <= (B/np.sqrt(Mdl.D)) * np.ones((n,1)),
            alpha_ >= np.zeros((t,1)),
            alpha_ <= np.ones((t,1)),
            cvx.abs(cvx.sum(beta_)/n - cvx.sum(alpha_)/t) <= epsilon_,
            # cvx.sum(beta_)/n - cvx.sum(alpha_)/t <= epsilon_,
            # cvx.sum(beta_)/n - cvx.sum(alpha_)/t >= -epsilon_,
            cvx.norm(alpha_ - np.ones((t,1))) <= (1-1/np.sqrt(Mdl.D)) * np.sqrt(t)
        ]
        problem = cvx.Problem(objective,constraints)
        problem.solve(solver='MOSEK')
                      #,verbose=True)

        Mdl.beta_ = beta_.value
        Mdl.alpha_ = alpha_.value
        Mdl.min_DWKMM = problem.value

        return Mdl

    def parameters(Mdl,xtr,ytr,xte):

        auxtau = []
        n = xtr.shape[0]
        t = xte.shape[0]

        for i in range(n):
            auxtau.append(Mdl.beta_[i] @ phi(Mdl,xtr[i, :],ytr[i]))
        Mdl.tau_ = np.ravel(np.mean(np.array(auxtau), axis=0))

        d = len(Mdl.tau_)
        delta = 1e-6*np.ones(d)

        # Define the variables of the opt. problem
        lambda_ = cvx.Variable(d)
        p = cvx.Variable((t,Mdl.labels))
        # Define the objetive function
        objective = cvx.Minimize(cvx.sum(lambda_))
        # Define the constraints
        # Construct constraints
        aux = np.zeros(d)
        for i in range(t):
            for j in range(Mdl.labels):
                aux = aux+p[i,j] * Mdl.alpha_[i] @ phi(Mdl,xte[i,:],np.array([j+1]))
        constraints = [
            Mdl.tau_ - lambda_ + delta <= aux,
            aux <= Mdl.tau_ + lambda_ - delta,
            lambda_ >= Mdl.lambda0*np.zeros(d),
            cvx.sum(p,axis=1) == np.ones(t)/t,
            p >= np.zeros((t,Mdl.labels))
        ]

        problem = cvx.Problem(objective, constraints)
        problem.solve()

        Mdl.lambda_ = np.maximum(lambda_.value,0)

        return Mdl

    def learning(Mdl,xte):
        t = xte.shape[0]
        d = len(Mdl.tau_)

        if Mdl.loss == '0-1':

            v = np.zeros((2**Mdl.labels-1,1))

            set = powerset(Mdl.labels)
            # M = []
            M = np.empty((0,d))
            for i in range(t):
                for j in range(2**Mdl.labels-1):
                    # M.append(np.sum(Mdl.alpha_[i]*phi(Mdl,xte[i,:],set[j]),axis=0)/set[j].shape[0])
                    M = np.vstack((M,np.sum(Mdl.alpha_[i]*phi(Mdl,xte[i,:],set[j]),axis=0)/set[j].shape[0]))
            # M = np.array(M)
            for j in range(2**Mdl.labels-1):
                v[j,0]=1/set[j].shape[0]
            v = np.tile(v,(1,t))
            # Define the variables of the opt. problem
            mu_ = cvx.Variable((d,1))
            # Define the objetive function
            objective = cvx.Minimize( -Mdl.tau_ @ mu_ \
                                    + cvx.sum(np.ones(t)+cvx.max(cvx.reshape(M @ mu_, (2**Mdl.labels-1, t)) - v, axis=0))/t \
                                    + Mdl.lambda_ @ cvx.abs(mu_))
            problem = cvx.Problem(objective)
            problem.solve(solver='MOSEK', verbose=True, mosek_params={'MSK_DPAR_OPTIMIZER_MAX_TIME': 60})

        if Mdl.loss =='log':

            M = np.empty((0,d))
            for i in range(t):
                M = np.vstack( ( M,Mdl.alpha_[i]*phi( Mdl,xte[i,:],np.arange(1,Mdl.labels+1) ) ) )
            # Define the variables of the opt. problem
            mu_ = cvx.Variable((d,1))
            # Define the objetive function
            objective = cvx.Minimize( -Mdl.tau_ @ mu_ \
                                    + sum([cvx.log_sum_exp(M[2*k:2*k+2,:] @ mu_) for k in range(t)]) / t \
                                    + Mdl.lambda_ @ cvx.abs(mu_) )
            problem = cvx.Problem(objective)
            problem.solve(solver='MOSEK', verbose=True, mosek_params={'MSK_DPAR_OPTIMIZER_MAX_TIME': 60})

        Mdl.mu_ = mu_.value
        Mdl.RU = problem.value
        return Mdl

    def prediction(Mdl,xte,yte):
        t = xte.shape[0]
        ye = np.zeros((t,1))

        if Mdl.deterministic == True:

            for i in range(t):
                ye[i] = np.argmax(phi(Mdl,xte[i,:],np.arange(1,Mdl.labels+1))@Mdl.mu_)+1
            Mdl.error = np.count_nonzero(yte != ye)/t

        if Mdl.deterministic == False:

            Mdl.h = np.zeros((Mdl.labels,t))

            if Mdl.loss == '0-1':
                set = powerset(Mdl.labels)
                varphi_mux = np.zeros(t)
                for i in range(t):
                    varphi_aux = np.zeros(2**Mdl.labels-1)
                    for j in range(2**Mdl.labels-1):
                        varphi_aux[j] = (np.sum(Mdl.alpha_[i] * phi(Mdl,xte[i,:],set[j])@Mdl.mu_)-1)/set[j].shape[0]
                    varphi_mux[i]= max(varphi_aux)
                    c = np.sum(np.maximum(Mdl.alpha_[i] * phi(Mdl,xte[i,:],np.arange(1,Mdl.labels+1)) @ Mdl.mu_-varphi_mux[i]*np.ones((Mdl.labels,1)),0))
                    if c == 0:
                        Mdl.h[:,i] = (1/Mdl.labels)*np.ones(Mdl.labels)
                    else:
                        Mdl.h[:,i] = np.squeeze(np.maximum( Mdl.alpha_[i] * phi(Mdl,xte[i,:],np.arange(1,Mdl.labels+1)) @ Mdl.mu_-varphi_mux[i]*np.ones((Mdl.labels,1)),0)/c)
                    ye[i] = np.random.choice(np.arange(1,Mdl.labels+1), p=Mdl.h[:,i])
                Mdl.error = np.count_nonzero(yte != ye)/t

            if Mdl.loss == 'log':
                for i in range(t):
                    for j in range(Mdl.labels):
                        Mdl.h[j,i] = 1/sum(np.exp(Mdl.alpha_[i] * phi(Mdl,xte[i,:],np.arange(1,Mdl.labels+1)) @ Mdl.mu_\
                                    -np.ones((Mdl.labels,1))* Mdl.alpha_[i] * phi(Mdl,xte[i,:],np.array([j+1])) @ Mdl.mu_))
                    ye[i] = np.random.choice(np.arange(1,Mdl.labels+1), p=Mdl.h[:,i])
                Mdl.error = np.count_nonzero(yte != ye)/t
        return Mdl


import hashlib
import time

i = 1
j = 0

testlen = 10
while(1):
    starttime = time.time()
    while(1):
        code = hashlib.sha256(str(i).encode()).hexdigest()
        flag = 0
        for j in range(0, testlen):
            print(code)
            right = 2*j + 2;
            left = 2*j + 1;
            if (left >= testlen or right >= testlen):
                break
            if(ord(code[left]) > ord(code[j]) or ord(code[right]) < ord(code[j])):
                flag = 1
                break
        if(flag == 0):
            print(code)
            break
        i += 1
    finishtime = time.time()
    print(finishtime - starttime)
    break


# -*- coding: utf-8 -*-
"""
Created on Sun May  2 21:10:35 2021

@author: Andres and Juankas
"""
class Nodo:
    def __init__(self,data):
        self.data = data
        self.izquierda = None
        self.derecha = None

class Arbol_binario:
    def __init__(self):
        self.raiz = None

    def insertar(self, data):
        if self.raiz is None:
            self.raiz = Nodo(data)
        else:
            self.insertar_aux(data, self.raiz)

    def insertar_aux(self, data, actual):
        if data < actual.data:
            if actual.izquierda == None:
                actual.izquierda = Nodo(data)
            else:
                self.insertar_aux(data,actual.izquierda)

        else:
            if actual.derecha == None:
                actual.derecha = Nodo(data)
            else:
                self.insertar_aux(data,actual.derecha)

    def Pos_orden(self,lista):
        for i in lista:
            self.insertar(i)

        self.print_nums(self.raiz)

    def print_nums(self,raiz):

        if raiz != None:
            self.print_nums(raiz.izquierda)
            self.print_nums(raiz.derecha)
            print(raiz.data)

ArbolB = Arbol_binario()
input_data = [50,30,24,5,28,45,98,52,60]
ArbolB.Pos_orden(input_data)


import getpass
import re
from address_change import change_address
from money_deposit import deposit_money
from money_withdrawal import withdraw_money
from print_statement import print_statement
from account_closure import close_account
from money_transfer import transfer_money
from open_account import open_account
from loan_account import take_loan
from tkinter import *
from tkinter import messagebox
from main import *
def moneydeposit():
    money = Tk()

    money.title("Deposit Money")
    money.geometry("600x400")
    label = Label(money,text= "Enter Account Number")
    label.place(x=40,y=40)
    T = Entry(money,width=20)
    T.place(x=200,y=40)
    label1 = Label(money,text= "amount to be deposited")
    label1.place(x=40,y=70)
    T1 = Entry(money,width=20)
    T1.place(x=200,y=70)
    submit = Button(money,text="submit",command = lambda : yes(money)).place(x=120,y=150)
    money.mainloop()

def accountclose():
    money = Tk()
    money.title("Close Account")
    money.geometry("600x400")
    label = Label(money,text= "Enter Account Number")
    label.place(x=40,y=40)
    T = Entry(money,width=20)
    T.place(x=200,y=40)
    submit = Button(money,text="submit",command = lambda : yes(money)).place(x=120,y=150)
    money.mainloop()

def avail():
    money = Tk()

    money.title("Loan")
    money.geometry("600x400")
    label = Label(money,text= "Enter Amount")
    label.place(x=40,y=40)
    T = Entry(money,width=20)
    T.place(x=200,y=40)
    label1 = Label(money,text= "Term")
    label1.place(x=40,y=70)
    T1 = Entry(money,width=20)
    T1.place(x=200,y=70)
    submit = Button(money,text="submit",command = lambda : yes(money)).place(x=120,y=150)
    money.mainloop()

def transfer():
    money = Tk()
    money.title("Tranfer Money")
    money.geometry("600x400")
    label = Label(money,text= "From (Account Number)")
    label.place(x=40,y=40)
    T = Entry(money,width=20)
    T.place(x=200,y=40)
    label1 = Label(money,text= "TO (Account Number)")
    label1.place(x=40,y=70)

    T1 = Entry(money,width=20)
    T1.place(x=200,y=70)
    label2 = Label(money,text= "Amount to be transferred")
    label2.place(x=40,y=100)

    T2 = Entry(money,width=20)
    T2.place(x=200,y=100)
    submit = Button(money,text="submit",command = lambda : yes(money)).place(x=120,y=150)
    money.mainloop()

def yes(s):
    messagebox.showinfo("Success","Operation done Successfully")
    s.destroy()

def withdraw():
    withd = Toplevel()

    withd.title("WithDraw Money")
    withd.geometry("600x400")
    label = Label(withd,text= "Enter Account Number")
    label.place(x=40,y=40)
    T = Entry(withd,width=20)
    T.place(x=200,y=40)
    label1 = Label(withd,text= "amount to be withdrawn")
    label1.place(x=40,y=70)
    T1 = Entry(withd,width=20)
    T1.place(x=200,y=70)
    submit = Button(withd,text="submit",command = lambda : yes(withd)).place(x=120,y=150)
    withd.mainloop()
    #withd.destroy()

def printstatement():
    ps = Toplevel()

    ps.title("Print Statement")
    ps.geometry("600x600")
    label1 = Label(ps,text= "Enter Account Number")
    label1.place(x=40,y=40)
    label = Label(ps,text= " Enter the date(yyyy-mm-dd) from which transaction is to be printed :")
    label.place(x=40,y=70)
    T = Entry(ps,width=20)
    T.place(x=450,y=70)
    label1 = Label(ps,text= " Enter the date(yyyy-mm-dd) to which transaction is to be printed :")
    label1.place(x=40,y=100)
    T1 = Entry(ps,width=20)
    T1.place(x=450,y=100)
    submit = Button(ps,text="submit",command = lambda : stmt(ps)).place(x=120,y=150)
    ps.mainloop()
    #ps.destroy()

def stmt(ps):
    statement = "+---------------+------------+----------------------------+---------+--------+\n| AccountNumber | CustomerId | Date                       | Details | Amount |\n+---------------+------------+----------------------------+---------+--------+\n|         25893 |      64540 | 2018-11-28 09:15:29.765956 | Credit  |   2000 |\n|         25893 |      64540 | 2018-11-28 09:15:59.972600 | Debit   |   3000 |\n|         25893 |      64540 | 2018-11-28 09:24:26.403083 | Debit   |   2000 |\n+---------------+------------+----------------------------+---------+--------+"
    messagebox.showinfo("Statement for Account Number : 25893",statement)
    ps.destroy()
def signin(db,cursor):
    flag = True
    login = Tk()
    login.title("Login")
    login.geometry("600x600")
    label = Label(text="Customer Id")
    label.place(x=80,y=50)
    T = Entry(login, width=20)
    T.place(x=190,y=50)
    label1 = Label(text="Password")
    label1.place(x=80,y=80)
    T1 = Entry(login, width=20,show="*")
    T1.place(x=190,y=80)
    submit = Button(login,text="Login" , command = lambda: loginauth(cursor,login,flag,T.get(),T1.get()))
    submit.place(x=190,y=210)

def loginauth(cursor,login,flag,uname,password):
    cursor.execute("Select CustomerId,Password from Customer where CustomerId = '"+str(uname)+"' and Password = '"+password+"'")
    if(not(cursor.fetchone())):
        messagebox.showinfo("Invalid"," Invalid customer id or password ")

    else:
        messagebox.showinfo("Successful"," Login successful")
        login.destroy()
        customermenu(cursor,uname)

def customermenu(cursor,uname):
    customer = Tk()
    customer.title("Welcome Customer %s"%uname)
    customer.geometry("600x600")
    openacc = Button(customer,text ="Address Change",command =  lambda : change_address(cursor,uname)).place(x=100,y=50)
    openacc1 = Button(customer,text ="Open New Account",command =  lambda : open_account(cursor,uname)).place(x=100,y=80)
    openacc2 = Button(customer,text ="Money Deposit",command = lambda : moneydeposit()).place(x=100,y=110)
    openacc3 = Button(customer,text ="Money Withdraw",command = lambda : withdraw()).place(x=100,y=140)
    openacc4 = Button(customer,text ="Print Statement",command = lambda : printstatement()).place(x=100,y=170)
    openacc5 = Button(customer,text ="Transfer Money",command =  lambda : transfer()).place(x=100,y=200)
    openacc6 = Button(customer,text ="Account Closure",command = lambda : accountclose()).place(x=100,y=230)
    openacc7= Button(customer,text ="Avail loan",command = lambda : avail()).place(x=100,y=270)
    openacc8 = Button(customer,text ="Logout").place(x=100,y=300)
    customer.mainloop()


from entities.entities import Device, User
from helper.device_helper import DeviceHelper
from my_stats_messages.my_stats_messages import *
import logging

class UserHelper():
    def __init__(self):
        logging.info("constructor calling.")

    def link_device(self, user, device):
        user.devices.append(device)
        user.put()
        return self.get_user_by_fb_id(user.fb_id)

    def create_user(self, fb_id, name, email):
        users = self.get_user_by_fb_id(fb_id)
        if len(users) > 0:
            pass
        else:
            user = User(fb_id=fb_id, name=name, email=email)
            user.put()

        return self.get_user_by_fb_id(fb_id)

    def get_user_by_fb_id(self, fb_id):
        query = User.query(User.fb_id == fb_id)
        return query.fetch()

    def create_user_resp(self, fb_id):
        users = self.get_user_by_fb_id(fb_id)
        device_helper = DeviceHelper()
        if len(users) > 0:
            user = users[0]
            user_resp = UserMessage(fb_id=user.fb_id, name=user.name, email=user.email)
            if len(user.devices) > 0:
                for device in user.devices:
                    user_resp.devices.append(device_helper.create_device_resp(device))
        return user_resp

    def is_device_already_registered(self, device, device_list):
        is_registered = False
        logging.info("****Before loop*****")
        logging.info(device)
        logging.info(device.device_id)
        for d in device_list:
            logging.info(sorted(device.device_id.split()))
            logging.info(sorted(d.device_id.split()))

            if sorted(device.device_id.split()) == sorted(d.device_id.split()):
                logging.info("is_registered=True")
                is_registered = True
        return is_registered


import time
import random

print("¡Vamos a adivinar un numero!")

time.sleep(1)

number_to_guess = random.randint(1, 10)
user_number = int(input("Dime un numero: "))

print("Comprobando si adivinaste...")

if user_number == number_to_guess:
    time.sleep(3)
    print("Has adivinado el numero")
else:
    time.sleep(3)
    print("No has adivinado el numero, el numero era {}".format(number_to_guess))


import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error
from mylinearregression import MyLinearRegression as MyLR
import matplotlib.pyplot as plt

path = "ressources/day01/resources/"
data = pd.read_csv(path + "are_blue_pills_magics.csv")
Xpill = np.array(data["Micrograms"]).reshape(-1,1)
Yscore = np.array(data["Score"]).reshape(-1,1)

linear_model1 = MyLR(np.array([[89.0], [-8]]))
linear_model2 = MyLR(np.array([[89.0], [-6]]))
Y_model1 = linear_model1.predict_(Xpill)
Y_model2 = linear_model2.predict_(Xpill)

# print("NB1", linear_model1.mse_(Y_model1, Yscore))
print("NB1", linear_model1.mse_(Xpill, Yscore))
# 57.60304285714282
print("NB2", mean_squared_error(Yscore, Y_model1))
# 57.603042857142825
# print("NB1", linear_model2.mse_(Y_model2, Yscore))
print("NB3", linear_model2.mse_(Xpill, Yscore))
# 232.16344285714285
print("NB4", mean_squared_error(Yscore, Y_model2))
# 232.16344285714285

data.plot.scatter("Micrograms", "Score")
# plt.show()

x = np.linspace(0,10,100)
y = linear_model1.theta[0] + (linear_model1.theta[1] * x)
plt.plot(x, y, '-r', label='Linear model 1')
# plt.title('Linear model 1')
y = linear_model2.theta[0] + (linear_model2.theta[1] * x)
plt.plot(x, y, '-r', label='Linear model 2', color = "blue")

linear_model2.fit_(Xpill, Yscore, alpha = 1.6e-4, n_cycle=200000)

y = linear_model2.theta[0] + (linear_model2.theta[1] * x)
plt.plot(x, y, '-r', label='Linear model 2', color = "green")
plt.legend(loc='lower left')
plt.grid()
plt.show()

# theta = np.linspace(-14,-4,5)
# print(theta)
# print(x)
# for i in range(theta.shape[0]):
# 	sol = []
# 	for j in range(x.shape[0]):
# 		elem = MyLR(np.array([[theta[i]], [x[j]]]))
# 		sol.append( elem.mse_(Xpill, Yscore))
# 		print(elem.theta, sol)
# 		# print(linear_model1.theta)
# 	plt.plot(theta[i], sol, label='Theta exp')
# plt.grid()
# plt.show()


import subprocess
import itertools
import os
from time import sleep
import re

GCC_HEADER = r"""
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "\./common\.h" 1
# 1 "<command-line>" 2
# 1 "<stdin>"\n
""".strip()

# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "./common.h" 1
# 19 "./common.h"
# 57 "./common.h"
# 1 "<command-line>" 2
# 1 "<stdin>"

config = {
    "defines": {
    },
    "undefines": [
    ],
    "replacements": {
        # r"":
        #     r"",
        r"\n *#pragma warning\(pop\)":
            r"",
        r"\n *#pragma (once|endregion)":
            r"",
        r"\n *#pragma region (Application|Desktop) Family":
            r"",
        r'( *)#define(.+)\'([\w\d]{0,4})\'':
            r'\1#define\2nimCharArray("\3")',
        r'( *)#endif( +)(\w.*)':
            r'\1#endif\2// \3',
        r"#if WINAPI_FAMILY_PARTITION\((.*)\)":
            r"#if WINAPI_FAMILY_PARTITION // \1"
  }
}

# Directories to search through
start_dirs = ['shared', 'ucrt', 'um', 'winrt']

# Calculate CPPP arguments
cppp_args = ['cppp']
for symbol, value in config['defines'].items():
    cppp_args.append('-D')
    if value:
        cppp_args.append(symbol + "=" + value)
    else:
        cppp_args.append(symbol)
for symbol in config['undefines']:
    cppp_args.append('-U')
    cppp_args.append(symbol)

with open('common.h', 'r') as fh:
    for i, line in enumerate(fh, 1):
        if line.startswith("#define"):
            m = re.match(r'^\s*#define\s+(\w+)(?:\(.*?\))?(?:\s+([0-9]+))?', line)
            symbol = m.group(1)
            value = m.group(2)

            cppp_args.append('-D')
            if value:
                cppp_args.append(symbol + "=" + value)
            else:
                cppp_args.append(symbol)

        elif line.startswith("#undef"):
            m = re.match(r'^\s*#undef\s+(.+)', line)
            cppp_args.append('-U')
            cppp_args.append(m.group(1))

        elif line.strip() == "" or re.match(r'\s*//', line):
            pass
        else:
            raise Exception("Non-matching line in common.h, line {}, '{}'".format(i, line))

gcc_args = ['gcc', '-xc', '-undef', '-CC', '-E', '-imacros', 'common.h', '-']

target_trees = itertools.chain.from_iterable(map(os.walk, start_dirs))
for dirpath, dirnames, filenames in target_trees:
    for name in filenames:
        if not name.endswith('.h'):
            continue

        filepath = os.path.join(dirpath, name)
        print("Processing", filepath)

        with open(filepath, 'r') as fh:
            contents = fh.read()

        # Run through replacements
        for match, replacement in config['replacements'].items():
            contents = re.sub(match, replacement, contents)

        # Run CPPP tool
        cppp_process = subprocess.run(
            cppp_args,
            input=contents,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines = True,
            check = False
        )
        contents = cppp_process.stdout
        print(cppp_process.stderr)

        # Comment out defines
        contents = re.sub(r'^([ \t]*)#', r'\1pound#', contents, flags=re.MULTILINE)

        # Run GCC
        gcc_process = subprocess.run(
            gcc_args,
            input=contents,
            stdout = subprocess.PIPE,
            stderr = subprocess.PIPE,
            universal_newlines = True,
            check = False
        )
        contents = gcc_process.stdout
        print(gcc_process.stderr)

        # Uncomment defines
        contents = re.sub(r"^([ \t]*)pound#", r"\1#", contents, flags=re.MULTILINE)

        # Remove GCC Header
        contents = re.sub(r"(\n|^) *# \d{1,2} .*", "", contents)

        # Remove redundant defines
        contents = re.sub(r'\n *#define +(.*) +\1$', '', contents, flags=re.MULTILINE)
        contents = re.sub(r'\n *#define *$', '', contents, flags=re.MULTILINE)

        # Remove redundant ifdefs
        contents = re.sub(r'\n *#if(def)? +.+(\n *)+#endif.*', '', contents, flags=re.MULTILINE)

        # Remove extra whitespace
        contents = re.sub(r'(\n *){5,}', '', contents, flags=re.MULTILINE)

        with open(filepath + '.out', 'w') as fh:
            fh.write(contents)


import rasterio as rio
import numpy as np
import fiona
from rasterio.windows import Window
from rasterio import features
from osgeo import gdal
from osgeo import osr

import fiona.crs
from operator import itemgetter
import itertools
from multiprocessing import Pool
from typing import Union
from fct.algorithms.transform import *
from scipy.spatial import KDTree
from shapely.geometry import mapping, Polygon, Point, MultiPoint, multipolygon
from rasterio.features import shapes
from osgeo import ogr
import pandas as pd
import geopandas as gdp
from math import ceil
from collections import OrderedDict
from rasterio import mask

def generate_seeds(feature,type='Poly'):

    if type =='Poly-s':

        for point in feature['geometry']['coordinates']:

            p1 = Polygon(point)
            x, y = p1.centroid.x ,p1.centroid.y

            yield (x, y)
    elif type =='Poly-g':
        for point in feature:

            p1 = point
            x, y = p1.centroid.x ,p1.centroid.y

            yield (x, y)
    else:
        for point in feature['geometry']['coordinates']:

            x, y = point[:2]
            yield (x, y)

def extract_pointxy(name_shp,type_geo='Poly'):

    with fiona.open(name_shp) as ft:
        list_point = [s for feat in ft for s in generate_seeds(feat, type=type_geo)]

    return list_point

def create_grid(xmin,ymin,xmax,ymax,lenght,width,p='General'):

    cols = list(np.arange(np.floor(xmin), np.ceil(xmax), width)) #list(range(int(np.floor(xmin)), int(np.ceil(xmax)), int(width)))
    rows =  list(np.arange(np.floor(ymin), np.ceil(ymax), width)) #list(range(int(np.floor(ymin)), int(np.ceil(ymax)), int(lenght)))

    rows.reverse()
    polygons = []
    for x in cols:
        for y in rows:
            polygons.append(Polygon([(x, y), (x + width, y), (x + width, y - lenght), (x, y - lenght)]))

    if p == 'General':
        centroide_point = [(p1.centroid.x, p1.centroid.y) for p1 in polygons]
    else:
        centroide_point = [(p1.bounds[2], p1.bounds[1]) for p1 in polygons]
    return polygons, centroide_point

def select_pixel_river(river_points, centroide_grid, src_dem, parm):
    kd_tree = KDTree(centroide_grid)

    indexes = kd_tree.query_ball_point(river_points, parm)
    seeds = [(centroide_grid[j][0], centroide_grid[j][1]) for i in range(len(indexes)) for j in indexes[i]]

    meta = src_dem.meta
    # raster_band = raster.read(1)  # read raster band
    pixeles_coord = []
    for i in seeds:
        rowcol = rio.transform.rowcol(meta['transform'], xs=i[0], ys=i[1])
        w = src_dem.read(1, window=Window(rowcol[1], rowcol[0], 1, 1))
        if len(w.tolist()) !=0:
            pixeles_coord.append([i[0], i[1], w.tolist()[0][0]])

    return pixeles_coord

def select_points_buffer(z_value, centroids_point, Meta_raster_dem, src_raster,Threshold):
    select_pixel_by_point = []
    for h in centroids_point:
        xs = h[0]
        ys = h[1]
        rowcol2 = rio.transform.rowcol(Meta_raster_dem, xs=xs, ys=ys)
        w2 = src_raster.read(1, window=Window(rowcol2[1], rowcol2[0], 1, 1))
        row, col = rowcol2
        if len(w2.tolist()) != 0:
            try:
                zs = w2.tolist()[0][0]
            except:
                a = None
        tem_op = zs - z_value     #abs(z_value - zs)
        if  tem_op < Threshold and tem_op!= 0 and tem_op>0 :  # <
            select_pixel_by_point.append([xs, ys, zs, row, col])
    return select_pixel_by_point

def buffer_river_points(xyz_river_points,src_dem,distance_buffer,Threshold):

    lng, wgh = src_dem.res
    meta = src_dem.meta
    pixeles_buffer = []
    contar = 1
    print('Points: ',len(xyz_river_points))
    for j in xyz_river_points:
        print(len(xyz_river_points)-contar)
        z0 = j[2]
        x0 = j[0]
        yo = j[1]
        test = Point(j[0], j[1])

        buf = test.buffer(distance_buffer, cap_style=3)

        xmin, ymin, xmax, ymax = buf.bounds

        p_grids,centroids  = create_grid(xmin, ymin, xmax, ymax, lng, wgh,p='other')

        result = select_points_buffer(z0 , centroids, meta['transform'], src_dem,Threshold)

        pixeles_buffer.extend(result )

        contar += 1
    return pixeles_buffer

def remove_duplicates(points_buffer):

    data = pd.DataFrame(points_buffer, columns=['x', 'y', 'z','row','col'])
    tmp = OrderedDict()
    for point3 in zip(data.x, data.y, data.z,data.row,data.col):
        tmp.setdefault(point3[:2], point3)

    mypoints = tmp.values()

    result = [(pp[0], pp[1], pp[2], pp[3], pp[4]) for pp in mypoints]
    return result

def export_result_raster_and_shp(array_points,cols,rows,raster_reference, output_raster,output_shp,export_Raster=True,export_shp=True):

    zo = pd.DataFrame(np.zeros((cols,rows)))

    for xyz in array_points:
        try:
            zo[xyz[4]].loc[xyz[3]]= xyz[2]
        except:
            print(None)

    zi = np.array(zo)

    if export_Raster == True:
        d = gdal.Open(raster_reference)

        pixelWidth = d.GetGeoTransform()[1]
        pixelHeight = d.GetGeoTransform()[5]
        cols = zi.shape[1]
        rows = zi.shape[0]
        originX = d.GetGeoTransform()[0]
        originY = d.GetGeoTransform()[3]
        driver = gdal.GetDriverByName('GTiff')
        outRaster = driver.Create(output_raster, cols, rows, 1, gdal.GDT_Float32)
        outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))
        outband = outRaster.GetRasterBand(1)
        outband.WriteArray(zi)
        outRasterSRS = osr.SpatialReference()
        code_epsg =osr.SpatialReference(wkt= d.GetProjection()).GetAttrValue('AUTHORITY',1)
        outRasterSRS.ImportFromEPSG(int(code_epsg))  # Change EPSG 32618
        outRaster.SetProjection(outRasterSRS.ExportToWkt())
        outband.FlushCache()

    else:
        print(None)

    if export_shp == True:
        mask = None
        with rio.Env():
            with rio.open(output_raster) as src2:
                temp = src2.read(1) # first band
                image = np.where(zi != 0,1, 0)
                results = ({'properties': {'raster_val': v}, 'geometry': s}
                for i, (s, v)
                in enumerate(
                    shapes(image, mask=mask, transform=src2.transform)))

        geoms = list(results)
        gpd_polygonized_raster = gdp.GeoDataFrame.from_features(geoms, crs=src2.meta['crs'])

        gpd_polygonized_raster.to_file(output_shp)
    else:
        print(None)

path_in = r'/'

path_out = r'/'
version = 'v3'
distance =200
threshold = 3
name_drenajes = path_in+'Drenajes_10m_T400.shp'
name_dem =path_in +'dem_10.tif'

outRuta_r = path_out+'Valley'+str(distance/1000)+ 'km_'+str(threshold)+'m_'+version+'.tiff'
outRuta_shp = path_out+'Valley'+str(distance/1000)+ 'km_'+str(threshold)+'m_'+version+'.shp'

points_River = extract_pointxy(name_drenajes,'line')

#tiles = extract_pointxy(path_shp+'grid_arcgis.shp','Poly-s')

# load tif
src = rio.open(name_dem)
pixelH, pixelW = src.res
cols, rows = src.shape
x_min, y_min, x_max, y_max = src.bounds

poly_grids_g,centroids_tiles = create_grid(x_min, y_min, x_max, y_max,pixelH, pixelW)

xyz_river = select_pixel_river(points_River,centroids_tiles,src,pixelH/2)

buffer_points =buffer_river_points(xyz_river,src,distance,threshold)

result_points = remove_duplicates(buffer_points)

export_result_raster_and_shp(array_points=result_points,cols=cols,rows=rows,raster_reference=name_dem,
                             output_raster=outRuta_r,output_shp=outRuta_shp,export_Raster=True,export_shp=True)


#!/bin/python3

import math
import os
import random
import re
import sys
# def athelete_sort(score, sort_column):
#     """
#     The sorting fo the score data according to the column
#     :param score: The raw unsorted list
#     :param sort_column: column according to which sorting needs to be done
#     :return: sorted list
#     """
#     for index in range(len(score)):
#         min_idx = index
#
#         for j in range(index + 1, len(score)):
#             if score[min_idx][sort_column] > score[j][sort_column]:
#                 min_idx = j
#
#         score[index], score[min_idx] = score[min_idx], score[index]
#     return score
def value_column(val):
    return val[k]

if __name__ == '__main__':
    nm = input().split()

    n = int(nm[0])

    m = int(nm[1])

    arr = []

    for _ in range(n):
        arr.append(list(map(int, input().rstrip().split())))

    k = int(input())

    arr.sort(key=value_column)
    print(arr)
    # result = athelete_sort(arr, k)
    for i in range(len(arr)):
        for j in range(len(arr[i])):
            print(arr[i][j], end=" ")
        print()


"""
create_html_from_markdown.
"""
from logging import getLogger
from pathlib import Path
from subprocess import call
from typing import Optional

_LOGGER = getLogger(__name__)

def create_html_from_markdown_internal(
    bib_file: Optional[Path], folder_path: Path
) -> None:
    """

    :param bib_file:
    :param folder_path:
    :return:
    """
    _LOGGER.info(f"Processing folder {folder_path}")
    for markdown_file in folder_path.glob("**/*.md"):
        html_file = str(markdown_file).replace(".md", ".html")
        command_to_execute = [
            "pandoc",
            str(markdown_file),
            "-o",
            html_file,
        ]
        if bib_file is not None:
            command_to_execute += ["--bibliography", str(bib_file)]
        _LOGGER.info(f"Converting {markdown_file} to {html_file}")
        call(command_to_execute)


# 서로소 집합(disjoint Set) : 공통 원소가 없는 두 집합 = 합치기 찾기 자료구조 (Union Find)
# 서로소 집합 자료구조 - 서로소 부분 집합들로 나눠진 원소들의 데이터를 처리하기 위한 자료구조
# 서로소 집합 자료구조가 지원하는 두 연산
# - 합집합 : 두개 원소가 포함된 집합을 하나의 집합으로 합치는 연산
# - 찾기 : 특정 원소가 속한 집합이 어떤 집합인지 알려주는 연산
# => 합집합의 부모들을 동일하게 지정해주는걸 반복하면 됨 Ex) A(A') & B(B') B'를 A'으로 해줌
# 보통 더큰 루트노드가 더 작은 루트노드를 가리키는것이 관행이므로 이를 따르도록 함
# 서로소 집합 자료구조에선 연결성을 통해 쉽게 집합의 형태를 확인할 수 있음
# 단! 기본적인 형태의 서로소 집합 자료구조에서는 루트 노드에 즉시 접근할 수 없음 (부모테이블을 확인하며 재귀적으로 거슬러 올라가야함)

# 특정 원소가 속한 집합을 찾기
def find_parent(parent, x): # x: 노드번호
    # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출
    if parent[x] != x:
        return find_parent(parent, parent[x])
    return x

# 두 원소가 속한 집합을 합치기
def union_parent(parent, a, b):
    a = find_parent(parent, a)
    b = find_parent(parent, b)
    if a < b:
        parent[b] = a
    else:
        parent[a] = b

# 노드의 개수와 간선(Union 연산)의 개수 입력 받기
v, e = map(int, input().split())
parent = [0] * (v + 1) # 부모 테이블 초기화하기

# 부모 테이블상에서, 부모를 자기 자신으로 초기화
for i in range(1, v + 1):
    parent[i] = i

# Union 연산을 각각 수행
for i in range(e):
    a, b = map(int, input().split())
    union_parent(parent, a, b)

# 각 원소가 속한 집합 출력하기
print('각 원소가 속한 집합: ', end='')
for i in range(1, v + 1):
    print(find_parent(parent, i), end=' ')

print()

# 부모 테이블 내용 출력하기 => 당장 자신의 부모를 담고 있으며 루트와는 관련 없음을 의미
print('부모 테이블: ', end='')
for i in range(1, v + 1):
    print(parent[i], end=' ')

# =================수행시간에서 단점이 있을 수 있음 (합집합 연산이 편향되게 이뤄지는 경우 찾기 함수가 비효율적임)==================

# 찾기 함수의 최적화 방법으로 경로압축
# 찾기 함수를 재귀적으로 호출한 후 부모 테이블 값을 바로 갱신 ==> 부모의 값이 루트가 될 수 있도록 함

# 특정 원소가 속한 집합을 찾기
def find_parent(parent, x):
    # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출
    if parent[x] != x:
        parent[x] = find_parent(parent, parent[x])
    return parent[x]

#============================================================================================================
# 서로소 집합을 활용한 사이클 판별
# 서로소 집합은 무방향 그래프 내에서 사이클 판별할 때 사용 (방향그래프에서 사이클 여부는 DFS를 이용)

# 특정 원소가 속한 집합을 찾기
def find_parent(parent, x):
    # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출
    if parent[x] != x:
        parent[x] = find_parent(parent, parent[x])
    return parent[x]

# 두 원소가 속한 집합을 합치기
def union_parent(parent, a, b):
    a = find_parent(parent, a)
    b = find_parent(parent, b)
    if a < b:
        parent[b] = a
    else:
        parent[a] = b

# 노드의 개수와 간선(Union 연산)의 개수 입력 받기
v, e = map(int, input().split())
parent = [0] * (v + 1) # 부모 테이블 초기화하기

# 부모 테이블상에서, 부모를 자기 자신으로 초기화
for i in range(1, v + 1):
    parent[i] = i

cycle = False # 사이클 발생 여부

for i in range(e):
    a, b = map(int, input().split())
    # 사이클이 발생한 경우 종료
    if find_parent(parent, a) == find_parent(parent, b):
        cycle = True
        break
    # 사이클이 발생하지 않았다면 합집합(Union) 연산 수행
    else:
        union_parent(parent, a, b)

if cycle:
    print("사이클이 발생했습니다.")
else:
    print("사이클이 발생하지 않았습니다.")

#============================================================================================================
# 신장트리 : 그래프에서 모든 노드를 포함하면서 사이클이 존재하지 않는 부분그래프로 모든 노드가 연결되면서 사이클이 존재하지 않는다는 조건은 트리의 조건이기도 함
# 최소 신장 트리 : 최소의 비용으로 구성되는 신장트리 찾기
# 크쿠스칼 알고리즘 => 최소 신장 트리 알고리즘으로 그리디 알고리즘으로 분류됨
# 1. 간선 데이터를 비용에 따라 오름차순 정렬
# 2. 간선 하나씩 확인하며 현 간선이 사이클을 발생시키는지 확인하며 사이클이 발생하지 않는 경우 최소 신장트리에 포함시킴 이를 모든간선에 대해 반복

# 특정 원소가 속한 집합을 찾기
def find_parent(parent, x):
    # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출
    if parent[x] != x:
        parent[x] = find_parent(parent, parent[x])
    return parent[x]

# 두 원소가 속한 집합을 합치기
def union_parent(parent, a, b):
    a = find_parent(parent, a)
    b = find_parent(parent, b)
    if a < b:
        parent[b] = a
    else:
        parent[a] = b

# 노드의 개수와 간선(Union 연산)의 개수 입력 받기
v, e = map(int, input().split())
parent = [0] * (v + 1) # 부모 테이블 초기화하기

# 모든 간선을 담을 리스트와, 최종 비용을 담을 변수
edges = []
result = 0

# 부모 테이블상에서, 부모를 자기 자신으로 초기화
for i in range(1, v + 1):
    parent[i] = i

# 모든 간선에 대한 정보를 입력 받기
for _ in range(e):
    a, b, cost = map(int, input().split())
    # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정
    edges.append((cost, a, b)) # 튜플을 이용하면 기본적으로 첫번째 원소를 기준으로 정렬함

# 간선을 비용순으로 정렬
edges.sort()

# 간선을 하나씩 확인하며
for edge in edges:
    cost, a, b = edge
    # 사이클이 발생하지 않는 경우에만 집합에 포함
    if find_parent(parent, a) != find_parent(parent, b):
        union_parent(parent, a, b)
        result += cost

print(result)

#============================================================================================================
# 위상정렬 : 사이클이 없는 방향 그래프의 모든 노드를 방향성에 거스르지 않도록 순서대로 나열하는 것 => 큐와 DFS를 이용 가능
# 예로 선수과목을 고려한 학습 순서 설정

# 진입차수 : 특정한 노드로 들어오는 간선의 개수 Indegree
# 진출차수 : 특정 노드에서 나가는 간선의 개수  Outdegree

# 큐 이용시 진입차수가 0인 모든 노드를 큐에 넣고 큐가 빌때까지 다음을 반복
# 큐에서 원소를 꺼내 해당 노드에서 나가는 간선을 그래프에서 제거, 새롭게 진입차수가 0이 된 노드를 큐에 넣기
# 모든 원소를 방문하기 전에 큐가 빈다면 사이클이 존재함 => 정렬 불가

from collections import deque

# 노드의 개수와 간선의 개수를 입력 받기
v, e = map(int, input().split())
# 모든 노드에 대한 진입차수는 0으로 초기화
indegree = [0] * (v + 1)
# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화
graph = [[] for i in range(v + 1)]

# 방향 그래프의 모든 간선 정보를 입력 받기
for _ in range(e):
    a, b = map(int, input().split())
    graph[a].append(b) # 정점 A에서 B로 이동 가능
    # 진입 차수를 1 증가
    indegree[b] += 1

# 위상 정렬 함수
def topology_sort():
    result = [] # 알고리즘 수행 결과를 담을 리스트
    q = deque() # 큐 기능을 위한 deque 라이브러리 사용

    # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입
    for i in range(1, v + 1):
        if indegree[i] == 0:
            q.append(i)

    # 큐가 빌 때까지 반복
    while q:
        # 큐에서 원소 꺼내기
        now = q.popleft()
        result.append(now)
        # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기
        for i in graph[now]:
            indegree[i] -= 1
            # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입
            if indegree[i] == 0:
                q.append(i)

    # 위상 정렬을 수행한 결과 출력
    for i in result:
        print(i, end=' ')

topology_sort()