import pandas as pd

df=pd.read_csv("G:/Project NLP/qa_Electronics.csv")
list(df.columns)
df.shape
df.info()

##answer##
qes=df.iloc[:,4]
qes=pd.DataFrame(qes)
qes.size

qes["question"].isnull().sum() ##checking Null values
# dropping null value columns to avoid errors
qes.dropna(subset=['question'], inplace=True)

pd.value_counts(qes['question']).head()
print(df['question'].nunique())

qes.duplicated().sum() ###39368 duplicated rows in question columns
qes['question'][2]

##Cleaning The Data
import nltk
#nltk.download()
from nltk.tokenize import sent_tokenize, word_tokenize

# Apply a first round of text cleaning techniques
import re
import string

## Make text lowercase, remove text in square brackets,
## remove punctuation and remove words containing numbers.

def clean_text_round1(text):

    text = text.lower()
    text = re.sub('\[.*?\]', '', text)
    text = re.sub('[%s]' % re.escape(string.punctuation), '', text)
    text = re.sub('\w*\d\w*', '', text)
    return text

round1 = lambda x: clean_text_round1(x)

# Let's take a look at the updated text
data_clean = pd.DataFrame(qes.question.apply(round1))
data_clean

##Apply a second round of cleaning,Get rid of some additional punctuation
##non-sensical text that was missed the first time around
def clean_text_round2(text):

    text = re.sub('[‘’“”…]', '', text)
    text = re.sub('\n', '', text)
    return text

round2 = lambda x: clean_text_round2(x)

# Let's take a look at the updated text
data_clean = pd.DataFrame(data_clean.question.apply(round2))
data_clean

pd.value_counts(data_clean['question']).head()
data_clean.duplicated().sum()##33944 duplicated rows in data_clean data
data=data_clean.drop_duplicates(['question'])

##Remove stop words
from nltk.corpus import stopwords
stop = stopwords.words('english')
stop_qes = data.question.apply(lambda x: " ".join(x for x in x.split() if x not in stop))
stop_qes.dtype

stop_words = pd.DataFrame(stop_qes)
stop_words.question.nunique()
stop_words.duplicated().sum() ###20697
stop_question = stop_words.drop_duplicates(['question'])
stop_question.question.head()

##Lemmatization
w_tokenizer = nltk.tokenize.WhitespaceTokenizer()
lemmatizer = nltk.stem.WordNetLemmatizer()
def lemmatize_text(text):
    return [lemmatizer.lemmatize(w,'v') for w in w_tokenizer.tokenize(str(text))]

lemm_question=stop_question.question.apply(lemmatize_text)
lemm_question.head(20)
lem_qes=pd.DataFrame(lemm_question)

##doing stemming part
from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
stem_qes = lem_qes.question.apply(lambda x: ' '.join([stemmer.stem(y) for y in x]))
stem_qes.dtype

ste_question = pd.DataFrame(stem_qes)
ste_question.question.nunique()
ste_question.duplicated().sum() ##2917
stem_question = ste_question.drop_duplicates(['question'])
stem_question["question"].head()

#Creating word Cloud
# Joinining all the reviews into single paragraph
import matplotlib.pyplot as plt
from wordcloud import WordCloud

cloud = " ".join(stem_question.question)

wordcloud= WordCloud(
                      background_color='black',
                      width=1800,
                      height=1400
                     ).generate(cloud)

plt.imshow(wordcloud)

##For positive world cloud
with open("G:/Assignments/Text Mining/Positive Words.txt","r") as pos:
  poswords = pos.read().split("\n")

stemqes=stem_question.question.tolist()###covertin data frame into list

qes_pos = ' '.join([w for w in stemqes if w in poswords])

wordcloud_pos = WordCloud(
                           background_color = 'black',
                           width =1800,
                           height =1400
                           ).generate(str(qes_pos))
plt.imshow(wordcloud_pos)

##For negative word cloud
with open("G:/Assignments/Text Mining/Negative Words.txt","r") as nos:
    negwords = nos.read().split("\n")

qes_neg =' '.join([w for w in stemqes if w in negwords])

wordcloud_neg = WordCloud(
                           background_color = 'black',
                           width =1800,
                           height =1400
                           ).generate(str(qes_neg))
plt.imshow(wordcloud_neg)

##N-Gram
corpus=stem_question["question"]
from sklearn.feature_extraction.text import CountVectorizer

def get_top_n_words(corpus, n=None):
    vec = CountVectorizer().fit(corpus)
    bag_of_words = vec.transform(corpus)
    sum_words = bag_of_words.sum(axis=0)
    words_freq = [(word, sum_words[0, idx]) for word, idx in
                   vec.vocabulary_.items()]
    words_freq =sorted(words_freq, key = lambda x: x[1],
                       reverse=True)
    return words_freq[:n]

#Convert most freq words to dataframe for plotting bar plot
top_words = get_top_n_words(corpus, n=25)
top_df = pd.DataFrame(top_words)
top_df.columns=["Word", "Freq"]
top_df.head(25)

#Barplot of most freq words
import seaborn as sns
sns.set(rc={'figure.figsize':(13,8)})
g = sns.barplot(x="Word", y="Freq", data=top_df)
g.set_xticklabels(g.get_xticklabels(), rotation=30)

#Most frequently occuring Bi-grams
def get_top_n2_words(corpus, n=None):
    vec1 = CountVectorizer(ngram_range=(2,2),
            max_features=2000).fit(corpus)
    bag_of_words = vec1.transform(corpus)
    sum_words = bag_of_words.sum(axis=0)
    words_freq = [(word, sum_words[0, idx]) for word, idx in
                  vec1.vocabulary_.items()]
    words_freq =sorted(words_freq, key = lambda x: x[1],
                reverse=True)
    return words_freq[:n]

#Convert most freq words to dataframe for plotting bar plot
top2_words = get_top_n2_words(corpus, n=20)
top2_df = pd.DataFrame(top2_words)
top2_df.columns=["Bi-gram", "Freq"]
print(top2_df)

#Barplot of most freq Bi-grams
import seaborn as sns
sns.set(rc={'figure.figsize':(13,8)})
h=sns.barplot(x="Bi-gram", y="Freq", data=top2_df)
h.set_xticklabels(h.get_xticklabels(), rotation=45)

#Most frequently occuring Tri-grams
def get_top_n3_words(corpus, n=None):
    vec1 = CountVectorizer(ngram_range=(3,3),
           max_features=2000).fit(corpus)
    bag_of_words = vec1.transform(corpus)
    sum_words = bag_of_words.sum(axis=0)
    words_freq = [(word, sum_words[0, idx]) for word, idx in
                  vec1.vocabulary_.items()]
    words_freq =sorted(words_freq, key = lambda x: x[1],
                reverse=True)
    return words_freq[:n]

#Convert most freq words to dataframe for plotting bar plot
top3_words = get_top_n3_words(corpus, n=20)
top3_df = pd.DataFrame(top3_words)
top3_df.columns=["Tri-gram", "Freq"]
print(top3_df)

#Barplot of most freq Tri-grams
import seaborn as sns
sns.set(rc={'figure.figsize':(13,8)})
j=sns.barplot(x="Tri-gram", y="Freq", data=top3_df)
j.set_xticklabels(j.get_xticklabels(), rotation=45)

##Named Entity Recognition with NLTK
import nltk
from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag

##Now we apply word tokenization and part-of-speech tagging to the sentence
corpus.question.dtype
corpus=pd.DataFrame(corpus)
def preprocess(sent):
    sent = nltk.word_tokenize(sent)
    sent = nltk.pos_tag(sent)
    return sent

##O/p we get a list of tuples containing the individual words in the
##sentence and their associated part-of-speech
sent = preprocess(str(corpus["question"]))
print(sent)

##Now we implement noun phrase chunking to identify named entities using
##a regular expression consisting of rules that indicate how sentences should be chunked
pattern = 'NP: {<DT>?<JJ>*<NN>}'

cp = nltk.RegexpParser(pattern)
cs = cp.parse(sent)
print(cs)

