#! /usr/bin/python3

from argparse import ArgumentParser
import os
import pathlib

template_path = '/'.join(pathlib.Path(__file__).parent.resolve().__str__().split('/')[0:-1]) + '/templates/'

FILES_AND_TEMPLATES = {
    "init_git.sh": template_path + 'init_git.sh',
    "README.md": template_path + 'README.md',
    "Dockerfile": template_path + 'python/Dockerfile',
    "Makefile": template_path + 'python/Makefile',
    "poetry.toml": template_path + 'python/poetry.toml',
    "pyproject.toml": template_path + 'python/pyproject.toml',
    "src/__init__.py": template_path + 'python/empty.py',
    "tests/__init__.py": template_path + 'python/empty.py',
    "tests/test_sample.py": template_path + 'python/test_sample.py',
    "bin/placeholder.py": template_path + 'python/empty.py',
    ".env/env": template_path + 'python/env',
    ".env/test": template_path + 'python/env',
    ".gitignore": template_path + 'python/gitignore',
    ".circleci/config.yml": template_path + 'python/circleci_config.yml',
}

def create_docker_image(docker_image_name, root_directory="", username="user"):
    docker_image_directory = f"{root_directory}projects/{docker_image_name}"
    os.mkdir(docker_image_directory)
    os.mkdir(f"{docker_image_directory}/src")
    os.mkdir(f"{docker_image_directory}/tests")
    os.mkdir(f"{docker_image_directory}/bin")
    os.mkdir(f"{docker_image_directory}/.env")
    os.mkdir(f"{docker_image_directory}/.circleci")

    for file_path, template_file in FILES_AND_TEMPLATES.items():
        with open(template_file, "r") as temp:
            file_contents = temp.read()
        replaced_file_contents = file_contents.replace("docker_image_name", docker_image_name).replace("username", username)

        docker_image_file_path = f"{docker_image_directory}/{file_path}"
        print(f"Creating {docker_image_file_path}...")
        with open(docker_image_file_path, "w+") as f:
            f.write(replaced_file_contents)

        if ".sh" in file_path:
            os.chmod(docker_image_file_path, 0o755)

def create_docker_image_if_nonexistent(docker_image_name, root_directory="", username="user"):
    project_directory = root_directory + "projects/"

    if not os.path.exists(project_directory):
        os.mkdir(project_directory)
    if not os.path.exists(project_directory + docker_image_name):
        print(f"Creating {docker_image_name} docker_image...")
        create_docker_image(docker_image_name, root_directory, username)
    else:
        print(f"The {docker_image_name} docker_image already exists at {project_directory}. Not creating...")

if __name__ == "__main__":
    parser = ArgumentParser(prog="Docker-ater")
    parser.add_argument(
        "--name",
        "-n",
        dest="name",
        required=True,
        help="The name of the docker project to create.",
    )
    parser.add_argument(
        "--root",
        "-r",
        dest="root_path",
        required=False,
        default="",
        help="Optional: Root path where your new docker project will be created.",
    )
    parser.add_argument(
        "--user",
        "-u",
        dest="username",
        required=False,
        default="",
        help="Optional: Username of the github repo owner / organization.",
    )
    args = parser.parse_args()
    if args.root_path:
        if args.root_path[-1] != "/":
            root_path = args.root_path + "/"
    else:
        root_path = pathlib.Path.home().__str__() + "/"

    create_docker_image_if_nonexistent(args.name, root_path, args.username)


import json
import requests
from .keys import PEXELS_API_KEY, OPEN_WEATHER_API_KEY

def get_photo(city, state):
    headers = {"Authorization": PEXELS_API_KEY}

    params = {
        "per_page": 1,
        "query": f"{city} {state}"
    }

    url = "https://api.pexels.com/v1/search"

    response = requests.get(url, params=params, headers=headers)

    content = json.loads(response.content)

    try:
        return {"picture_url": content["photos"][0]["src"]["original"]}
    except (KeyError, IndexError):
        return {"picture_url": None}

def get_weather_data(city, state):

    url = "http://api.openweathermap.org/geo/1.0/direct"

    params = {
        "q": f"{city},{state},US",
        "limit": 1,
        "appid": OPEN_WEATHER_API_KEY
    }

    response = requests.get(url, params=params)
    content = json.loads(response.content)

    latitude = content[0]['lat']
    longitude = content[0]['lon']

    weather_url = "https://api.openweathermap.org/data/2.5/weather"

    weather_params = {
        "lat": latitude,
        "lon": longitude,
        "appid": OPEN_WEATHER_API_KEY
    }

    response = requests.get(weather_url, params=weather_params)

    weather_content = json.loads(response.content)

    try:
        return {
            "weather": weather_content["main"]["temp"],
            "description": weather_content["weather"][0]["description"]
            }

    except (KeyError, IndexError):
        return {"weather": None}


#!/bin/bash

"""Echoes the script filename and any supplied arguments."""

import argparse

def parse_arguments():
    """Extracts the command line arguments.

    Returns:
      The parsed command line arguments.
    """

    parser = argparse.ArgumentParser()
    parser.add_argument("filename", type=str, help="Path to file.")
    parser.add_argument(
        "-f",
        "--format",
        type=str,
        choices=["CSV", "TSV", "JSON"],
        default="CSV",
        help=r"File format.",
    )

    return parser.parse_args()

def main():
    """Performs the main task of the script."""

    args = parse_arguments()

    print(args)

if __name__ == "__main__":
    main()


'''
Q) X 일 동안 가장 많이 들어온 방문자 수와 기간이 몇 개 있는지 확인하자
 - X 일 동안 가장 많이 들어온 방문자 수를 출력한다
    만약 최대 방문자 수가 0명이라면 SAD 를 출력한다
- 만약 최대 방문자 수가 0 명이 아닌 경우 둘째 줄에 기간이 몇 개 있는지 확인한다

'''

# N : 블로그를 시작하고 지난 일수
N, X = map(int, input().split())

# 1일차부터 N일차까지 하루 방문자 수
visited = list(map(int, input().split()))

max_visit = sum(visited[:X])  # 첫 X일 동안의 방문자 수
current_visit = max_visit
count = 1

for i in range(X, N):
    # 새로운 날의 방문자 수를 추가하고, 가장 오래된 날의 방문자 수를 뺌
    current_visit = current_visit + visited[i] - visited[i - X]

    # 최대 방문자 수 갱신
    if current_visit > max_visit:
        max_visit = current_visit
        count = 1  # 새로운 최대값이므로 카운트 초기화
    elif current_visit == max_visit:
        count += 1  # 동일한 최대값 발견 시 카운트 증가

if max_visit == 0:
    print('SAD')
else:
    print(max_visit)
    print(count)


# Write your FrequentWordsWithMismatches() function here, along with any subroutines you need.
# Your function should return a list.

# test1

# from collections import OrderedDict
# from operator import itemgetter

# def FrequentWordsWithMismatches(sequence, motif_length, max_mismatches, most_common=False):
# #def kmers_finder_with_mismatches(sequence, motif_length, max_mismatches, most_common=False):
#   '''(str, int, int) -> sorted(list)
#   Find the most frequent k-mers with mismatches in a string.
#   Input: A sequence and a pair of integers: motif_length (<=12) and max_mismatch (<= 3).
#   Output: An OrderedDict containing all k-mers with up to d mismatches in string.
#   If most_common: return only the most represented kmer(s).
#   Sample Input:   ACGTTGCATGTCGCATGATGCATGAGAGCT 4 1
#   Sample Output:  OrderedDict([('ATGC', 5), ('ATGT', 5), ('GATG', 5),...])
#   '''

#   #check passed variables
#   if not motif_length <= 12 and motif_length >= 1:
#       raise ValueError("motif_length must be between 0 and 12. {} was passed.".format(motif_length))
#   if not max_mismatches <= 3 and max_mismatches >= 1:
#       raise ValueError("max_mismatch must be between 0 and 3. {} was passed.".format(max_mismatches))

#   #build a dict of motifs/kmers
#   motif_dict = {}
#   for i in range(len(sequence) - motif_length +1):
#       motif = sequence[i:i+motif_length]
#       if motif not in motif_dict:
#           motif_dict[motif] = 1
#       else:
#           motif_dict[motif] += 1

#   #check for mismatches
#   motif_dict_with_mismatches = {}
#   for kmer in motif_dict:
#       motif_dict_with_mismatches.update({kmer:[]})

#       for other_kmer in motif_dict:
#           mismatches = 0
#           for i in range(len(kmer)):
#               if kmer[i] != other_kmer[i]:
#                   mismatches += 1
#           if mismatches <= max_mismatches:
#               motif_dict_with_mismatches[kmer].append([other_kmer,motif_dict[other_kmer]])

#   #count occurrences of motifs
#   tmp = {}
#   for item in motif_dict_with_mismatches:
#       count = 0
#       for motif in motif_dict_with_mismatches[item]:
#           count += motif[-1]
#       tmp.update({item:count})

#   result = OrderedDict(sorted(tmp.items(), key=itemgetter(1), reverse=True))

#   #find the most common/s
#   if most_common:
#       commons = OrderedDict()
#       _max = result.items()[0][1]
#       for item in result:
#           if result[item] == _max:
#               commons.update({item:result[item]})
#           else:
#               return commons

#   # return result

#   # used for stepik
#   res = []
#   for key in a:
#       if a[key] == m:
#           res.append(a[key])

##Test
# sequence = 'ACGTTGCATGTCGCATGATGCATGAGAGCT'
# motif_length = 4
# max_mismatches = 1
# a = FrequentWordsWithMismatches(sequence, motif_length, max_mismatches, most_common=False)
# m = max(a.values())
# res = []
# for key in a:
#     if a[key] == m:
#       print(key, a[key])