from nltk.chunk import conlltags2tree, tree2conlltags
from pprint import pprint
iob_tagged = tree2conlltags(cs)
pprint(iob_tagged)

##With the function nltk.ne_chunk(),
##we can recognize named entities using a classifier
ne_tree = nltk.ne_chunk(pos_tag(word_tokenize(str(corpus))))
print(ne_tree)


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn import linear_model
from sklearn.metrics import mean_squared_error
# import sys

# np.set_printoptions(threshold=sys.maxsize)
# https://archive.ics.uci.edu/dataset/183/communities+and+crime dataset
df = pd.read_csv('data/communities.data', names=['state', 'county', 'community', 'population', 'householdsize'],
                 usecols=[0, 1, 2, 4, 5], na_values='?', dtype=float)

ar = np.genfromtxt('data/communities.data', dtype=float, names=['state', 'county', 'community', 'population',
                                                                'householdsize'],
                   usecols=[0, 1, 2, 4, 5], missing_values='?', delimiter=',', filling_values=0)

def fill_df_na():
    df.fillna(0)
    for i in ['county', 'community', 'population', 'householdsize']:
        df[i].fillna(df[i].mean(), inplace=True)

def fill_ar_na():
    for i in ['county', 'community', 'population', 'householdsize']:
        n = 0
        mean = np.mean(ar[i][ar[i] != 0])
        for a in ar[i]:
            ar[i][n] = mean if a == 0. else a
            n += 1

def normalize_df():
    for i in ['county', 'community', 'population', 'householdsize']:
        mean = df[i].mean()
        std = df[i].std()
        for a in range(len(df[i])):
            df.at[a, i] = (df.at[a, i] - mean) / std

def normalize_ar():
    min_max_county = (np.std(ar['county']), np.mean(ar['county']))
    min_max_community = (np.std(ar['community']), np.mean(ar['community']))
    min_max_population = (np.std(ar['population']), np.mean(ar['population']))
    min_max_householdsize = (np.std(ar['householdsize']), np.mean(ar['householdsize']))
    n = 0
    for i in ar:
        ar[n][1] = (i[1] - min_max_county[1]) / min_max_county[0]
        ar[n][2] = (i[2] - min_max_community[1]) / min_max_community[0]
        ar[n][3] = (i[3] - min_max_population[1]) / min_max_population[0]
        ar[n][4] = (i[4] - min_max_householdsize[1]) / min_max_householdsize[0]
        n += 1

normalize_df()
normalize_ar()

def plotting_ar(atr, *args):
    for i in range(1, len(args) + 1):
        plt.subplot(2, 3, i % 5 if i % 5 != 0 else 5)
        plt.hist(ar[atr][args[i - 1][0]:args[i - 1][1]], label=f'{args[i - 1][0]} - {args[i - 1][1]}')
        plt.legend()
        plt.xlabel(atr.title())
    plt.tight_layout()
    # plt.show()

# plotting_ar('community', (10, 100), (100, 200), (200, 300), (300, 400), (400, 500), (500, 600), (600, 700), (700, 800),
#                          (800, 900), (900, 1000))

def plotting_df(atr, *args):
    for i in range(1, len(args) + 1):
        plt.subplot(2, 3, i % 5 if i % 5 != 0 else 5)
        plt.hist(df[atr][args[i - 1][0]:args[i - 1][1]], label=f'{args[i - 1][0]} - {args[i - 1][1]}')
        plt.legend()
        plt.xlabel(atr.title())
    plt.tight_layout()
    # plt.show()

# plotting_df('community', (10, 100), (100, 200), (200, 300), (300, 400), (400, 500), (500, 600), (600, 700), (700, 800),
#                          (800, 900), (900, 1000))

def cor_plot_df(atr_1, atr_2):
    sns.kdeplot(data=df, x=atr_1, hue=atr_2)
    # plt.show()

def cor_plot_ar(atr_1, atr_2):
    data_frame = pd.DataFrame(ar)
    sns.kdeplot(data=data_frame, x=atr_1, hue=atr_2)
    # plt.show()

def pearson_ar(atr_1, atr_2):
    ar_pearson = stats.pearsonr(ar[atr_1], ar[atr_2]).statistic
    return ar_pearson

def pearson_df(atr_1, atr_2):
    df_pearson = stats.pearsonr(df[atr_1], df[atr_2]).statistic
    return df_pearson

# print(pearson('community', 'householdsize'))

def one_hot_ar():
    global ar
    ar = ar.view(np.float64).reshape(ar.shape + (-1,))
    with open('data/states.txt', 'r') as file:
        states = [i.replace('\n', '') for i in file.readlines()]
        states.insert(0, '')
        states.extend(['California' for i in range(6)])
    sta = []
    for i in range(len(ar[:, 0])):
        sta.append(states[int(ar[:,0][i])])
    sta = np.array(sta).reshape((len(ar[:, 0]), 1))
    oh = OneHotEncoder()
    new = oh.fit_transform(sta).toarray()
    new = np.hstack((new, ar))
    return new

def one_hot_df():
    global df
    with open('data/states.txt', 'r') as file:
        states = [i.replace('\n', '') for i in file.readlines()]
        states.insert(0, '')
        states.extend(['California' for i in range(6)])
    df.replace([np.float64(i) for i in range(1, 58)], states, inplace=True)
    oh = OneHotEncoder()
    new = oh.fit_transform(df['state'].to_numpy().reshape((-1, 1))).toarray()
    new = pd.DataFrame(new)
    new = pd.concat([df, new], axis=1).drop('state', axis=1)
    return new

def viz_3d_df():
    fig = plt.figure(figsize=(8, 6))
    ax = fig.add_subplot(111, projection='3d')
    xs = df['community']
    ys = df['householdsize']
    zs = df['county']
    ax.scatter(xs, ys, zs, s=50, alpha=0.6, edgecolors='w')
    ax.set_xlabel('Community')
    ax.set_ylabel('Household Size')
    ax.set_zlabel('County')
    # plt.show()

def viz_3d_ar():
    fig = plt.figure(figsize=(8, 6))
    ax = fig.add_subplot(111, projection='3d')
    xs = ar['community']
    ys = ar['householdsize']
    zs = ar['county']
    ax.scatter(xs, ys, zs, s=50, alpha=0.6, edgecolors='w')
    ax.set_xlabel('Community')
    ax.set_ylabel('Household Size')
    ax.set_zlabel('County')
    # plt.show()

def np_reg():
    data = train_test_split(ar, test_size=0.5, train_size=0.5)
    reg = linear_model.LinearRegression()
    reg.fit(data[0]['community'].reshape(1, -1), data[0]['householdsize'].reshape(1, -1))
    print(mean_squared_error(data[1]['householdsize'].reshape(1, -1),
                             reg.predict(data[1]['community'].reshape(1, -1))))

    reg1 = linear_model.Lasso(alpha=0.1)
    reg1.fit(data[0]['community'].reshape(1, -1), data[0]['householdsize'].reshape(1, -1))
    print(mean_squared_error(data[1]['householdsize'].reshape(1, -1),
                             reg1.predict(data[1]['community'].reshape(1, -1))))

    reg2 = linear_model.LassoLars(alpha=.1)
    reg2.fit(data[0]['community'].reshape(1, -1), data[0]['householdsize'].reshape(1, -1))
    print(mean_squared_error(data[1]['householdsize'].reshape(1, -1),
                             reg2.predict(data[1]['community'].reshape(1, -1))))

def df_reg():
    data = train_test_split(df, test_size=0.5, train_size=0.5)
    reg = linear_model.LinearRegression()
    reg.fit(data[0]['community'].to_numpy().reshape(1, -1), data[0]['householdsize'].to_numpy().reshape(1, -1))
    print(mean_squared_error(data[1]['householdsize'].to_numpy().reshape(1, -1),
                             reg.predict(data[1]['community'].to_numpy().reshape(1, -1))))

    reg1 = linear_model.Lasso(alpha=0.1)
    reg1.fit(data[0]['community'].to_numpy().reshape(1, -1), data[0]['householdsize'].to_numpy().reshape(1, -1))
    print(mean_squared_error(data[1]['householdsize'].to_numpy().reshape(1, -1),
                             reg1.predict(data[1]['community'].to_numpy().reshape(1, -1))))

    reg2 = linear_model.LassoLars(alpha=.1)
    reg2.fit(data[0]['community'].to_numpy().reshape(1, -1), data[0]['householdsize'].to_numpy().reshape(1, -1))
    print(mean_squared_error(data[1]['householdsize'].to_numpy().reshape(1, -1),
                             reg2.predict(data[1]['community'].to_numpy().reshape(1, -1))))


import pycountry
from os import system
import msvcrt

players = ["Alex", "Patric"]

def main(players, max_rounds = 1):
    countries = {c.name: c for c in pycountry.countries}
    score = {p: {} for p in players}
    guessed_countries = {}
    exit_word = "123"

    round = 1

    print("Welcome to our Geography Quiz!")
    print(f"To give up, please type in '{exit_word}' as a guess at any time.")
    input(f"Press ENTER to start!!")

    while round <= max_rounds:
        system("cls")
        print(f"Round {round}!")
        for p in players:
            while True:
                is_hit = False
                guess = input(f"Please enter your guess, {p}:\n")

                if guess == exit_word:
                    print(f"{p} has given up. This is the last round.")
                    max_rounds = 0
                    break

                if countries.get(guess):
                    hit = guess
                else:
                    try:
                        all_hits = [hit.name for hit in pycountry.countries.search_fuzzy(guess)]
                        hits = [hit for hit in all_hits if not guessed_countries.get(hit)]
                    except Exception:
                        hits = []

                    if len(hits) > 1:
                        print("Your guess generated more than one result. Please be more specific.")
                        continue
                    if not len(hits):
                        print(f"There is no country called {guess}. Please try again.")
                        continue

                    hit = hits[0]

                prev_guess = guessed_countries.get(hit)
                if prev_guess:
                    print(f"{hit} has already been guessed by {prev_guess}. Please try again.")
                elif countries.get(hit):
                    guessed_countries[hit] = countries.pop(hit)
                    print(f"{hit} is a country! Good Job, {p}!")
                    score[p][hit] = None
                    guessed_countries.update({hit:p})
                    break
                else:
                    print(f"There is no country called {guess}. Please try again.")

        print(f"Score after round {round}:")
        for player, guesses in score.items():
            print(f"{player}: {len(guesses)}")

        if round < max_rounds:
            input("Press ENTER to the next round")

        round += 1

    max_score = 0
    for p, s in score.items():
        if len(s) > max_score:
            max_score = len(s)
            winner = p

    print(f"The winner is {winner}!")
    return score

if __name__ == "__main__":
    score = main(players, max_rounds=300)


COLUMN_EVENT_ID = "event_id"
COLUMN_SERVER_ID = "server_id"
COLUMN_MESSAGE_ID = "message_id"

class EventMessageProxy(object):
    table = "eventmessages"

    db_mapping = [
        COLUMN_EVENT_ID,
        COLUMN_SERVER_ID,
        COLUMN_MESSAGE_ID
    ]

    @staticmethod
    def get_event_id_statement(server_id, message_id):
        sql = f"SELECT {COLUMN_EVENT_ID} from {EventMessageProxy.table} where " \
              f"{COLUMN_SERVER_ID} = %s AND {COLUMN_MESSAGE_ID} = %s;"
        data = (str(server_id), str(message_id),)

        return sql, data

    @staticmethod
    def get_message_id_statement(event_id):
        sql = f"SELECT {COLUMN_MESSAGE_ID} from {EventMessageProxy.table} where " \
              f"{COLUMN_EVENT_ID} =%s;"
        data = (event_id,)

        return sql, data

    @staticmethod
    def add_event_message_statement(event_id, server_id, message_id):
        columns = ",".join(EventMessageProxy.db_mapping)
        sql = f"INSERT INTO {EventMessageProxy.table}({columns}) VALUES(%s,%s,%s);"
        data = (event_id, server_id, message_id)

        return sql, data


from django.db import models
from utils.models import BaseSlugNameModel
import uuid

from .formation_area_model import FormationArea

class SubFormationArea(BaseSlugNameModel):

    name = models.CharField(
        max_length=36,
        default=str(uuid.uuid4()),
        unique=True,
        null=False,
        blank=False
    )
    description = models.TextField(
        max_length=1000,
        null=True,
        blank=True
    )

    formation_area = models.ForeignKey(
        FormationArea,
        related_name='sub_formation_areas',
        on_delete=models.CASCADE
    )

    class Meta:
        db_table = 'sub_formation_area'
        verbose_name = 'sub_formation_area'
        verbose_name_plural = 'sub_formation_areas'

    def get_absolute_url(self):
        return f'api/formation-area/{self.formation_area}/sub-formation-area/{self.slug}/'

    def get_formation_area_slug(self):
        return self.formation_area.slug


import sys

sys.path.append("..")

from fastapi import Depends, APIRouter, Request, Response, HTTPException
from Modules import auth
from sqlalchemy.orm import Session
from models import model

router = APIRouter(
    prefix="/orientation",
    tags=["orientation"],
    responses={401: {"user": "Not Authorised"}},
)

@router.get("/getlist")
async def get_list(db: Session = Depends(auth.get_db), User: None = Depends(auth.get_current_user)):
    persons = db.query(model.Person).filter(model.Person.cultivator_id != None).all()
    for item in persons:  # remove the cultivators
        if item.cultivator_id == 0:
            persons.remove(item)
    return {"persons": persons}


# LEGO sorter project
# Image loading and processing functions
# (c) lego-sorter team, 2022-2023

import os
import numpy as np
import logging
import tensorflow as tf
import tensorflow_addons as tfa
import matplotlib.pyplot as plt
from absl import flags
from keras.utils import image_dataset_from_directory
from dataclasses import dataclass
from functools import partial
from itertools import zip_longest
from typing import Tuple, Iterable, Union

from lib.globals import IMAGE_DIR, BATCH_SIZE, IMAGE_SIZE
from lib.model import preprocess_input, restore_processed_image

_logger = logging.getLogger('lego-sorter')

FLAGS = flags.FLAGS
flags.DEFINE_bool('gray', False, short_name='g',
    help='Convert images to grayscale')
flags.DEFINE_bool('edges', False, short_name='e',
    help='Convert images to wireframe (edges-only) images')
flags.DEFINE_bool('emboss', False, short_name='x',
    help='Mix wireframe with actual image, can be combined with --gray')
flags.DEFINE_boolean('zoom', False, short_name='z',
    help='Apply zoom augmentation (slows down the training by x5)')
flags.DEFINE_float('zoom_factor', 0.3,
    help='Maximum zoom level for image augmentation (for --zoom model only)')
flags.DEFINE_float('brightness_factor', 0.3,
    help='Maximum brightness level for image augmentation')
flags.DEFINE_float('rotation_factor', 0.45,
    help='Maximum rotation in image augmentation')
flags.DEFINE_float('crop_factor', 0.0, upper_bound=1.0,
    help='Crop image factor (from center)')
flags.DEFINE_float('edge_emboss', 0.5, lower_bound=0.0,
    help='Edge embossing factor (for --emboss model only)')
flags.DEFINE_float('shuffle_buffer_size', 0.25,
    help='Shuffle buffer, either ratio to number of files (<1) or actual size')

tf.get_logger().setLevel('ERROR')

@dataclass
class ImageDataset:
    """ Dataset with extra info resulting from `load_dataset()` call """
    tfds: tf.data.Dataset
    """ actual tensorflow dataset """

    num_files: int
    """ number of image files in a dataset """

    class_names: Iterable[str]
    """ class names """

def _sobel_edges(images):
    """ Internal - applies edges filter on gray image """
    shape = images.shape
    if len(shape) == 3: images = tf.expand_dims(images, 0)
    grad_components = tf.image.sobel_edges(images)
    grad_mag_components = grad_components**2
    grad_mag_square = tf.math.reduce_sum(grad_mag_components,axis=-1)
    images = tf.sqrt(grad_mag_square)
    if len(shape) == 3: images = images[0]
    return images