# test2

# import collections
# kmer = 4
# in_genome = "ACGTTGCATGTCGCATGATGCATGAGAGCT";
# in_mistake = 1;
# out_result = [];
# mismatch_list = []

# def hamming_distance(s1, s2):
#   # Return the Hamming distance between equal-length sequences
#   if len(s1) != len(s2):
#       raise ValueError("Undefined for sequences of unequal length")
#   else:
#       return sum(ch1 != ch2 for ch1, ch2 in zip(s1, s2))

# for i in range(len(in_genome)-kmer + 1):
#   v = in_genome[i:i + kmer]
#   out_result.append(v)

# for i in range(len(out_result)):
#   for j in range(i + 1, len(out_result)):
#       if hamming_distance(out_result[i], out_result[j]) <= in_mistake:
#           mismatch_list.extend([out_result[i], out_result[j]])

# #  Here is some code that counts the occurrences in mismatch_list,
# # sorts the results by frequency (not used, but you
# # may want it later),
# # and then prints all those that match the assumed frequency of 4.
# mismatch_count = collections.Counter(mismatch_list)
# sorted_match = sorted(list(mismatch_count), key=lambda pair: pair[1], reverse=True)
# for item, value in mismatch_count.items():
#     if value == 4:
#         print(item)

# print(mismatch_count)
# print(mismatch_list)
# create a result dict
# mismatch_res = {}

# # create a set out of list
# mismatch_set = set(mismatch_list)
# for match in mismatch_set:
#   # print(match)
#   mismatch_res[match] = mismatch_list.count(match)

# print(mismatch_res)

# aLGORITHM
# from .d-neigbours import findNeigbours

# def FrequentWordsWithMismatches(Text, k, d)
#         FrequentPatterns = set()
#         Neighborhoods = list()
#         for i in range(len(Text) − len(k) + 1):
#             Neighborhoods.append(findNeigbours(Text(i, k), d)
#         NeighborhoodArray = []
#         for i in Neighborhoods:
#           for patern in i:
#               NeighborhoodArray.append(patern)
#         for i ← 0 to |Neighborhoods| − 1
#             Pattern ← NeighborhoodArray(i)
#             Index(i) ← PatternToNumber(Pattern)
#             Count(i) ← 1
#         SortedIndex ← Sort(Index)
#         for i ← 0 to |Neighborhoods| − 2
#             if SortedIndex(i) = SortedIndex(i + 1)
#                 Count(i + 1) ← Count(i) + 1
#        maxCount ← maximum value in array Count
#        for i ← 0 to |Neighborhoods| − 1
#            if Count(i) = maxCount
#                Pattern ← NumberToPattern(SortedIndex(i), k)
#                add Pattern to FrequentPatterns
#        return FrequentPatterns

# Test3: tested working, only test #8 failed.
import d_neigbours, math
from count1 import ApproximatePatternCount

# create variables to work with
Text = 'ACGTTGCATGTCGCATGATGCATGAGAGCT'
# patern = 'ACGT'
k = 4
d = 1
# 1. build an array of k-mers Neighborhoods
# neigbours = d_neigbours.findNeigbours(patern, d)
# print(neigbours)

# convert patern to number in the neigbours array
def PatternToNumber(patern):
    '''
        convert patern to number given patern of k-mer
        e.g: PatternToNumber('AAAA') -> 0
        @args: i -> str, represents patern of each k-mer in
                lexicographic order
        @returns: int, the index of patern in its Neighborhoods
    '''
    neigbours = sorted(d_neigbours.findNeigbours(patern, k))
    return neigbours.index(patern)

def NumberToPattern(i, k):
    '''
        convert number back to patern given i and k-mer
        e.g: NumberToPattern(0, 4) -> 'AAAA'
        @args: i -> int, represents index of each k-mer in in
                lexicographic order
        @args: k -> int, represents the number of DNA k-mers
        @returns: str, the patern of k-mers at index i in its Neighborhoods
    '''
    patern = 'A' * k
    neigbours = sorted(d_neigbours.findNeigbours(patern, k))
    return neigbours[i]

# test NumberToPattern function
# print(NumberToPattern(0, 4))

# 2. create an index array of k-mers (k raised to power k)
def ComputingFrequenciesWithMismatches(Text, k, d):
    FrequencyArray = []
    for i in range(int(math.pow(4, k))):
      FrequencyArray.append(0)

    # print(FrequencyArray)
    for i in range(len(Text) - k + 1):
        ptn = Text[i:i + k]
        neigbours = sorted(d_neigbours.findNeigbours(ptn, d))
        # print('neigbours -> ', i)

        for ApproximatePattern in neigbours:
            # print(ApproximatePattern)
            j = PatternToNumber(ApproximatePattern)
            FrequencyArray[j] += 1
            # print(ApproximatePattern, end=' ')

    return FrequencyArray

# now get the frequent words with mismatches
def FrequentWordsWithMismatches(Text, k, d):
    '''
        Frequent Words with Mismatches Problem: Find the most
            frequent k-mers with mismatches in a string.
        Input: A string Text as well as integers k and d.
            (You may assume k ≤ 12 and d ≤ 3.)
        Output: All most frequent k-mers with up to d mismatches
            in Text.
    '''

    # get the FrequencyArray in Text
    FrequencyArray = ComputingFrequenciesWithMismatches(Text, k, d)

    # get the maximum count of the most frequent word
    m = max(FrequencyArray)

    # lastly, get the most frequent word
    most_common = [NumberToPattern(i, k) for i, value in enumerate(FrequencyArray) if value == m]

    # return the most_common word
    return most_common

# m = (ComputingFrequenciesWithMismatches(Text, k, d).count(5))
#print(FrequentWordsWithMismatches(Text, k, d))
# print(m)
# 3. build the frequency array with up to d mismatches

# test4 worked excellently
import itertools
import time
from collections import defaultdict

def FrequentWordsWithMismatches(Genome, k, d):
    start = time.process_time()
    aprox_frq_words = []
    frequencies = defaultdict(lambda: 0)
    # all existent kmers with d mismatches of current kmer in genome
    for index in range(len(Genome) - k + 1):
        curr_kmer_and_neighbors = PermuteMotifDistanceTimes(Genome[index : index + k], d)
        for kmer in curr_kmer_and_neighbors:
            frequencies[kmer] += 1

    for kmer in frequencies:
        if frequencies[kmer] == max(frequencies.values()):
            aprox_frq_words.append(kmer)
    end = time.process_time()
    print("Time:", end - start)
    return aprox_frq_words

def PermuteMotifOnce(motif, alphabet={"A", "C", "G", "T"}):
    """
    Gets all strings within hamming distance 1 of motif and returns it as a
    list.
    """

    return list(set(itertools.chain.from_iterable([[
        motif[:pos] + nucleotide + motif[pos + 1:] for
        nucleotide in alphabet] for
        pos in range(len(motif))])))

def PermuteMotifDistanceTimes(motif, d):
    workingSet = {motif}
    for _ in range(d):
        workingSet = set(itertools.chain.from_iterable(map(PermuteMotifOnce, workingSet)))
    return list(workingSet)

# create variables to work with
Text = 'ACGTTGCATGTCGCATGATGCATGAGAGCT'
# patern = 'ACGT'
k = 4
d = 1

print(FrequentWordsWithMismatches(Text, k, d))

week one/Frequent Words with Mismatches.py


import random
from decorator_utilities import utility_decorator
import time