def _wireframe(images):
    """ Internal - generates wireframe image """
    shape = images.shape
    if len(shape) == 3: images = tf.expand_dims(images, 0)

    gray_images = tf.image.rgb_to_grayscale(images)
    sobel_images = _sobel_edges(gray_images)

    mask = tf.where(sobel_images < 127.5, 0.0, 255.0)   # VGG-16 operates on [0...255] range
    if FLAGS.edge_emboss > 0:
        kernel = tf.zeros((3, 3, mask.get_shape()[3]))
        dilation = (1.0, FLAGS.edge_emboss, FLAGS.edge_emboss, 1.0)
        mask = tf.nn.dilation2d(mask, kernel, (1,1,1,1), 'SAME', 'NHWC', dilation, 'dilation')

    if len(shape) == 3: mask = mask[0]
    return mask

def _preprocess(images, labels=None, seed=None):
    """ Image preprocessing function """
    if FLAGS.crop_factor:
        images = tf.image.central_crop(images, FLAGS.crop_factor)
        images = tf.image.resize(images, IMAGE_SIZE, preserve_aspect_ratio=False)

    images = preprocess_input(images)

    if FLAGS.emboss:
        mask = _wireframe(images)
        images = tf.where(tf.equal(mask, 0.0), images, tf.constant((0.0, 0.0, 255.0), images.dtype))
        if FLAGS.gray:
            images = tf.image.rgb_to_grayscale(images)
    elif FLAGS.gray:
        images = tf.image.rgb_to_grayscale(images)
    elif FLAGS.edges:
        images = _wireframe(images)

    return images, labels

# https://towardsdatascience.com/image-augmentations-in-tensorflow-62967f59239d
@tf.function
def _augment_images(image_and_label, seed):
    image, label = image_and_label
    new_seed = tf.random.experimental.stateless_split(seed, num=1)[0, :]
    image = tf.image.stateless_random_brightness(image, max_delta=FLAGS.brightness_factor, seed=new_seed)
    image = tf.image.stateless_random_flip_left_right(image, seed=new_seed)
    image = tf.image.stateless_random_flip_up_down(image, seed=new_seed)
    return image, label, seed

@tf.function
def _rotate_images(feature, label, seed):
    num_samples = int(tf.shape(feature)[0])
    degrees = tf.random.stateless_uniform(
        shape=(num_samples,), seed=seed, minval=FLAGS.rotation_factor*100.0, maxval=FLAGS.rotation_factor*100.0
    )
    degrees = degrees * 0.017453292519943295  # convert the angle in degree to radians
    rotated_images = tfa.image.rotate(feature, degrees, fill_mode='reflect')
    return rotated_images, label, seed

@tf.function
def _zoom_images(feature, label, seed):
    def _func(images, seed):
        return tf.keras.layers.RandomZoom(
                    (-FLAGS.zoom_factor, FLAGS.zoom_factor),
                    (-FLAGS.zoom_factor, FLAGS.zoom_factor),
                    fill_mode='nearest', interpolation='nearest', seed=seed)(images)
    zoomed_images = tf.py_function(func=_func, inp=[feature, seed], Tout=tf.float32)
    return zoomed_images, label, seed

@tf.function
def _drop_seed(feature, label, seed):
    return feature, label

def load_dataset() -> ImageDataset:
    """ Load images into a dataset """

    _flags = []
    if FLAGS.gray: _flags.append('gray')
    if FLAGS.edges: _flags.append('edges')
    if FLAGS.emboss: _flags.append('emboss')
    if FLAGS.zoom: _flags.append('zoom')
    _logger.debug(f'Model type flags: {", ".join(_flags)}')

    seed = np.random.randint(1e6)
    ds = image_dataset_from_directory(
        IMAGE_DIR,
        label_mode='categorical',
        color_mode='rgb',
        batch_size=None,
        image_size=IMAGE_SIZE,
        shuffle=False,
        crop_to_aspect_ratio=True,
        seed=seed,
    )
    num_files = len(ds.file_paths)
    buf_size = int(FLAGS.shuffle_buffer_size * num_files) if FLAGS.shuffle_buffer_size < 1 \
        else int(FLAGS.shuffle_buffer_size)
    return ImageDataset(
        ds.shuffle(buffer_size=buf_size, reshuffle_each_iteration=False, seed=seed) \
            .map(partial(_preprocess, seed=seed)) \
            .batch(BATCH_SIZE) \
            .prefetch(tf.data.AUTOTUNE),
        num_files,
        ds.class_names.copy()
    )

def split_dataset(ids: ImageDataset, split_by: float=0.8) -> Tuple[tf.data.Dataset, tf.data.Dataset]:
    """ Split dataset into train/test TF subsets """
    train_size = int(ids.num_files * split_by / BATCH_SIZE)
    train_ds = ids.tfds.take(train_size)
    test_ds = ids.tfds.skip(train_size)
    return (train_ds, test_ds)

def augment_dataset(tfds: tf.data.Dataset) -> tf.data.Dataset:
    """ Applies multiple augmentatiions to the TF dataset """
    counter = tf.data.experimental.Counter()
    tfds_with_seed = tf.data.Dataset.zip((tfds, (counter, counter)))
    augmented_dataset = tfds_with_seed.map(_augment_images)
    augmented_dataset = augmented_dataset.map(_rotate_images)
    if FLAGS.zoom:
        augmented_dataset = augmented_dataset.map(_zoom_images)
    augmented_dataset = augmented_dataset.map(_drop_seed)
    return augmented_dataset

def get_dataset_samples(tfds: tf.data.Dataset, num_batches: int = 1) -> tf.data.Dataset:
    """ Generate given number of samples from dataset """
    shape = tfds.cardinality().numpy()
    if shape <= num_batches:
        return tfds

    sample_idx = np.random.randint(shape-num_batches)
    return tfds.take(sample_idx).skip(sample_idx-num_batches)

def show_samples(tfds: tf.data.Dataset, class_names: Iterable[str], num_samples: int = 9):
    """ Show random image samples from TF dataset """
    plt.figure(figsize=(8, 8))
    cmap = 'gray' if FLAGS.gray or FLAGS.edges else None
    for images, labels in get_dataset_samples(tfds):
        for i in range(num_samples):
            _ = plt.subplot(int(num_samples/3), int(num_samples/3), i + 1)
            plt.imshow(restore_processed_image(images[i].numpy()), cmap=cmap)
            label = np.argmax(labels[i])
            plt.title(class_names[label])
            plt.axis('off')
    plt.show()

def predict_image(
    model: tf.keras.Model,
    image: np.ndarray,
    class_names: Iterable[str],
    return_image: bool = False) -> Tuple[str, float]:
    """ Run a pretrained model prediction on an image """

    resized_image = tf.keras.preprocessing.image.smart_resize(image, IMAGE_SIZE)
    prepared_image, _ = _preprocess(tf.expand_dims(resized_image, 0))

    prediction = model.predict(prepared_image, verbose=0)
    most_likely = np.argmax(prediction)
    label = class_names[most_likely]
    prob = prediction[0][most_likely]

    if not return_image:
        return label, prob

    return label, prob, prepared_image[0]

def predict_image_probs(
    model: tf.keras.Model,
    image: np.ndarray,
    class_names: Iterable[str]) -> Iterable[Tuple[str, float]]:
    """ Run a pretrained model prediction on an image returning all detections and probabilities """

    resized_image = tf.keras.preprocessing.image.smart_resize(image, IMAGE_SIZE)
    prepared_image, _ = _preprocess(tf.expand_dims(resized_image, 0))

    prediction = model.predict(prepared_image, verbose=0)
    probs = []
    for prob, pred in sorted(zip(prediction[0], range(len(prediction[0]))), key=lambda x: x[0], reverse=True):
        label = class_names[pred]
        probs.append((label, prob))
    return probs

def predict_dataset(model: tf.keras.Model, tfds: tf.data.Dataset) -> Tuple[tf.Tensor, tf.Tensor]:
    """ Get predictions for TF dataset """

    true_labels = [tf.argmax(labels) for _, labels in tfds.unbatch()]
    true_labels = tf.stack(true_labels, axis=0)

    predicted_labels = model.predict(tfds)
    predicted_labels = tf.concat(predicted_labels, axis=0)
    predicted_labels = tf.argmax(predicted_labels, axis=1)

    return true_labels, predicted_labels

def _pad_to_bounding_box_color(image, offset_height, offset_width,
                                 target_height, target_width, pad_color):
  """ Internal - TF `pad_to_bounding_box()` function adjusted to accept padding color """
  from tensorflow.python.framework import ops
  from tensorflow.python.ops import array_ops
  from tensorflow.python.ops.image_ops_impl import _ImageDimensions, _is_tensor

  with ops.name_scope(None, 'pad_to_bounding_box_white', [image]):
    image = ops.convert_to_tensor(image, name='image')

    is_batch = True
    image_shape = image.get_shape()
    if image_shape.ndims == 3:
      is_batch = False
      image = array_ops.expand_dims(image, 0)
    elif image_shape.ndims is None:
      is_batch = False
      image = array_ops.expand_dims(image, 0)
      image.set_shape([None] * 4)
    elif image_shape.ndims != 4:
      raise ValueError(
          '\'image\' (shape %s) must have either 3 or 4 dimensions.' %
          image_shape)

    batch, height, width, depth = _ImageDimensions(image, rank=4)
    after_padding_width = target_width - offset_width - width
    after_padding_height = target_height - offset_height - height

    # Do not pad on the depth dimensions.
    paddings = array_ops.reshape(
        array_ops.stack([
            0, 0, offset_height, after_padding_height, offset_width,
            after_padding_width, 0, 0
        ]), [4, 2])
    padded = array_ops.pad(image, paddings, constant_values=pad_color)

    padded_shape = [
        None if _is_tensor(i) else i
        for i in [batch, target_height, target_width, depth]
    ]
    padded.set_shape(padded_shape)

    if not is_batch:
      padded = array_ops.squeeze(padded, axis=[0])

    return padded

def zoom_image(image: Union[np.ndarray, tf.Tensor], zoom: float,
               pad_color: int = 0) -> Union[np.ndarray, tf.Tensor]:
    """ Image zoom with tensorflow functions.

    Arguments:
        image:  Either OpenCV (`np.ndarray`) or Tensorflow (`tf.Tensor`) image array.
            The image must be of supported `dtype` (`uint8` or `float`).
        zoom:   Zoom factor, float value greater than 0.
            If it is less than 1, then image is zoomed in (become larger),
            and if greater - zoomed out (become smaller) (this is oppozite to OpenCV's zoom behaviour).
        pad_color:  padding color (0 - black, 255 - white)

    Returns:
        zoomed image of the same type and size as original
    """

    if zoom < 0.0:
        raise ValueError(f'Zoom must be greater than zero')

    if zoom == 1.0:
        # No zoom
        return image

    is_tensor = isinstance(image, tf.Tensor)
    if not is_tensor:
        shape = image.shape
        image_size = np.array(shape[:2])
    else:
        shape = image.get_shape()
        image_size = np.array(shape[:2]) if shape.ndims < 4 else np.array(shape[1:3])

    if zoom < 1.0:
        # Zoom in (result is larger)
        crop_image = tf.image.central_crop(image, zoom)
        zoomed_image = tf.image.resize(crop_image, image_size, preserve_aspect_ratio=False)
    else:
        # Zoom out (result is smaller)
        zoom_size = (zoom * image_size).astype('int')
        offset_height, offset_width = (zoom_size[0]-image_size[0]) // 2, (zoom_size[1]-image_size[1]) // 2
        target_height, target_width = zoom_size[0], zoom_size[1]
        resized_image = _pad_to_bounding_box_color(image, offset_height, offset_width, target_height, target_width, pad_color)
        zoomed_image = tf.image.resize(resized_image, image_size, preserve_aspect_ratio=False)

    zoomed_image = tf.cast(zoomed_image, image.dtype)
    return zoomed_image.numpy() if not is_tensor and isinstance(zoomed_image, tf.Tensor) else zoomed_image

def predict_image_files_zoom(
    model: tf.keras.Model,
    file_names: Iterable[str],
    class_names: Iterable[str],
    true_labels: Iterable[str] = None,
    zoom_levels: Iterable[float] = None,
    show_processed_image: bool = False):
    """ Run a pretrained model prediction on multiple image files with optional zooming and display the result """

    cmap = 'gray' if FLAGS.gray or FLAGS.edges else None
    for file_name, true_label in zip_longest(file_names, true_labels or []):
        image = tf.image.decode_image(tf.io.read_file(file_name), channels=3)

        for zoom in zoom_levels or [1.0]:
            zoomed_image = zoom_image(image, zoom, 255)
            zoomed_image = tf.cast(zoomed_image, tf.uint8)

            predicted_label, predicted_prob, processed_image = predict_image(model, zoomed_image, class_names, return_image=True)

            plt.figure(f'{file_name} @ {zoom}')
            plt.title(f'{true_label or "?"} <- {predicted_label} ({predicted_prob:.2%}) @ {zoom}')
            img_to_show = restore_processed_image(processed_image.numpy()) if show_processed_image else zoomed_image.numpy()
            plt.imshow(img_to_show, cmap=cmap)
            plt.axis('off')

    plt.show()

def predict_image_file(
    model: tf.keras.Model,
    file_name: str,
    class_names: Iterable[str],
    true_label: str = None,
    show_processed_image: bool = False):
    """ Run a pretrained model prediction on an image file and display the result """

    predict_image_files_zoom(model, [file_name], class_names, [true_label], show_processed_image=show_processed_image)

def predict_image_files(
    model: tf.keras.Model,
    file_names: Iterable[str],
    class_names: Iterable[str],
    true_labels: Iterable[str] = None,
    show_processed_image: bool = False):
    """ Run a pretrained model prediction on multiple image files and display the result """

    predict_image_files_zoom(model, file_names, class_names, true_labels, show_processed_image=show_processed_image)

def show_prediction_samples(
    model: tf.keras.Model,
    tfds: tf.data.Dataset,
    class_names: Iterable[str],
    num_samples: int = 9):
    """ Show prediction samples from test dataset """

    plt.figure(figsize=(8, 8))
    cmap = 'gray' if FLAGS.gray or FLAGS.edges else None
    for images, labels in get_dataset_samples(tfds):
        for i in range(min(num_samples, labels.shape[0])):
            _ = plt.subplot(int(num_samples/3), int(num_samples/3), i + 1)
            label = class_names[np.argmax(labels[i])]
            image = images[i].numpy()
            prediction = model.predict(np.array([image]))
            most_likely = np.argmax(prediction)
            predicted_label = class_names[most_likely]
            predicted_prob = prediction[0][most_likely]

            plt.title(f'{label} <- {predicted_label} ({predicted_prob:.2%})')
            plt.imshow(restore_processed_image(image), cmap=cmap)
            plt.axis('off')
    plt.show()

def filter_dataset_by_label(tfds: tf.data.Dataset, class_names: Iterable[str], label: str) -> tf.data.Dataset:
    """ Return a dataset subset containing images of given label only """
    label_index = class_names.index(label)
    return tfds.unbatch().filter(lambda _, label: tf.equal(tf.math.argmax(label), label_index)).batch(BATCH_SIZE)

def fast_get_class_names() -> Iterable[str]:
    """ Faster way of getting image class names """
    return [f for f in os.listdir(IMAGE_DIR) if os.path.isdir(os.path.join(IMAGE_DIR, f))]


from flask import Flask, render_template, jsonify
import pandas as pd
import requests
import etl

# adding new comment

# Access NOAA API and return pandas dataframe for year range selected