@utility_decorator
def do_math(x):
	time.sleep(1.25)
	print(random.randint(1000,1000000)//random.randint(1000,100000))
	print(x*random.randint(10000,10000000))
	return "done"

if __name__ == '__main__':
	g = do_math
	print(g)
	print(g(11))


# Ordena um vetor de palavras em ordem alfabética

palavras = ["Camarão", "Chimarrão", "Banana", "Mesa", "Tábua", "Abelha", "Mel",
           "Mostarda", "Time", "Escanteio", "Zebra", "Dinossauro", "Xerox",
           "Favo", "Neve", "Sol", "Verão", "Inverno", "Kiwi", "Lombriga" ]

#def ordena(lista):

#    tamanho = len(lista)

#    if(tamanho == 1):
#        return

#    for i in range(tamanho - 2):

#        j = i + 1

#        for j in range(tamanho - 1):

#            ord1 = lista[i][0]
#            ord2 = lista[j][0]


import numpy as np
from tensorflow import keras

import cv2

class DataGenerator(keras.utils.Sequence):
    def __init__(self, image_filenames, labels, batch_size, num_classes, image_shape=(224, 224)):
        self.image_filenames, self.labels = image_filenames, labels
        self.batch_size = batch_size
        self.image_shape = image_shape
        self.num_classes = num_classes
        self.n = len(image_filenames)

    def __len__(self):
        return int(np.ceil(len(self.image_filenames) / float(self.batch_size)))

    def __getitem__(self, idx):
        batch_x = self.image_filenames[idx * self.batch_size : (idx + 1) * self.batch_size]
        batch_y = self.labels[idx * self.batch_size : (idx + 1) * self.batch_size]
        batch_imgs = np.array(
            [cv2.resize(cv2.imread(file_name), self.image_shape) for file_name in batch_x]
        )

        mean = np.mean(batch_imgs, axis=(1, 2), keepdims=True)
        std = np.std(batch_imgs, axis=(1, 2), keepdims=True)
        standardized_images = (batch_imgs - mean) / std

        return (
            standardized_images,
            keras.utils.to_categorical(np.array(batch_y), num_classes=self.num_classes),
        )


from __future__ import absolute_import, division, print_function

import pytest
pytest.importorskip('dask')

from odo.backends.dask import append, Array, merge
from dask.array.core import insert_to_ooc
from dask import core
from odo import convert, into
from odo.utils import tmpfile
import numpy as np
import bcolz

def eq(a, b):
    c = a == b
    if isinstance(c, np.ndarray):
        c = c.all()
    return c

def test_convert():
    x = np.arange(600).reshape((20, 30))
    d = convert(Array, x, blockshape=(4, 5))

    assert isinstance(d, Array)

def test_convert_to_numpy_array():
    x = np.arange(600).reshape((20, 30))
    d = convert(Array, x, blockshape=(4, 5))
    x2 = convert(np.ndarray, d)

    assert eq(x, x2)

def test_append_to_array():
    x = np.arange(600).reshape((20, 30))
    a = into(Array, x, blockshape=(4, 5))
    b = bcolz.zeros(shape=(0, 30), dtype=x.dtype)

    append(b, a)
    assert eq(b[:], x)

    with tmpfile('hdf5') as fn:
        h = into(fn+'::/data', a)
        assert eq(h[:], x)
        h.file.close()

def test_into_inplace():
    x = np.arange(600).reshape((20, 30))
    a = into(Array, x, blockshape=(4, 5))
    b = bcolz.zeros(shape=(20, 30), dtype=x.dtype)

    append(b, a, inplace=True)
    assert eq(b[:], x)

def test_insert_to_ooc():
    x = np.arange(600).reshape((20, 30))
    y = np.empty(shape=x.shape, dtype=x.dtype)
    a = convert(Array, x, blockshape=(4, 5))

    dsk = insert_to_ooc(y, a)
    core.get(merge(dsk, a.dask), list(dsk.keys()))

    assert eq(y, x)

def test__array__():
    x = np.arange(600).reshape((20, 30))
    d = convert(Array, x, blockshape=(4, 5))

    assert eq(x, np.array(d))


serie  = ["the walking dead","Entourage","The sopranos"]

for series in serie:
    print(serie)

for i in range(25,50):
    print(i)

shows = ["The Walking Dead", "Entourage", "The Sopranos", "The Vampire Diaries"]
for index, show in enumerate(shows):
    print(index)
    print(show)

numeros = [1,23,56,70]

while True:
    palpite = input("tente adivinhar o número")

    if palpite == "q":
        break
    try:
        palpite = int(palpite)
    except ValueError:
        print("please type a number or q to quit.")
    if palpite in numeros:
        print("Seu palpite esta certo")
    else:
        print("Seu palpite está errado")

numeros1 = [8,19,148,4]
numeros2 = [9,1,33,83]
result = []

for i in numeros1:
    for j in numeros2:
        mult = i * j
        result.append(mult)

print(result)


def sortByRanking(val):
    return val[1]

def sortByOriginalOrder(val):
    return val[2]

def create_summary(original_sentences_ranked, summary_percent, debug):
    original_sentences_ranked.sort(key=sortByRanking, reverse=True)

    top_sentences_count = round(
        len(original_sentences_ranked) * summary_percent / 100)

    top_sentences = original_sentences_ranked[0:top_sentences_count]

    top_sentences.sort(key=sortByOriginalOrder)

    summary_sentences = []

    for enhanced_sentence in top_sentences:
        sentence = enhanced_sentence[0]

        if debug:
            original_index = str(enhanced_sentence[2] + 1)
            ranking = ' [' + str(round(enhanced_sentence[1], 2)) + ']\n'

            line = sentence.split('\n')[0]
            summary_sentences.append(original_index + ' ' + line + ranking)
        else:
            summary_sentences.append(sentence)

    return summary_sentences


# Pong v3
#
# Pong is a game where two players try to bounce a moving ball into the oponents side
# The ball bounces off the walls and if it hits the oponents side the player gets a score
# The players use their paddles to stop and bounce the ball around
# First person to get to 11 points wins
#
# v3 requirements:
# In v3 the players are now able to move the paddles up and down by pressing the associated keys

# imports the pygame module
import pygame

# User-defined fucntions

def main():
   # initialize all pygame modules
   pygame.init()
   # create a pygame display window
   window_width = 500
   window_height = 400
   pygame.display.set_mode((window_width, window_height))
   # set the title of the display window
   pygame.display.set_caption('Pong')
   # get the display surface
   w_surface = pygame.display.get_surface()

   # create a game object
   game = Game(w_surface, window_width, window_height)
   # start the main game loop by calling the play method on the game object
   game.play()
   # quit pygame and clean up the pygame window
   pygame.quit()

# User-defined classes

class Game:
   # An object in this class represents a complete game.

   def __init__(self, surface, window_width, window_height):
      # Initialize a Game.
      # - self is the Game to initialize
      # - surface is the display window surface object
      # - bg_color us the background colour
      # - FPS is the frames per second
      # - game_Clock is our games timekeeping clock
      # - close_clicked is a boolean set as false
      # - self.continue_game is a boolean set as true

      # === general game objects
      self.surface = surface
      self.window_width = window_width
      self.window_height = window_height
      self.bg_color = pygame.Color('black')
      self.FPS = 60
      self.game_Clock = pygame.time.Clock()
      self.close_clicked = False
      self.continue_game = True

      # === game specific objects

      # Paddles specifications
      self.paddle_margin_wall = 100
      self.paddle_width = 12
      self.paddle_height = 50
      self.paddle_color = pygame.Color('white')

      # left paddle specifications
      self.left_paddle_position = [self.paddle_margin_wall, self.window_height //2 - self.paddle_height // 2]
      self.left_paddle_velocity = 0
      self.left_paddle_params = pygame.Rect(self.left_paddle_position[0], \
                                self.left_paddle_position[1], self.paddle_width, self.paddle_height)

      # right paddle specifications
      self.right_paddle_position = [self.window_width - self.paddle_width \
                                 - self.paddle_margin_wall, self.window_height //2 - self.paddle_height // 2]
      self.right_paddle_velocity = 0
      self.right_paddle_params = pygame.Rect(self.right_paddle_position[0], \
                                 self.right_paddle_position[1], self.paddle_width, self.paddle_height)

      # create the left and right paddles
      self.left_paddle = Paddle(self.paddle_color ,self.left_paddle_params, self.left_paddle_position, surface)
      self.right_paddle = Paddle(self.paddle_color ,self.right_paddle_params, self.right_paddle_position, surface)

      # balls specifications
      self.ball_radius = 6
      self.ball_colour = 'white'
      self.x_velocity = 9
      self.y_velocity = 3
      self.center = [window_width // 2 - 7, window_height // 2 - 7]

      # create the ball
      self.ball = Ball(self.ball_colour, self.ball_radius, self.center, \
                  [self.x_velocity, self.y_velocity], self.left_paddle, self.right_paddle, surface)

      # create scoreboard values
      self.score_left, self.score_right = 0, 0

   def play(self):
      # Play the game until the player presses the close box.
      # - self is the Game that should be continued or not.

      while not self.close_clicked:  # until player clicks close box
         # play frame
         self.handle_events()
         self.draw()
         if self.continue_game:
            self.update(self)
            self.decide_continue()
         self.game_Clock.tick(self.FPS) # run at most with FPS Frames Per Second

   def handle_events(self):
      # Handle each user event by changing the game state appropriately.
      # - self is the Game whose events will be handled
      # - pygame.KEYDOWN and pygame.KEYUP are functions used to check for keyboard presses

      events = pygame.event.get()
      for event in events:
         if event.type == pygame.QUIT:
            self.close_clicked = True

         if event.type == pygame.KEYDOWN and self.continue_game: # Has there been a keyboard click?
            self.handle_key_down(event.key)

         if event.type == pygame.KEYUP and self.continue_game: # Has there been a keyboard release?
            self.handle_key_up(event.key)

   def handle_key_down(self,key):
      # change the velocity of the paddles which moves the paddles up and down
      # depending on what key is pressed
      # velocity_change is used for this and is of type int
       # self.left_paddle_velocity and self.right_paddle_velocity are of type int

      velocity_change = 5

      # when the 'q' key is pressed down the left paddle moves up
      # when the 'a' key is pressed down the left paddle moves down
      if key == pygame.K_q:
         self.left_paddle_velocity = -velocity_change
      if key == pygame.K_a:
         self.left_paddle_velocity = velocity_change

      # when the 'p' key is pressed down the right paddle moves up
      # when the 'l' key is pressed down the right paddle moves down
      if key == pygame.K_p:
         self.right_paddle_velocity = -velocity_change
      if key == pygame.K_l:
         self.right_paddle_velocity = velocity_change

   def handle_key_up(self,key):
      # when the 'q' key or the 'a' is released the left paddle stops moving because the velocity is
      # changed to zero
      # self.left_paddle_velocity and self.right_paddle_velocity are of type int
      if key == pygame.K_q:
         self.left_paddle_velocity = 0
      if key == pygame.K_a:
         self.left_paddle_velocity = 0

      # when the 'p' key or the 'l' is released the right paddle stops moving
      if key == pygame.K_p:
         self.right_paddle_velocity = 0
      if key == pygame.K_l:
         self.right_paddle_velocity = 0

   def move_paddle(self):
      # sets the paddles to constantly move based on the velocities of the paddles and restricts
      # movement of paddles offscreen
      self.left_paddle_params.top +=  self.left_paddle_velocity
      self.right_paddle_params.top += self.right_paddle_velocity

      # restrict the left paddle from moving off screen
      if self.left_paddle_params.top <= 0:
         self.left_paddle_params.top = 0
      if self.left_paddle_params.bottom >= self.window_height:
         self.left_paddle_params.bottom = self.window_height

      # restrict the right paddle from moving off screen
      if self.right_paddle_params.top <= 0:
         self.right_paddle_params.top = 0
      if self.right_paddle_params.bottom >= self.window_height:
         self.right_paddle_params.bottom = self.window_height

   def draw(self):
      # Draw all game objects.
      # - self is the Game to draw
      self.surface.fill(self.bg_color) # clear the display surface first
      self.ball.draw()
      self.left_paddle.draw()
      self.right_paddle.draw()
      self.draw_score()
      pygame.display.update() # make the updated surface appear on the display

   def draw_score(self):
      # render scoreboards text to screen
      text_color = pygame.Color('white')
      text_font = pygame.font.SysFont("", 72)
      left_scoreboard_position = (0, 0)
      left_scoreboard = text_font.render(str(self.score_left), True, text_color)
      self.surface.blit(left_scoreboard , left_scoreboard_position)
      right_scoreboard = text_font.render(str(self.score_right), True, text_color)
      right_scoreboard_position = (self.window_width - right_scoreboard.get_width(), 0)
      self.surface.blit(right_scoreboard, right_scoreboard_position)

   def update(self, key):
      # Update the game objects for the next frame.
      # - self is the Game to update
      self.ball.move()
      self.move_paddle()
      self.ball.collision_paddle(self.left_paddle_params,self.right_paddle_params)

      # check if the ball hit the left or right wall and discribute points accordingly
      if self.center[0] < self.ball_radius:
         self.score_right +=  1
      if self.center[0] + self.ball_radius > self.window_width:
         self.score_left += 1

   def decide_continue(self):
      # Decides game end condition
      if self.score_left >= 11 or self.score_right >= 11:
         self.continue_game = False

class Ball:
   # An object in this class represents a Ball that that moves

   def __init__(self, ball_color, ball_radius, ball_center, ball_velocity, left_paddle, right_paddle, surface):
      # Initialize the ball.
      # - self is the Ball to initialize
      # - color is the pygame.Color of the Ball
      # - center is a list containing the x and y int
      #   coords of the center of the Ball
      # - radius is the int pixel radius of the Ball
      # - velocity is a list containing the x and y components
      # - surface is the window's pygame.Surface object
      self.color = pygame.Color(ball_color)
      self.radius = ball_radius
      self.center = ball_center
      self.velocity = ball_velocity
      self.left_padle = left_paddle
      self.right_paddle = right_paddle
      self.surface = surface

   def move(self):
      # Change the location of the Ball by adding the corresponding
      # speed values to the x and y coordinate of its center
      # - self is the Ball
      # move our Ball based on its velocity. If it comes in contact
      # with any of the four walls, reverse its direction of motion.
      size = self.surface.get_size()
      for index in range(0, len(size)):
         self.center[index] = (self.center[index] + self.velocity[index])
         if (self.center[index] < self.radius \
             or self.center[index] > size[index] - self.radius):
            self.velocity[index] = -self.velocity[index]

   def draw(self):
      # Draw the Ball on the surface
      # - self is the Ball
      pygame.draw.circle(self.surface, self.color, self.center, self.radius)

   def collision_paddle(self, left_paddle, right_paddle):
      # check if ball bounced on the  front of each paddle
      # collidepoint is associated with the pygame rect object and is used to chick if the ball
      # collides with the paddle
      if left_paddle.collidepoint(self.center[0] - self.radius, self.center[1]) and self.velocity[0] < 0 \
         or right_paddle.collidepoint(self.center[0] + self.radius, self.center[1]) and self.velocity[0] > 0: \
         self.velocity[0] = -self.velocity[0]

class Paddle:
   # An object in this class represents a paddle

   def __init__(self, paddle_color, paddle_params, paddle_position, surface):
      # Initialize the paddle
      # - self is the paddle to initialize
      # - paddle_color is the Color of the paddle
      # - rect_params give the values of rect_left, rect_top, rect_width, rect_height
      # - surface is the window's pygame.Surface object
      self.paddle_color = paddle_color
      self.paddle_params = paddle_params
      self.paddle_position = paddle_position
      self.surface = surface

   def draw(self):
      # Draw the paddle on the surface
      # - self is the paddle
      pygame.draw.rect(self.surface, self.paddle_color, self.paddle_params)

main()


import streamlit as st
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

def head():
    st.markdown("""

        Kelime Testi Envanteri

    """, unsafe_allow_html=True
                )

    st.caption("""

        Sakarya Üniversitesi Kariyer ve Yetenek Yönetimi Koordinatörlüğü

    """, unsafe_allow_html=True
               )

def body():
    mavi, sari, kirmizi, yesil = 0, 0, 0, 0
    st.markdown("""

            Güçlü Yönler. Her dört seçenekten birini seçiniz.

        """, unsafe_allow_html=True
            )

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose1 = st.radio("------------------------------------- " + "1" + " -------------------------------------",
                            ("Sonuç Odaklı", "Uyum Sağlayan", "Hareketli", "Analitik"),
                            key="choose1",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose2 = st.radio("------------------------------------- " + "2" + " -------------------------------------",
                            ("Mantıklı", "Neşeli", "İkna Edici", "Barışçıl"),
                            key="choose2",
                            horizontal=True)
    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose3 = st.radio("------------------------------------- " + "3" + " -------------------------------------",
                            ("Uysal", "Fedakar", "Sosyal", "İradeli"),
                            key="choose3",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose4 = st.radio("------------------------------------- " + "4" + " -------------------------------------",
                                ("İnsaflı", "Denetimli", "Yarışçıl", "İnandırıcı"),
                                key="choose4",
                                horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose5 = st.radio("------------------------------------- " + "5" + " -------------------------------------",
                                ("Ferahlatıcı", "Saygılı", "İyi dinleyici", "Becerikli"),
                                key="choose5",
                                horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose6 = st.radio("------------------------------------- " + "6" + " -------------------------------------",
                            ("Hoşnut", "Duyarlı", "Kendine güvenen", "Cesur"),
                            key="choose6",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose7 = st.radio("------------------------------------- " + "7" + " -------------------------------------",
                            ("Planlı", "Sabırlı", "Olumlu", "Teşvik edici"),
                            key="choose7",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose8 = st.radio("------------------------------------- " + "8" + " -------------------------------------",
                            ("Emin", "Kendiliğinden", "Programa bağlı", "Utangaç"),
                            key="choose8",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose9 = st.radio("------------------------------------- " + "9" + " -------------------------------------",
                            ("Düzenli", "İyiliksever", "Dobra", "İyimser"),
                            key="choose9",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose10 = st.radio("------------------------------------- " + "10" + "-------------------------------------",
                            ("Arkadaşçıl", "Sadık", "Komik", "Baskıcı"),
                            key="choose10",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose11 = st.radio("------------------------------------- " + "11" + "-------------------------------------",
                            ("Cesaretli", "Hoş", "Diplomatik", "Detaycı"),
                            key="choose11",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose12 = st.radio("------------------------------------- " + "12" + "-------------------------------------",
                            ("Esin Kaynağı", "Tutarlı", "Kültürlü", "Güvenli"),
                            key="choose12",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose13 = st.radio("------------------------------------- " + "13" + "-------------------------------------",
                            ("İdealist", "Bağımsız", "Zararsız", "Heyecanlandırıcı"),
                            key="choose13",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose14 = st.radio("------------------------------------- " + "14" + "-------------------------------------",
                            ("Coşkun", "Kesin", "Kuru esprili", "Derin düşünceli"),
                            key="choose14",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose15 = st.radio("------------------------------------- " + "15" + "-------------------------------------",
                            ("Aracı", "Ahenkli", "Harekete geçiren", "Kolay kaynaşır"),
                            key="choose15",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose16 = st.radio("------------------------------------- " + "16" + "-------------------------------------",
                            ("İnce düşünceli", "İş Bitirici", "Konuşma yanlısı", "Hoşgörülü"),
                            key="choose16",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose17 = st.radio("------------------------------------- " + "17" + "-------------------------------------",
                            ("Destekleyen", "Samimi", "Lider", "Canlı"),
                            key="choose17",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose18 = st.radio("------------------------------------- " + "18" + "-------------------------------------",
                            ("Halinden memnun", "Başkan, Şef", "Araştırmacı", "Şirin"),
                            key="choose18",
                            horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose19 = st.radio("------------------------------------- " + "19" + "-------------------------------------",
                        ("Mükemmeliyetçi", "Cana yakın", "Üretici", "Popüler"),
                        key="choose19",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose20 = st.radio("------------------------------------- " + "20" + "-------------------------------------",
                        ("Cömert", "Atılgan", "Terbiyeli", "Dengeli"),
                        key="choose20",
                        horizontal=True)

    st.markdown("""

            Zayıf Yönler. Her dört seçenekten birini seçiniz.

        """, unsafe_allow_html=True
            )

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose21 = st.radio("------------------------------------- " + "21" + "-------------------------------------",
                        ("İfadesiz", "Çekingen", "Utanması olmayan", "Zorba"),
                        key="choose21",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose22 = st.radio("------------------------------------- " + "22" + "-------------------------------------",
                        ("Disiplinsiz", "Sevimsiz", "Donuk", "Affetmez"),
                        key="choose22",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose23 = st.radio("------------------------------------- " + "23" + "-------------------------------------",
                        ("Ketum", "Kinci", "Dayanıksız", "Tekrarlayan"),
                        key="choose23",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose24 = st.radio("------------------------------------- " + "24" + "-------------------------------------",
                        ("Titiz", "Korkak", "Unutkan", "Açıksözlü"),
                        key="choose24",
                        horizontal=True)
    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose25 = st.radio("------------------------------------- " + "25" + "-------------------------------------",
                        ("Sabırsız", "Güvensiz", "Kararsız", "Laf kesici"),
                        key="choose25",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose26 = st.radio("------------------------------------- " + "26" + "-------------------------------------",
                        ("Sevilmeyen", "İşe karışmayan", "Ne yapacağı belirsiz", "Şefkatsiz"),
                        key="choose26",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose27 = st.radio("------------------------------------- " + "27" + "-------------------------------------",
                        ("Dik kafalı", "Gelişigüzel", "Zor beğenen", "Tereddütlü"),
                        key="choose27",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose28 = st.radio("------------------------------------- " + "28" + "-------------------------------------",
                        ("Sade", "Karamsar", "Kibirli", "Toleranslı"),
                        key="choose28",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose29 = st.radio("------------------------------------- " + "29" + " -------------------------------------",
                        ("Kolay sinirlenir", "Amaçsız", "Tartışmacı", "Soğuk"),
                        key="choose29",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose30 = st.radio("------------------------------------- " + "30" + " -------------------------------------",
                        ("Saf", "Olumsuz tavırlı", "Sinirli", "Kayıtsız"),
                        key="choose30",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose31 = st.radio("------------------------------------- " + "31" + " -------------------------------------",
                        ("Kaygılanan", "İçine Kapanık", "İşkolik", "Tanınmak isteyen"),
                        key="choose31",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose32 = st.radio("------------------------------------- " + "32" + " -------------------------------------",
                        ("Çok hassas", "Kaba", "Ürkek", "Çok konuşan"),
                        key="choose32",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose33 = st.radio("------------------------------------- " + "33" + " -------------------------------------",
                        ("Kuşkulu", "Organize olmamış", "Otoriter", "Kederli"),
                        key="choose33",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose34 = st.radio("------------------------------------- " + "34" + " -------------------------------------",
                        ("Tutarsız", "İçe dönük", "Hoşgörüsüz", "Sıradan"),
                        key="choose34",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose35 = st.radio("------------------------------------- " + "35" + " -------------------------------------",
                        ("Dağınık", "Huysuz", "Ağzında kelimeleri yuvarlayan", "İnsan kullanan"),
                        key="choose35",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose36 = st.radio("------------------------------------- " + "36" + " -------------------------------------",
                        ("Uyuşuk", "İnatçı", "Hava atan", "Kuşkucu"),
                        key="choose36",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose37 = st.radio("------------------------------------- " + "37" + " -------------------------------------",
                        ("Yalnız", "Denetleyici", "Tembel", "Gürültücü"),
                        key="choose37",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose38 = st.radio("------------------------------------- " + "38" + " -------------------------------------",
                        ("Miskin", "Şüpheci", "Çabuk öfkelenen", "Dikkatsiz"),
                        key="choose38",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose39 = st.radio("------------------------------------- " + "39" + " -------------------------------------",
                        ("İntikamcı", "Patavatsız", "İsteksiz", "Kötü dinleyici"),
                        key="choose39",
                        horizontal=True)

    col1, col2, col3 = st.columns([1, 3, 1])
    with col2:
        choose40 = st.radio("------------------------------------- " + "40" + " -------------------------------------",
                        ("Uzlaşmacı", "Eleştirici", "Kurnaz", "Çabuk sıkılan"),
                        key="choose40",
                        horizontal=True)

    if choose1 == "Hareketli":
        sari += 1
    elif choose1 == "Sonuç odaklı":
        kirmizi += 1
    elif choose1 == "Analitik":
        mavi += 1
    else:
        yesil += 1

    if choose2 == "Neşeli":
        sari += 1
    elif choose2 == "İkna Edici":
        kirmizi += 1
    elif choose2 == "Mantıklı":
        mavi += 1
    else:
        yesil += 1

    if choose3 == "Sosyal":
        sari += 1
    elif choose3 == "İradeli":
        kirmizi += 1
    elif choose3 == "Uysal":
        mavi += 1
    else:
        yesil += 1

    if choose4 == "İnandırıcı":
        sari += 1
    elif choose4 == "Yarışçıl":
        kirmizi += 1
    elif choose4 == "İnsaflı":
        mavi += 1
    else:
        yesil += 1

    if choose5 == "Ferahlatıcı":
        sari += 1
    elif choose5 == "Becerikli":
        kirmizi += 1
    elif choose5 == "Saygılı":
        mavi += 1
    else:
        yesil += 1

    if choose6 == "Cesur":
        sari += 1
    elif choose6 == "Kendine güvenen":
        kirmizi += 1
    elif choose6 == "Duyarlı":
        mavi += 1
    else:
        yesil += 1

    if choose7 == "Teşvik edici":
        sari += 1
    elif choose7 == "Olumlu":
        kirmizi += 1
    elif choose7 == "Planlı":
        mavi += 1
    else:
        yesil += 1

    if choose8 == "Kendiliğinden":
        sari += 1
    elif choose8 == "Emin":
        kirmizi += 1
    elif choose8 == "Programa bağlı":
        mavi += 1
    else:
        yesil += 1

    if choose9 == "İyimser":
        sari += 1
    elif choose9 == "Dobra":
        kirmizi += 1
    elif choose9 == "Düzenli":
        mavi += 1
    else:
        yesil += 1

    if choose10 == "Komik":
        sari += 1
    elif choose10 == "Baskıcı":
        kirmizi += 1
    elif choose10 == "Sadık":
        mavi += 1
    else:
        yesil += 1

    if choose11 == "Hoş":
        sari += 1
    elif choose11 == "Cesaretli":
        kirmizi += 1
    elif choose11 == "Detaycı":
        mavi += 1
    else:
        yesil += 1

    if choose12 == "Esin kaynağı":
        sari += 1
    elif choose12 == "Güvenli":
        kirmizi += 1
    elif choose12 == "Kültürlü":
        mavi += 1
    else:
        yesil += 1

    if choose13 == "Heyecanlandırıcı":
        sari += 1
    elif choose13 == "Bağımsız":
        kirmizi += 1
    elif choose13 == "İdealist":
        mavi += 1
    else:
        yesil += 1

    if choose14 == "Coşkun":
        sari += 1
    elif choose14 == "Kesin":
        kirmizi += 1
    elif choose14 == "Derin düşünceli":
        mavi += 1

    if choose15 == "Kolay Kaynaşır":
        sari += 1
    elif choose15 == "Harekete geçiren":
        kirmizi += 1
    elif choose15 == "Ahenkli":
        mavi += 1
    else:
        yesil += 1

    if choose16 == "Konuşma yanlısı":
        sari += 1
    elif choose16 == "İş Bitirici":
        kirmizi += 1
    elif choose16 == "İnce düşünceli":
        mavi += 1
    else:
        yesil += 1

    if choose17 == "Canlı":
        sari += 1
    elif choose17 == "Lider":
        kirmizi += 1
    elif choose17 == "Samimi":
        mavi += 1
    else:
        yesil += 1

    if choose18 == "Şirin":
        sari += 1
    elif choose18 == "Başkan, Şef":
        kirmizi += 1
    elif choose18 == "Araştırmacı":
        mavi += 1
    else:
        yesil += 1

    if choose19 == "Popüler":
        sari += 1
    elif choose19 == "Üretici":
        kirmizi += 1
    elif choose19 == "Mükemmeliyetçi":
        mavi += 1
    else:
        yesil += 1

    if choose20 == "Cömert":
        sari += 1
    elif choose20 == "Atılgan":
        kirmizi += 1
    elif choose20 == "Terbiyeli":
        mavi += 1
    else:
        yesil += 1

    if choose21 == "Utanması olmayan":
        sari += 1
    elif choose21 == "Zorba":
        kirmizi += 1
    elif choose21 == "Çekingen":
        mavi += 1
    else:
        yesil += 1

    if choose22 == "Disiplinsiz":
        sari += 1
    elif choose22 == "Sevimsiz":
        kirmizi += 1
    elif choose22 == "Affetmez":
        mavi += 1
    else:
        yesil += 1

    if choose23 == "Tekrarlayan":
        sari += 1
    elif choose23 == "Dayanıksız":
        kirmizi += 1
    elif choose23 == "Kinci":
        mavi += 1
    else:
        yesil += 1

    if choose24 == "Unutkan":
        sari += 1
    elif choose24 == "Açıksözlü":
        kirmizi += 1
    elif choose24 == "Titiz":
        mavi += 1
    else:
        yesil += 1

    if choose25 == "Laf kesici":
        sari += 1
    elif choose25 == "Sabırsız":
        kirmizi += 1
    elif choose25 == "Güvensiz":
        mavi += 1
    else:
        yesil += 1

    if choose26 == "Ne yapacağı belirsiz":
        sari += 1
    elif choose26 == "Şefkatsiz":
        kirmizi += 1
    elif choose26 == "Sevilmeyen":
        mavi += 1
    else:
        yesil += 1

    if choose27 == "Gelişigüzel":
        sari += 1
    elif choose27 == "Dik kafalı":
        kirmizi += 1
    elif choose27 == "Zor beğenen":
        mavi += 1
    else:
        yesil += 1

    if choose28 == "Toleranslı":
        sari += 1
    elif choose28 == "Kibirli":
        kirmizi += 1
    elif choose28 == "Karamsar":
        mavi += 1
    else:
        yesil += 1

    if choose29 == "Kolay sinirlenir":
        sari += 1
    elif choose29 == "Tartışmacı":
        kirmizi += 1
    elif choose29 == "Soğuk":
        mavi += 1
    else:
        yesil += 1

    if choose30 == "Saf":
        sari += 1
    elif choose30 == "Sinirli":
        kirmizi += 1
    elif choose30 == "Olumsuz tavırlı":
        mavi += 1
    else:
        yesil += 1

    if choose31 == "Tanınmak isteyen":
        sari += 1
    elif choose31 == "İşkolik":
        kirmizi += 1
    elif choose31 == "İçine kapanık":
        mavi += 1
    else:
        yesil += 1

    if choose32 == "Çok konuşan":
        sari += 1
    elif choose32 == "Kaba":
        kirmizi += 1
    elif choose32 == "Çok hassas":
        mavi += 1
    else:
        yesil += 1

    if choose33 == "Organize olmamış":
        sari += 1
    elif choose33 == "Otoriter":
        kirmizi += 1
    elif choose33 == "Kederli":
        mavi += 1
    else:
        yesil += 1

    if choose34 == "Tutarsız":
        sari += 1
    elif choose34 == "Hoşgörüsüz":
        kirmizi += 1
    elif choose34 == "İçe dönük":
        mavi += 1
    else:
        yesil += 1

    if choose35 == "İnsan kullanan":
        sari += 1
    elif choose35 == "Dağınık":
        kirmizi += 1
    elif choose35 == "Huysuz":
        mavi += 1
    else:
        yesil += 1

    if choose36 == "Hava atan":
        sari += 1
    elif choose36 == "İnatçı":
        kirmizi += 1
    elif choose36 == "Kuşkucu":
        mavi += 1
    else:
        yesil += 1

    if choose37 == "Gürültücü":
        sari += 1
    elif choose37 == "Denetleyici":
        kirmizi += 1
    elif choose37 == "Yalnız":
        mavi += 1
    else:
        yesil += 1

    if choose38 == "Dikkatsiz":
        sari += 1
    elif choose38 == "Çabuk öfkelenen":
        kirmizi += 1
    elif choose38 == "Şüpheci":
        mavi += 1
    else:
        yesil += 1

    if choose39 == "Kötü dinleyici":
        sari += 1
    elif choose39 == "Patavatsız":
        kirmizi += 1
    elif choose39 == "İntikamcı":
        mavi += 1
    else:
        yesil += 1

    if choose40 == "Çabuk sıkılan":
        sari += 1
    elif choose40 == "Kurnaz":
        kirmizi += 1
    elif choose40 == "Eleştirici":
        mavi += 1
    else:
        yesil += 1

    return mavi, sari, kirmizi, yesil

def save_file(file_name):
    gauth = GoogleAuth()
    create_cred_file()
    #gauth.LoadCredentialsFile(st.secrets("my_creds"))
    #if gauth.credentials is None:
    #    # Authenticate if they're not there
    #    gauth.LocalWebserverAuth()
    #elif gauth.access_token_expired:
    #    # Refresh them if expired
    #    gauth.Refresh()
    #else:
    #    # Initialize the saved creds
    #    gauth.Authorize()
    # Save the current credentials to a file
    gauth.LoadCredentialsFile('mycreds_test.txt')

    drive = GoogleDrive(gauth)
    folderName = 'Renk Testi'  # Please set the folder name.

    folders = drive.ListFile(
        {
            'q': "title='" + folderName + "' and mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList()
    for folder in folders:
        if folder['title'] == folderName:
            file2 = drive.CreateFile({'parents': [{'id': folder['id']}]})
            file2.SetContentFile(file_name)
            file2.Upload()

def create_cred_file():
    cred_str = '{"access_token": "' + st.secrets["access_token"] +\
               '", "client_id": "' + st.secrets["client_id"] +\
               '", "client_secret": "' + st.secrets["client_secret"] + \
               '", "refresh_token": "' + st.secrets["refresh_token"] + \
               '", "token_expiry": "' + st.secrets["token_expiry"] + \
               '", "token_uri": "' + st.secrets["token_uri"] + \
               '", "user_agent": null' + \
               ', "revoke_uri": "' + st.secrets["revoke_uri"] + \
               '", "id_token": null' + \
               ', "id_token_jwt": null' + \
               ', "token_response": {"access_token": "' + st.secrets["token_response"]["access_token"] + \
               '", "expires_in": ' + str(st.secrets["token_response"]["expires_in"]) + \
               ', "refresh_token": "' + st.secrets["token_response"]["refresh_token"] + \
               '", "scope": "' + st.secrets["token_response"]["scope"] + \
               '", "token_type": "' + st.secrets["token_response"]["token_type"] + \
               '"}, "scopes": ["https://www.googleapis.com/auth/drive"]' + \
               ', "token_info_uri": "' + st.secrets["token_info_uri"] + \
               '", "invalid": false' + \
               ', "_class": "' + st.secrets["_class"] + \
               '", "_module": "' + st.secrets["_module"] + '"}'
    text_file = open("mycreds_test.txt", "w")
    n = text_file.write(cred_str)
    text_file.close()

def version():
    st.caption("""

                ver 1.0.0
build 03052023.2307

            """, unsafe_allow_html=True
               )


import numpy as np
from keras.models import load_model
from keras.preprocessing import image
import tensorflow as tf
class flowertype:
    def __init__(self,filename):
        self.filename =filename

    def predictionflower(self):
        # load model
        # model = load_model('model.h5')
        model=tf.keras.models.load_model(r'C:\Users\DELL\Documents\CNN\CustomImageClassification\flowerRecognition\model.h5')

        # summarize model
        #model.summary()
        imagename = self.filename
        test_image = image.load_img(imagename, target_size = (128,128))
        test_image = image.img_to_array(test_image)
        test_image = np.expand_dims(test_image, axis = 0)
        result = model.predict(test_image)
        # print(result[0][4],result)
        # return result
        if result[0][0] == 1:
            prediction = 'daisy'
            return [prediction]
        elif result[0][1] == 1:
            prediction = 'dandelion'
            return [prediction]
        elif result[0][2] == 1:
            prediction = 'rose'
            return [prediction]
        elif result[0][3] == 1:
            prediction = 'sunflower'
            return [prediction]
        else:
            prediction = 'tulip'
            return [prediction]

# filename = r"C:\Users\DELL\Documents\CNN\CustomImageClassification\flowerRecognition\tulip.jpg"
# classifier = flowertype(filename)
# # print(classifier)
# print(classifier.predictionflower())


import os
import torch
from lib.dataset.landsat_8_dataloader import Get_dataloader
from lib.model.create_generator import create_generator
from lib.model.generator.ms_net import MS_Net
from lib.model.generator.msa_net import MSA_Net
from lib.model.generator.rsc_net import RSC_Net
from lib.model.generator.ssa_net import SSA_Net
from lib.utils.config import Config
from lib.utils.parse_args import parse_args
from rm_cloud.single_model_methods.tester import Testner

def eval():
    config = Config().parse()
    args = parse_args(config)
    print(args)
    train_loader, test_loader = Get_dataloader(args)
    os.environ['CUDA_VISIBLE_DEVICES'] = args.devices

    if args.model.arch == 'rsc':
        model = RSC_Net()
    if args.model.arch == 'msa':
        model = MSA_Net()
    if args.model.arch == 'ssa':
        model = SSA_Net()

    if args.model.arch == 'ms':
        model = MS_Net()

    if args.model.arch == 'msa_':
        model = MSA_Net()
    all_eval_dir = '/home/data1/xiesong/git_repo/removal_thin_cloud/experiments/'+ args.model.arch + '/every_model/'

    list_checkpoint = os.listdir(args.checkpoint_dir)
    for checkpoint in list_checkpoint:
        if int(checkpoint.split('-')[0]) > 3018:
            checkpoint_path = os.path.join(args.checkpoint_dir + checkpoint)
            args.evaluation_dir = os.path.join(all_eval_dir + checkpoint.split('-')[0] + '/')
            os.makedirs(args.evaluation_dir,exist_ok=True)
            print(args.evaluation_dir)
            c_model = create_generator(args, model)

            c_model.load_state_dict(torch.load(checkpoint_path))
            test_model = Testner(c_model)
            test_model .test(args,test_loader)
            test_model.eval(args)

if __name__ == '__main__':

    eval()


import psycopg2
from psycopg2.extensions import adapt
import logging
import os
import time
import math

logging.basicConfig(level=logging.INFO)

def setup_supabase(vector_name:str, verbose:bool=False):
    hello = f"Setting up supabase database: {vector_name}"
    logging.debug(hello)
    if verbose:
        print(hello)
    setup_database(vector_name, verbose)

def setup_cloudsql(vector_name:str, verbose:bool=False):
    hello = f"Setting up cloudsql database: {vector_name}"
    logging.debug(hello)
    if verbose:
        print(hello)
    setup_database(vector_name, verbose)

def lookup_connection_env(vector_name:str):
    from utils.config import load_config_key

    vs_str = load_config_key("vectorstore", vector_name)
    if vs_str == "supabase":
        return "DB_CONNECTION_STRING"
    elif vs_str == "cloudsql":
        return "PGVECTOR_CONNECTION_STRING"

    raise ValueError("Could not find vectorstore for {vs_str}")

def get_vector_size(vector_name: str):
    from qna.llm import load_config_key
    llm_str = load_config_key("llm", vector_name)

    vector_size = 768
    if llm_str == 'openai':
        vector_size = 1536 # openai

    logging.debug(f'vector size: {vector_size}')
    return vector_size

def setup_database(vector_name:str, verbose:bool=False):

    connection_env = lookup_connection_env(vector_name)

    params = {'vector_name': vector_name, 'vector_size': get_vector_size(vector_name)}

    execute_sql_from_file("sql/sb/setup.sql", params, verbose=verbose, connection_env=connection_env)
    execute_sql_from_file("sql/sb/create_table.sql", params, verbose=verbose, connection_env=connection_env)
    execute_sql_from_file("sql/sb/create_function.sql", params, verbose=verbose, connection_env=connection_env)

    if verbose: print("Ran all setup SQL statements")

    return True

def return_sources_last24(vector_name:str):
    params = {'vector_name': vector_name, 'time_period':'1 day'}
    return execute_sql_from_file("sql/sb/return_sources.sql", params, return_rows=True,
                                 connection_env=lookup_connection_env(vector_name))

def delete_row_from_source(source: str, vector_name:str):
    # adapt the user input and decode from bytes to string to protect against sql injection
    source = adapt(source).getquoted().decode()
    sql_params = {'source_delete': source}
    sql = f"""
        DELETE FROM {vector_name}
        WHERE metadata->>'source' = %(source_delete)s
    """

    do_sql(sql, sql_params=sql_params, connection_env=lookup_connection_env(vector_name))

def do_sql(sql, sql_params=None, return_rows=False, verbose=False, connection_env='DB_CONNECTION_STRING', max_retries=5):

    if connection_env is None:
        raise ValueError("Need to specify connection_env to connect to DB")

    rows = []
    connection_string = os.getenv(connection_env, None)
    if connection_string is None:
        raise ValueError("No connection string")

    for attempt in range(max_retries):
        try:
            connection = psycopg2.connect(connection_string)
            cursor = connection.cursor()

            if verbose:
                logging.info(f"SQL: {sql}")
            else:
                pass
            # execute the SQL - raise the error if already found
            cursor.execute(sql, sql_params)

            # commit the transaction to save changes to the database
            connection.commit()

            if return_rows:
                rows = cursor.fetchall()
            logging.debug("SQL successfully fetched")
            break  # If all operations were successful, break the loop

        except (psycopg2.errors.DuplicateObject,
                psycopg2.errors.DuplicateTable,
                psycopg2.errors.DuplicateFunction) as e:
            logging.debug(str(e))
            if verbose:
                print(str(e))
            continue

        except psycopg2.errors.InternalError as error:
            logging.error(f"InternalError, retrying... Attempt {attempt+1} out of {max_retries}")
            time.sleep(math.pow(2, attempt))  # Exponential backoff
            continue  # Go to the next iteration of the loop to retry the operation

        except (Exception, psycopg2.Error) as error:
            logging.error(f"Error while connecting to PostgreSQL: {str(error)}", exc_info=True)
            continue

        finally:
            if connection:
                cursor.close()
                connection.close()
                logging.debug("PostgreSQL connection is closed")

        # If we've exhausted all retries and still haven't succeeded, raise an error
        if attempt + 1 == max_retries:
            raise Exception("Maximum number of retries exceeded")

    if rows:
        return rows

    return None

def execute_sql_from_file(filepath, params, return_rows=False, verbose=False, connection_env=None):

     # Get the directory of this Python script
    dir_path = os.path.dirname(os.path.realpath(__file__))
    # Build the full filepath by joining the directory with the filename
    filepath = os.path.join(dir_path, filepath)

    # read the SQL file
    with open(filepath, 'r') as file:
        sql = file.read()

    # substitute placeholders in the SQL
    sql = sql.format(**params)
    rows = do_sql(sql, return_rows=return_rows, verbose=verbose, connection_env=connection_env)

    if return_rows:
        if rows is None: return None
        return rows

    return True

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(description="Setup a database",
                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("vectorname", help="The namespace for vectorstore")
    parser.add_argument("connection_env", help="The connection environment string", default="DB_CONNECTION_STRING")

    args = parser.parse_args()
    config = vars(args)

    vector_name = config.get('vectorname', None)
    if vector_name is None:
        raise ValueError("Must provide a vectorname")

    setup_database(vector_name, verbose=True, connection_env=config.get("connection_env"))


import matplotlib.pyplot as plt
import itertools
import pandas as pd
import re
from scipy.stats import chi2_contingency
from statsmodels.sandbox.stats.multicomp import multipletests
plt.rcParams["font.family"] = "Lucida Sans Unicode"

class ProtocolData:
    def __init__(self, text, datetime_date):
        self.date = datetime_date
        self.member_affiliations = {}
        self.text = text
        self.interjection_locations = {}

        self.protocol_segments = []

        # Bit tricky
        self.words_preceding_interjections = {}

    def add_member(self, name, party):
        self.member_affiliations[name] = party

    def append_protocol_segment(self, segment):
        self.protocol_segments.append(segment)

    def count_word_preceding_interjection(self, word):
        self.words_preceding_interjections[word] = self.words_preceding_interjections.get(word, 0) + 1

    def print_data(self):
        print(self.date)
        print(self.member_affiliations)
        print(self.text)
        print(self.interjection_locations)
        print(self.words_preceding_interjections)
        print(len(self.interjection_locations))

    def print_data_graph(self):
        #drawnDict = dict(reversed(sorted(self.words_preceding_interjections.items(), key=lambda item: item[1])))
        #drawnDict = {k: v for k, v in drawnDict.items() if len(k) > 4 or k.isupper()}
        #drawnDict = dict(itertools.islice(drawnDict.items(), 15))
        #prediction = self.model.predict_output_word(['COMMENT'], topn = 20)

        #Pattern: Word, comment occurences, no comment occurences
        frequency_data = [(key, value, self.total_searched_words[key] - value) for (key, value) in self.most_frequent_words_near_search_words.items() if self.total_searched_words[key] > 3]
        df = pd.DataFrame(frequency_data, columns=["word", "comments", "no_comments"])
        df = df.set_index("word")
        significant_words = chisq_and_posthoc_corrected(df)
        significance_filtered_words = [(key, value) for (key, value) in self.most_frequent_words_near_search_words.items() if key in significant_words]
        relative_frequency_filtered_words = [(key, value / self.total_searched_words[key]) for (key, value) in significance_filtered_words if self.total_searched_words[key] > 3]
        #prediction = list(itertools.islice(self.most_frequent_words_near_search_words.items(), 20))
        prediction = sorted(relative_frequency_filtered_words[:20], key=lambda x: x[1], reverse=False)
        plt.barh([t[0] for t in prediction], [t[1] for t in prediction])
        #axes = plt.gca()
        #axes.set_ylim([0.011363, 0.011366])
        plt.show()

    def plot_significant_words(self):
        frequency_data = [(key, value, self.total_searched_words[key] - value) for (key, value) in self.most_frequent_words_near_search_words.items()]
        df = pd.DataFrame(frequency_data, columns=["word", "comments", "no_comments"])
        df = df.set_index("word")
        significant_words = chisq_and_posthoc_corrected(df)
        significance_filtered_words = [(key, value) for (key, value) in self.most_frequent_words_near_search_words.items() if key in significant_words if self.total_searched_words[key] > 3]
        relative_frequency_filtered_words = [(key, value / self.total_searched_words[key]) for (key, value) in significance_filtered_words]
        prediction = sorted(relative_frequency_filtered_words[:20], key=lambda x: x[1], reverse=False)
        plt.barh([t[0] for t in prediction], [t[1] for t in prediction])
        plt.show()

    def plot_word_count(self, search_pattern):
        pattern = re.compile(search_pattern)
        plotted_words = []
        for word, count in self.total_searched_words.items():
            if pattern.search(word):
                plotted_words.append([word, count])
        plt.barh([t[0] for t in plotted_words], [t[1] for t in plotted_words])
        plt.show()

    def get_full_text(self):
        full_text = ""
        for segment in self.protocol_segments:
            full_text += segment.get_text_equivalent()
        return full_text

def get_asterisks_for_pval(p_val):
    """Receives the p-value and returns asterisks string."""
    if p_val > 0.05:
        p_text = "ns"  # above threshold => not significant
    elif p_val < 1e-4:
        p_text = '****'
    elif p_val < 1e-3:
        p_text = '***'
    elif p_val < 1e-2:
        p_text = '**'
    else:
        p_text = '*'

    return p_text

# https://neuhofmo.github.io/chi-square-and-post-hoc-in-python/
def chisq_and_posthoc_corrected(df):
    """Receives a dataframe and performs chi2 test and then post hoc.
    Prints the p-values and corrected p-values (after FDR correction)"""
    # start by running chi2 test on the matrix
    chi2, p, dof, ex = chi2_contingency(df, correction=True)
    print(f"Chi2 result of the contingency table: {chi2}, p-value: {p}")

    avg_comments = df["comments"].mean()
    avg_no_comments = df["no_comments"].mean()
    # Any random occurence word, interjection afterwards?
    df.loc["AVERAGE_WORD"] = [avg_comments, avg_no_comments]
    print(df)

    #Bonferroni correction
    # post-hoc
    #all_combinations = list(itertools.com(df.index, 2))  # gathering all combinations for post-hoc chi2
    all_combinations = [(index, "AVERAGE_WORD") for index in df.index]
    p_vals = []
    print("Significance results:")
    for comb in all_combinations:
        new_df = df[(df.index == comb[0]) | (df.index == comb[1])]
        chi2, p, dof, ex = chi2_contingency(new_df, correction=True)
        p_vals.append(p)
        # print(f"For {comb}: {p}")  # uncorrected

    # checking significance
    # correction for multiple testing
    reject_list, corrected_p_vals = multipletests(p_vals, method='fdr_bh', alpha=0.05)[:2]
    for p_val, corr_p_val, reject, comb in zip(p_vals, corrected_p_vals, reject_list, all_combinations):
        print(f"{comb}: p_value: {p_val:5f}; corrected: {corr_p_val:5f} ({get_asterisks_for_pval(p_val)}) reject: {reject}")

    result = [comb[0] for p_val, corr_p_val, reject, comb in zip(p_vals, corrected_p_vals, reject_list, all_combinations) if reject]
    return result


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import annotations
from typing import Dict, Optional
import os
import numpy as np
import torch
import torch.nn as nn
from transformers import BertConfig, BertForSequenceClassification
from .DeepLearning import ConfigDeepLearning

DEFAULT_RANDOM_STATE = None

class ConfigBertClassification(ConfigDeepLearning):
    bert_classification_params = [
        # name, vtype, is_require, default
        ('nict_bert_dir', str, True, None),
        ('num_class', int, True, None),
        ('unique_categories', [list, str], True, None),
        ('random_state', int, False, DEFAULT_RANDOM_STATE),
    ]

    def __init__(
        self: ConfigBertClassification,
        config: Dict,
        config_model_json: str
    ) -> None:
        # model_name
        config['model_name'] = 'BertClassification'
        # load json
        self._load_one(config, config_model_json)
        # init parent class
        self._init_deeplearning(config)
        # set parameters
        for param in self.deeplearning_params:
            self._init_param(config, *param)
        for param in self.bert_classification_params:
            self._init_param(config, *param)
        # value_assertion
        assert(os.path.exists(self.nict_bert_dir))
        return

    def load(self: ConfigBertClassification) -> None:
        return

    def save(self: ConfigBertClassification) -> None:
        return

class BertClassification(nn.Module):
    def __init__(
        self: BertClassification,
        config: Dict,
        config_model_json: str
    ) -> None:
        super().__init__()
        self.config = ConfigBertClassification(config, config_model_json)
        # set random seed
        if self.config.random_state is not None:
            np.random.seed(self.config.random_state)
            torch.manual_seed(self.config.random_state)
            if torch.cuda.is_available():
                torch.cuda.manual_seed(self.config.random_state)
        # load BertForSequenceClassification of NICT BERT
        bert_config = BertConfig.from_pretrained(
            os.path.join(self.config.nict_bert_dir, 'config.json')
        )
        id2label = {i: x for i, x in enumerate(self.config.unique_categories)}
        label2id = {x: i for i, x in enumerate(self.config.unique_categories)}
        bert_config.update({'num_labels': self.config.num_class})
        bert_config.update({'id2label': id2label, 'label2id': label2id})
        if torch.cuda.is_available():
            map_location = torch.device('cuda')
        else:
            map_location = torch.device('cpu')
        state_dict = torch.load(
            os.path.join(self.config.nict_bert_dir, 'pytorch_model.bin'),
            map_location=map_location
        )
        self.model = BertForSequenceClassification.from_pretrained(
            None,
            config=bert_config,
            state_dict=state_dict,
            from_tf=False
        )
        # disable training (changing its weights) of all bert layers
        for name, param in self.model.bert.named_parameters():
            param.requires_grad_(False)
        return

    def forward(
        self: BertClassification,
        input_ids: torch.Tensor,
        attention_mask: torch.Tensor,
        token_type_ids: torch.Tensor,
        labels: torch.Tensor
    ) -> torch.Tensor:
        return self.model.forward(
            input_ids=input_ids,
            attention_mask=attention_mask,
            token_type_ids=token_type_ids,
            labels=labels
        )

    def load(self: BertClassification) -> None:
        bert_config = BertConfig.from_pretrained(
            self.config.config_json
        )
        if torch.cuda.is_available():
            map_location = torch.device('cuda')
        else:
            map_location = torch.device('cpu')
        state_dict = torch.load(
            self.config.binary_path, map_location=map_location
        )
        self.model = BertForSequenceClassification.from_pretrained(
            None,
            config=bert_config,
            state_dict=state_dict,
            from_tf=False
        )
        # disable training (changing its weights) of all bert layers
        for name, param in self.model.bert.named_parameters():
            param.requires_grad_(False)
        return

    def save(self: BertClassification) -> None:
        self.model.save_pretrained(self.config.base_dir)
        return

    def train(self: BertClassification, mode: Optional[bool] = True) -> None:
        self.model.train(mode)
        return

    def eval(self: BertClassification) -> None:
        self.model.eval()
        return


from __future__ import print_function
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms

import numpy as np
import torch.utils.data as utils

#for checking summary of model
from torchvision import models
from torchsummary import summary

#for plotting
import matplotlib.pyplot as plt

# The parts that you should complete are designated as TODO
class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        # TODO: define the layers of the network
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, stride=1, padding=0)
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=0)
        self.relu = nn.ReLU()
        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
        self.dropout = nn.Dropout2d(p=0.25)
        self.flatten = nn.Flatten()
        self.linear1 = nn.Linear(9216, 128)
        self.dropout2 = nn.Dropout(p=0.5)
        self.linear2 = nn.Linear(128,10)

    def forward(self, x):
        # TODO: define the forward pass of the network using the layers you defined in constructor
        x = self.conv1(x)
        x = self.relu(x)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.pool1(x)
        x = self.dropout(x)
        x = self.flatten(x)
        x = self.linear1(x)
        x = self.relu(x)
        x = self.dropout2(x)
        x = self.linear2(x)

        return x

def train(model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = F.cross_entropy(output, target)
        loss.backward()
        optimizer.step()
        #accuracy = 100. * batch_idx / len(train_loader)
        if batch_idx % 100 == 0: #Print loss every 100 batch
            print('Train Epoch: {} [{}/{}]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                loss.item()))
    print('-'*20)
    print('Training Accuracy (not test accuracy):')
    accuracy = test(model, device, train_loader)
    print('-'*20)

    return accuracy

def test(model, device, test_loader):
    model.eval()
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
            correct += pred.eq(target.view_as(pred)).sum().item()

    accuracy = 100. * correct / len(test_loader.dataset)
    print('\nTest set Accuracy: {}/{} ({:.0f}%)\n'.format(
        correct, len(test_loader.dataset),
        accuracy))
    print('-'*20)

    return accuracy

def main():
    print('-'*20)
    print('Start of CNN Script')
    torch.manual_seed(1)
    np.random.seed(1)
    # Training settings
    use_cuda = False # Switch to False if you only want to use your CPU
    learning_rate = 0.01
    NumEpochs = 10
    batch_size = 32

    device = torch.device("cuda" if use_cuda else "cpu")

    train_X = np.load('../../Data/X_train.npy')
    train_Y = np.load('../../Data/y_train.npy')

    test_X = np.load('../../Data/X_test.npy')
    test_Y = np.load('../../Data/y_test.npy')

    train_X = train_X.reshape([-1,1,28,28]) # the data is flatten so we reshape it here to get to the original dimensions of images
    test_X = test_X.reshape([-1,1,28,28])

    # transform to torch tensors
    tensor_x = torch.tensor(train_X, device=device)
    tensor_y = torch.tensor(train_Y, dtype=torch.long, device=device)

    test_tensor_x = torch.tensor(test_X, device=device)
    test_tensor_y = torch.tensor(test_Y, dtype=torch.long)

    train_dataset = utils.TensorDataset(tensor_x,tensor_y) # create your datset
    train_loader = utils.DataLoader(train_dataset, batch_size=batch_size) # create your dataloader

    test_dataset = utils.TensorDataset(test_tensor_x,test_tensor_y) # create your datset
    test_loader = utils.DataLoader(test_dataset) # create your dataloader if you get a error when loading test data you can set a batch_size here as well like train_dataloader

    model = ConvNet().to(device)
    #print a summary of layer dimensions and parameters
    print('Model Summary:')
    summary(model, input_size=(1,28,28))
    optimizer = optim.Adam(model.parameters(), lr=learning_rate)

    #create lists to store training and testing accuracy for plotting
    training_accuracy = []
    testing_accuracy = []

    for epoch in range(NumEpochs):
        train_acc = train(model, device, train_loader, optimizer, epoch)
        #append training accuracy list
        training_accuracy.append(train_acc)
        test_acc = test(model, device, test_loader)
        #append testing accuracy list
        testing_accuracy.append(test_acc)

    torch.save(model.state_dict(), "mnist_cnn.pt")

    #TODO: Plot train and test accuracy vs epoch
    plt.plot(list(range(1,11)), training_accuracy, label='Training Accuracy')
    plt.plot(list(range(1,11)), testing_accuracy, label='Testing Accuracy')
    plt.title('Training and Testing Accuracy\nfor Each Epoch')
    plt.xlabel('Number of Epochs')
    plt.ylabel('Accuracy (%)')
    plt.legend()
    plt.savefig('../Figures/cnn_accuracy.png')
    plt.show()
    plt.clf()

    print('End of CNN Script')
    print('-'*20)
    print('End of HW5 Scripts')

if __name__ == '__main__':
    main()

#Below was used to generate the predictions for the submission folder
#select all and run selection if you would like to reproduce
#digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
#model.eval()
#correct = 0
#predictions_vect = []
#with torch.no_grad():
#    for data, target in test_loader:
#        data, target = data.to(device), target.to(device)
#        output = model(data)
#        pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
#        correct += pred.eq(target.view_as(pred)).sum().item()
#        _, predictions = torch.max(output, 1)
#        predictions_vect.append(digits[predictions])
#np.savetxt('../Predictions/predictions_MNIST.csv', predictions_vect, delimiter=',')