def call_api(year):
    global df
    the_json = (requests.get("https://www.ngdc.noaa.gov/hazel/hazard-service/api/v1/volcanoes?maxYear=2022&minYear=2000")).json()
    empty_df = pd.DataFrame(columns=["id","name","country","year","morphology","vei","deathsTotal",\
                    "missingTotal","injuriesTotal","damageMillionsDollarsTotal",\
                    "housesDestroyedTotal"])

    try:
        df = pd.DataFrame(data=the_json["items"])
        df = df[["id","name","country","year","morphology","vei","deathsTotal",\
                    "missingTotal","injuriesTotal","damageMillionsDollarsTotal",\
                    "housesDestroyedTotal"]]
    except:
        print("Error making dataframe")
        return empty_df

    # Define Year Range Dataframes

    df_dict = {}

    try:
        df_2000_2022 = df.copy()
        df_2000_2022.index.name = "2000-2022"
        df_dict[df_2000_2022.index.name] = df_2000_2022

        df_2000_2011 = df.loc[((df["year"]>=2000) & (df["year"]<=2011)), :]
        df_2000_2011.index.name = "2000-2011"
        df_dict[df_2000_2011.index.name] = df_2000_2011

        df_2012_2022 = df.loc[((df["year"]>=2012) & (df["year"]<=2022)), :]
        df_2012_2022.index.name = "2012-2022"
        df_dict[df_2012_2022.index.name] = df_2012_2022

        df_2000_2004 = df.loc[((df["year"]>=2000) & (df["year"]<=2004)), :]
        df_2000_2004.index.name = "2000-2004"
        df_dict[df_2000_2004.index.name] = df_2000_2004

        df_2005_2009 = df.loc[((df["year"]>=2005) & (df["year"]<=2009)), :]
        df_2005_2009.index.name = "2005-2009"
        df_dict[df_2005_2009.index.name] = df_2005_2009

        df_2010_2014 = df.loc[((df["year"]>=2010) & (df["year"]<=2014)), :]
        df_2010_2014.index.name = "2010-2014"
        df_dict[df_2010_2014.index.name] = df_2010_2014

        df_2015_2019 = df.loc[((df["year"]>=2015) & (df["year"]<=2019)), :]
        df_2015_2019.index.name = "2015-2019"
        df_dict[df_2015_2019.index.name] = df_2015_2019

        df_2020_2022 = df.loc[((df["year"]>=2020) & (df["year"]<=2022)), :]
        df_2020_2022.index.name = "2020-2022"
        df_dict[df_2020_2022.index.name] = df_2020_2022

    except:
        print("Error making dataframe")
        return empty_df

    year_range_list = df_dict.keys()

    if year in year_range_list:

        return df_dict[year]

    else:

        print("Error finding year range")
        return empty_df

# Make sure year range selection is valid

def validate_year(year):
    if year in ["2000-2022", "2000-2011", "2012-2022", "2000-2004",\
        "2005-2009", "2010-2014", "2015-2019", "2020-2022"]:
        return year

    else:
        return "2000-2022"

#############################################################
# BEGIN FLASK ROUTING
#############################################################

app = Flask(__name__)
app.config["JSON_SORT_KEYS"] = False
app.config["SEND_FILE_MAX_PAGE_DEFAULT"] = 0

#############################################################
# Index endpoint
#############################################################

@app.route("/")
def index():
    etl.load()
    return render_template("index.html")

#############################################################

@app.route("/map")
def map():
    return render_template("map.html")

@app.route("/new")
def new():
    return render_template("new.html")

@app.route("/volcano")
def ServeVolcano():
   return render_template("volcano.html")

@app.route("/year")
def ServeYear():
   return render_template("year.html")

#############################################################

@app.route("/readmongodb")
def ReadMongoDB():
    data = etl.fetch()
    return jsonify(data)

@app.route("/volcanoes_by_year/<year>")
def volcanoes_by_year(year):
    global df
    df = call_api(validate_year(year))
    vol_by_yr = df.groupby("year")["id"].count().to_dict()

    return jsonify(vol_by_yr)

@app.route("/volcanos_by_country/<year>")
def volcanos_by_country(year):
    global df
    df = call_api(validate_year(year))
    vol_by_ctry = df.groupby(["country"])["id"].count().sort_values(ascending=False).to_dict()

    return jsonify(vol_by_ctry)

@app.route("/volcanos_by_morphology/<year>")
def volcanos_by_morphology(year):
    global df
    df = call_api(validate_year(year))
    vol_by_morph = df.groupby(["morphology"])["id"].count().sort_values(ascending=False).to_dict()

    return jsonify(vol_by_morph)

@app.route("/volcanos_by_vei/<year>")
def volcanos_by_vei(year):
    global df
    df = call_api(validate_year(year))
    vol_by_vei = df.groupby(["vei"])["id"].count().sort_values(ascending=False).to_dict()

    return jsonify(vol_by_vei)

@app.route("/summary_data/<year>")
def summary_data(year):
    global df
    df = call_api(validate_year(year))
    deaths = round(df["deathsTotal"].sum())
    injuries = round(df["injuriesTotal"].sum())
    houses = round(df["housesDestroyedTotal"].sum())
    damages = round(df["damageMillionsDollarsTotal"].sum())*1_000_000

    summ_data = {"Deaths": "{:0,}".format(deaths), "Injuries": "{:0,}".format(injuries),
                 "Houses Destroyed": "{:0,}".format(houses), "Damages": "${:0,}".format(damages)}

    return jsonify(summ_data)

@app.route("/graphs")
def makeGraph():
    return render_template("graphs.html")

#############################################################
# END FLASK ROUTING
#############################################################

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


import random
def display_board():
    """
                    This function displays the board
                    Date:02/02/2020
                    Created By:Alekhyo
                    Input:None
                    Output:board
    """

    print("  {one}  |  {two}  |  {three} \n -------------\n  {four}  |  {five}  |  {six} \n -------------\n  {seven}  |  {eight}  |  {nine}".format(one=board[0],two=board[1],three=board[2],four=board[3],five=board[4],six=board[5],seven=board[6],eight=board[7],nine=board[8]))

def clear_board():
    """
                        This function clears the board
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:None
                        Output:Empty board
    """
    for i in range(0,len(board)):
        board[i]=''

def verify_marker(player):
    """
                        This function verifies illegal marker
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:'X' or 'O'
                        Output:'X' or 'O'
    """
    marker = input("Player {} Choose your marker X or O:".format(player))
    marker=marker.upper()
    if marker=='X' or marker=='O':
        pass
    else:
        print("This is not a correct marker")
        marker=verify_marker(player)
    return marker

def remember_marker(rem,marker,player):
    """
                        This function checks whether the current player is not using opponent's marker
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:dictionary,integer,integer
                        Output:True/False
    """

    if rem['Player {}'.format(player)]==marker:
        return True
    else:
        return False

def player_choice(player):
    """
                        This function verifies correct position,marker entered by the user
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:None
                        Output:'X'/'O',integer(0-9),integer(1-2)
    """

    position = int(input("Player {} Enter your position: (1-9) \n".format(player)))
    marker = verify_marker(player)
    return marker,position,player

def place_marker(marker,position,player):
    """
                        This function places the marker in the desired position
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:None
                        Output:Empty board
    """

    board[position - 1] = marker
    return marker,player

def space_check(position):
    """
                        This function checks the desired position is empty or not
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:Integer number (0-9)
                        Output:True/False
    """
    if board[position-1]=='':
        return True
    else:
        return False

def full_board_check():
    """
                        This function checks if all the positions is filled or not
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:None
                        Output:True/False
    """
    if '' in board:
        return True
    else:
        return False

def win_check(marker):
    """
                        This function checks whether the player won or not
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:'X' or 'O'
                        Output:1/0
    """
    l=[[1,2,3],[4,5,6],[7,8,9],[1,4,7],[2,5,8],[3,6,9],[3,5,7],[1,5,9]]
    flag=0
    for i in l:
        for j in i:
            if marker in board[j-1]:
                flag=1
            else:
                flag=0
                break

        if flag == 1:
            return 1
            break
        else:
            pass

def player_input(player):
    """
                        This function takes the user's input
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:integer
                        Output:None
    """
    count=1
    win=0
    player_num=player
    while(count<9):
        if player_num==1:
            if full_board_check()==True:
                marker,position,player=player_choice(2)
                if space_check(position)==True:
                    if remember_marker(rem,marker,player)==True:
                        marker,player=place_marker(marker,position,2)
                        display_board()
                        win=win_check(marker)
                        if win==1:
                            print("Player 2 WON the game")
                            break
                        else:
                            win=0
                            player_num=2
                            count=count+1
                    else:
                        print("This is not your marker\n")
                        player_input(player_num)
                else:
                    print("This position is filled \n")
                    player_input(player_num)
            else:

                print("It's a TIE")

        else:
            if full_board_check()==True:
                marker,position,player=player_choice(1)
                if space_check(position)==True:
                    if remember_marker(rem,marker,player)==True:
                        marker,player=place_marker(marker,position,1)
                        display_board()
                        win=win_check(marker)
                        if win==1:
                            print("Player 1 WON the game")
                            break
                        else:
                            win=0
                            player_num=1
                            count=count+1
                    else:
                        print("This is not your marker \n")
                        player_input(player_num)

                else:
                    print("This position is filled\n")
                    player_input(player_num)
            else:
                print("It's a TIE")

def choose_first(rem):
    """
                        This function randomly chooses which player will go first
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:dictionary
                        Output:Player 1/ Player 2
    """
    a=1
    b=2
    print("Welcome to Tic Tac Toe!!!!\n")
    player = random.randint(a, b)
    print("Player {} will go first \n".format(player))
    marker,position,player=player_choice(player)
    marker,player=place_marker(marker,position,player)

    rem['Player {}'.format(player)] = marker
    if player == 1:
        if marker == 'X':
            rem['Player 2'] = 'O'
        else:
            rem['Player 2'] = 'X'
    else:
        if marker == 'X':
            rem['Player 1'] = 'O'
        else:
            rem['Player 1'] = 'X'

    display_board()
    return player

def replay():
    """
                        This function used restart the game
                        Date:02/02/2020
                        Created By:Alekhyo
                        Input:None
                        Output:Board
    """
    answer='Yes'
    while(answer=='Yes'):
        clear_board()
        player=choose_first(rem)
        player_input(player)
        print("-"*48)
        print("Do you want to play again? Yes or No")
        answer=input()

rem={}
board=['', '', '', '', '', '', '', '', '']
replay()


#!/usr/bin/env python3.6

import requests
import json
import sys
import os
from functools import reduce
import datetime

class GithubEvents(object):
    config = {}
    issuesEvents = []

    def __init__(self, config):
        self.config = config

    def __getIssueEvents(self, url):
        headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/vnd.github.starfox-preview+json',
            'Authorization': 'token {0}'.format(self.config['github']['api_token'])
        }
        payload = {'per_page': 100}
        response = requests.get(url, params=payload, headers=headers)

        return response.json()

    def __calcTimeInColumns(self, events):
        moveCardEvents = list(filter(
            lambda event: 'moved_columns_in_project' == event['event'] or 'added_to_project' == event['event'],
            events
        ))

        cyclesTimes = []
        for event in moveCardEvents:
            if 'previous_column_name' not in event['project_card']:
                continue

            startCol = event['project_card']['previous_column_name']
            startEvent = next(iter(list(filter(
                lambda event: event['project_card']['column_name'] == startCol,
                moveCardEvents
            ))))

            lastColTime = datetime.datetime.strptime(startEvent['created_at'], '%Y-%m-%dT%H:%M:%SZ')
            moveTimeToThisCol = datetime.datetime.strptime(event['created_at'], '%Y-%m-%dT%H:%M:%SZ')

            duration = moveTimeToThisCol - lastColTime
            element = {
                'column': startCol,
                'end_column': event['project_card']['column_name'],
                'duration': duration.total_seconds(),
            }

            colElement = list(filter(
                lambda cycle: startCol == cycle['column'],
                cyclesTimes
            ))
            if not colElement:
                cyclesTimes.append(element)
                continue

            element = next(iter(colElement))
            index = cyclesTimes.index(element)
            cyclesTimes[index] = element

        return cyclesTimes

    def getDateStart(self, events_url):
        events = self.__getIssueEvents(events_url)
        moveCardEvents = list(filter(
            lambda event: 'moved_columns_in_project' == event['event'] or 'added_to_project' == event['event'],
            events
        ))

        for event in moveCardEvents:
            if event['project_card']['column_name'] == 'In progress':
                return event['created_at']

        for event in moveCardEvents:
            if event['project_card']['column_name'] == 'Review':
                return event['created_at']

        for event in moveCardEvents:
            if event['project_card']['column_name'] == 'Testing':
                return event['created_at']

        return None

    def getIssuesEvents(self, issues):
        eventsList = {}
        for issue in issues:
            events = self.__getIssueEvents(issue['events_url'])
            item = { issue['id']: events }
            eventsList.update(item)

        return eventsList

    def getCardsCyclesTimes(self, issues):
        cardsCyclesTimes = {}
        for issue in issues:
            events = self.issuesEvents[str(issue['id'])]
            issueCyclesTimes = self.__calcTimeInColumns(events)
            item = { issue['id']: issueCyclesTimes }
            cardsCyclesTimes.update(item)

        return cardsCyclesTimes


import numpy as np
from melodion.ops import psi, vec, mat

def sample_matrices():
    X = np.array([[1, 2, 3], [4, 5, 6]])
    Y = np.array([[7, 8, 9], [10, 11, 12]])
    return X, Y

def test_psi():
    X, Y = sample_matrices()
    d = psi(X, Y)
    assert np.all(d == [50, 167])

def test_vec():
    X, Y = sample_matrices()
    xv = vec(X)
    assert np.all(xv == [1, 2, 3, 4, 5, 6])

def test_mat():
    X, Y = sample_matrices()
    matrix_shape = np.shape(X)
    xv = vec(X)
    Xx = mat(xv, matrix_shape)
    assert np.all(X == Xx)

if __name__ == "__main__":
    test_psi()
    test_vec()
    test_mat()


import numpy

class Ant:
    dx = [-2, -2, -1, -1, 1, 1, 2, 2]
    dy = [-1, 1, -2, 2, -2, 2, -1, 1]

    def __init__(self, size_x, size_y):
        self.size_x = size_x
        self.size_y = size_y
        self.size = size_x * size_y
        self.conf = [numpy.random.randint(low=0, high=self.size)]

    def possible_moves(self, index=None):
        next_possible_moves = []
        if index is None:
            index = self.conf[-1]
        x = index // self.size_y
        y = index % self.size_y
        for direction in range(8):
            next_x = x + self.dx[direction]
            next_y = y + self.dy[direction]
            if 0 <= next_x < self.size_x and 0 <= next_y < self.size_y:
                # valid move
                next_index = next_x * self.size_y + next_y
                if next_index not in self.conf:
                    next_possible_moves.append(next_index)
        return next_possible_moves.copy()

    def move_coefficient(self, index):
        # dummy = Ant(self.size_x, self.size_y)
        # dummy.conf = self.conf.copy()
        # dummy.conf.append(index)
        # return 9 - len(dummy.possible_moves(index))
        # return 8 - len(self.possible_moves(index))
        return 1

    def ok_move(self, pos1, pos2):
        pos1_x = pos1 // self.size_y
        pos1_y = pos1 % self.size_y
        pos2_x = pos2 // self.size_y
        pos2_y = pos2 % self.size_y
        for dire in range(8):
            if self.dx[dire] + pos1_x == pos2_x and self.dy[dire] + pos1_y == pos2_y:
                return True
        return False

    def update(self, q0, trace, alpha, beta):
        next_moves = self.possible_moves().copy()
        if len(next_moves) == 0:
            return False
        p = [0 for _ in range(self.size)]
        for i in next_moves:
            p[i] = self.move_coefficient(i)
        for i in range(len(p)):
            p[i] = trace[self.conf[-1]][i] ** alpha + p[i] ** beta
        if numpy.random.uniform(0, 1.0) < q0:
            index_to_add = -1
            max_value = 0
            for i in range(len(p)):
                if max_value < p[i] and i not in self.conf:
                    index_to_add = i
                    max_value = p[i]
            self.conf.append(index_to_add)
        else:
            for i in range(len(p)):
                if not self.ok_move(self.conf[-1], i):
                    p[i] = 0
                if i in self.conf:
                    p[i] = 0
            total = sum(p)
            pdf = [p[i] / total for i in range(len(p))]
            index = [i for i in range(len(p))]
            index_to_add = numpy.random.choice(index, 1, p=pdf).tolist()[0]
            self.conf.append(index_to_add)
        # print(self.conf)
        return True

    def fitness(self):
        return len(self.conf)

# def print_to_map(table, n, m):
#     k = 0
#     for _ in range(n):
#         for _ in range(m):
#             print(table[k], end=", ")
#             k += 1
#         print()

class Controller:
    def __init__(self, size_x, size_y,
                 epoch_no, ant_no, alpha,
                 beta, rho, q0):
        self.size_x = size_x
        self.size_y = size_y
        self.epoch_no = epoch_no
        self.ant_no = ant_no
        self.alpha = alpha
        self.beta = beta
        self.rho = rho
        self.q0 = q0
        self.trace = [[1 for _ in range(size_x * size_y)] for _ in range(size_x * size_y)]
        # for i in self.trace:
        #     print(i)

    def solve(self):
        best_sol = []
        for i in range(self.epoch_no):
            sol = self.run_epoch.copy()
            if len(sol) > len(best_sol):
                best_sol = sol.copy()
        return best_sol

    @property
    def run_epoch(self):
        ants = [Ant(self.size_x, self.size_y) for _ in range(self.ant_no)]

        for i in range(self.size_x * self.size_y):
            for x in ants:
                x.update(self.q0, self.trace, self.alpha, self.beta)
        d_trace = [1.0 / ants[i].fitness() for i in range(len(ants))]

        for i in range(self.size_x * self.size_y):
            for j in range(self.size_x * self.size_y):
                self.trace[i][j] = (1 - self.rho) * self.trace[i][j]

        for i in range(len(ants)):
            for j in range(len(ants[i].conf) - 1):
                x = ants[i].conf[j]
                y = ants[i].conf[j + 1]
                self.trace[x][y] = self.trace[x][y] + d_trace[i]

        f = [[ants[i].fitness(), i] for i in range(len(ants))]
        f = max(f)
        return ants[f[1]].conf

class Problem:
    def __init__(self, size_x, size_y,
                 epoch_no, ant_no, alpha,
                 beta, rho, q0):
        self.size_x = size_x
        self.size_y = size_y
        self.controller = Controller(size_x, size_y, epoch_no, ant_no, alpha, beta, rho, q0)

    def solve(self):
        print("Attempting solve, this may take a while")
        solution = self.controller.solve()
        print("Solution's length: %d, out of %d, percentage: %.2f" % (len(solution), self.size_x * self.size_y,
                                                                      100 * (len(solution) / (
                                                                                self.size_x * self.size_y))))
        print("Path found:", solution)
        fancy_print(solution, self.size_x, self.size_y)
        okay(solution)

def fancy_print(conf, n, m):
    path = [-1 for _ in range(n * m)]
    k = 1
    for i in conf:
        path[i] = k
        k += 1
    k = 0
    for i in range(n):
        for j in range(m):
            print(path[k], end=", ")
            k += 1
        print()

def okay(path):
    path_copy = path.copy()
    for i in range(len(path_copy)):
        val = path_copy[i]
        path_copy[i] = 0
        if val in path_copy and val != 0:
            print("DUBLURA - ai gresit verificarile, baiatul meu")

if __name__ == '__main__':
    prob = Problem(8, 8, 500, 3, 1.9, 0.9, 0.05, 0.5)
    prob.solve()


# coding=utf-8

import os
import re
import json

def findAllFile(base, extension):
    for root, ds, fs in os.walk(base):
        for f in fs:
            if f.endswith('.' + extension) and 'tests/' not in root and 'test/' not in root:
                    fullname = os.path.join(root, f)
                    yield fullname

def extract_servicename_from_log(path):
    with open(path, 'r', encoding='UTF-8') as file:  # 转换编码以实现正确输出中文格式
        lines = file.readlines()

        analyze_this_file = False
        for i, line in enumerate(lines):
            if 'SEARCH FROM FUNCTION WHICH CONTAINS getService()' in line:
                # print(line.split("["))
                tem = line.split("[")[-1].strip()
                tem = tem[:-1]
                print(tem)

if __name__ == '__main__':
    paths = findAllFile('log/', 'txt')
    for path in paths:
        extract_servicename_from_log(path)


def count(s1,s2):
   fin=''
   for i in range(0,len(s1)):
    if s1[i]==s2[i]:
        fin+=s1[i]
    elif s2[i+1]==s1[i] or s1[i+1]==s2[i]:
        fin+=s2[i+1]

s1 = "SHINCHAN"
s2 = "NOHARAAA"
print(count(s1, s2))


class Solution:
    def isIsomorphic(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        key_maps, right_key_maps = {}, {}
        for left, right in zip(s, t):
            if left in key_maps and key_maps[left] != right:
                return False

            if right in right_key_maps and right_key_maps[right] != left:
                return False

            key_maps[left] = right
            right_key_maps[right] = left

        return True

x = Solution()
print(x.isIsomorphic('egg', 'add') == True)
print(x.isIsomorphic('foo', 'bar') == False)
print(x.isIsomorphic('paper', 'title') == True)
print(x.isIsomorphic('ab', 'aa') == False)


from collections import deque
from sound.music_player import MusicPlayer
import logging
from logging import getLogger
from excluded.config import midi_output

class NoteString:
    """
    Stores notes in a string, similar to lights
    When a new note is pushed in, and old one is pushed out
    """

    def __init__(self, max_len, midi_port=midi_output):
        self.mp: MusicPlayer = MusicPlayer(midi_port)
        self.contents: deque = deque(maxlen=max_len)
        for x in range(len(self.contents)):
            self.contents[x] = None
        logging.basicConfig(level=logging.INFO)
        self.logger = getLogger('NoteString')

    def add(self, note: int):
        self.stop_last_note()
        self.contents.appendleft(note)
        self.mp.play_note(note)
        self.logger.info(f'Added note {note}')

    def stop_last_note(self):
        if len(self.contents) == self.contents.maxlen:
            last_note = self.contents[self.contents.maxlen - 1]
            self.mp.stop_note(last_note)
            self.logger.info(f'Removed note {last_note}')


'''
Created on Jan 18, 2016

@author: azaringh
'''
import redis
import json
import csv
import os

stats_name = 'chicago:ge-1/0/5:traffic statistics'

r = redis.StrictRedis(host='10.10.4.252', port=6379, db=0)
csv_file = os.getenv('HOME') + '/' + stats_name.replace(':', '_').replace('/', '-').replace(' ', '_') + '.csv'
f = open(csv_file, 'w+')   # Read and write

def create_csv():
    csvwriter = csv.writer(f)
    stat_list = r.lrange(stats_name, 0 , -1)
    hflag = True
    for stat in reversed(stat_list):
        j = json.loads(stat)

        d = { 'time': j['timestamp'],
              'input-bytes': j['stats'][0]['input-bytes'][0]['data'],
              'input-bps': j['stats'][0]['input-bps'][0]['data'],
              'output-pps': j['stats'][0]['output-pps'][0]['data'],
              'output-bps': j['stats'][0]['output-bps'][0]['data'],
              'output-bytes': j['stats'][0]['output-bytes'][0]['data'],
              'input-pps': j['stats'][0]['input-pps'][0]['data'],
              'input-packets': j['stats'][0]['input-packets'][0]['data'],
              'output-packets': j['stats'][0]['output-packets'][0]['data']
             }
        if hflag == True:
            header = d.keys()
            csvwriter.writerow(header)
            hflag = False
        csvwriter.writerow(d.values())
    return

create_csv()