import os
from io import StringIO
import xlsxwriter
from django.http import HttpResponse
from django.shortcuts import render
from nltk import FreqDist
from nltk.sentiment.vader import SentimentIntensityAnalyzer
from nltk.corpus import stopwords
from string import punctuation
import spacy
import pandas as pd
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import warnings
from .models import Pos_Freq, Table_data

pd.set_option("display.max_colwidth", 200)

warnings.filterwarnings("ignore", category=UserWarning)
warnings.filterwarnings("ignore", category=DeprecationWarning)
warnings.filterwarnings("ignore", category=FutureWarning)

# Globals
us_state_to_abbrev = {
    'AL': 'Alabama',
    'AK': 'Alaska',
    'AZ': 'Arizona',
    'AR': 'Arkansas',
    'CA': 'California',
    'CO': 'Colorado',
    'CT': 'Connecticut',
    'DE': 'Delaware',
    'FL': 'Florida',
    'GA': 'Georgia',
    'HI': 'Hawaii',
    'ID': 'Idaho',
    'IL': 'Illinois',
    'IN': 'Indiana',
    'IA': 'Iowa',
    'KS': 'Kansas',
    'KY': 'Kentucky',
    'LA': 'Louisiana',
    'ME': 'Maine',
    'MD': 'Maryland',
    'MA': 'Massachusetts',
    'MI': 'Michigan',
    'MN': 'Minnesota',
    'MS': 'Mississippi',
    'MO': 'Missouri',
    'MT': 'Montana',
    'NE': 'Nebraska',
    'NV': 'Nevada',
    'NH': 'New Hampshire',
    'NJ': 'New Jersey',
    'NM': 'New Mexico',
    'NY': 'New York',
    'NC': 'North Carolina',
    'ND': 'North Dakota',
    'OH': 'Ohio',
    'OK': 'Oklahoma',
    'OR': 'Oregon',
    'PA': 'Pennsylvania',
    'RI': 'Rhode Island',
    'SC': 'South Carolina',
    'SD': 'South Dakota',
    'TN': 'Tennessee',
    'TX': 'Texas',
    'UT': 'Utah',
    'VT': 'Vermont',
    'VA': 'Virginia',
    'WA': 'Washington',
    'WV': 'West Virginia',
    'WI': 'Wisconsin',
    'WY': 'Wyoming',
    'DC': 'District of Columbia',
    'AS': 'American Samoa',
    'GU': 'Guam',
    'MP': 'Northern Mariana Islands',
    'PR': 'Puerto Rico',
    'UM': 'United States Minor Outlying Islands',
    'VI': 'U.S. Virgin Islands'}
add_stop = ["2", "26", "'s", ".", "i", "I", "��", "say", "me", "the", "my", "myself", "we", "theword", "our", "ours",
            "ourselves", "you", "your", "yours", "yourself", "yourselves", "he", "him", "his", "himself", "she", "her",
            "hers", "herself", "it", "its", "itself", "they", "them", "their", "theirs", "themselves", "what", "which",
            "who", "whom", "this", "that", "these", "those", "am", "is", "are", "was", "were", "be", "been", "being",
            "have", "has", "had", "having", "do", "does", "did", "doing", "a", "an", "the", "and", "but", "if", "or",
            "because", "as", "until", "while", "of", "at", "by", "for", "with", "about", "against", "between", "into",
            "through", "during", "before", "after", "above", "below", "to", "from", "up", "down", "in", "out", "on",
            "off", "over", "under", "again", "further", "then", "once", "here", "there", "when", "where", "why", "how",
            "all", "any", "both", "each", "few", "more", "most", "other", "some", "such", "no", "nor", "not", "only",
            "own", "same", "so", "than", "too", "very", "s", "t", "can", "will", "just", "don", "good", "should", "now"]
stop_words = set(stopwords.words('english') + list(punctuation) + list(add_stop))
nlp = spacy.load('en_core_web_sm', disable=['parser', 'ner'])
to_freq = []

# function to remove stopwords
def remove_stopwords(rev):
    rev_new = " ".join([i for i in rev if i not in stop_words])
    return rev_new

def freq_words(x, terms=30):
    all_words = ' '.join([text for text in x])
    all_words = all_words.split()

    fdist = FreqDist(all_words)
    words_df = pd.DataFrame({'word': list(fdist.keys()), 'count': list(fdist.values())})

    # selecting top 20 most frequent words
    d = words_df.nlargest(columns="count", n=terms)
    return d

def get_reviews(request, city_name):
    print("in get_reviews")

    df = pd.read_excel("Feedback.xlsx", sheet_name="Feedback Details")
    df = df[df['Feedback'] != "--"].reset_index(drop=True)

    # replace "n't" with " not"
    df['Feedback'] = df['Feedback'].str.replace("n\'t", " not")

    # remove unwanted characters, numbers and symbols
    df['Feedback'] = df['Feedback'].str.replace("[^a-zA-Z#]", " ")

    # remove short words (length < 3)
    df['Feedback'] = df['Feedback'].apply(lambda x: ' '.join([w for w in x.split() if len(w) > 2]))

    # remove stopwords from the text
    df = df.loc[df['City'] == city_name]
    reviews = [remove_stopwords(r.lower().split()) for r in df['Feedback']]
    tokenized_reviews = pd.Series(reviews).apply(lambda x: x.split())
    print("Data Cleaning....")

    def lemmatization(texts):
        output = []
        for sent in texts:
            doc = nlp(" ".join(sent))
            output.append([token.lemma_ for token in doc if token.pos_ in ['NOUN', 'ADJ']])
        return output

    reviews_2 = lemmatization(tokenized_reviews)
    print("Data lemmatization....")

    reviews_3 = []
    for i in range(len(reviews_2)):
        reviews_3.append(' '.join(reviews_2[i]))
    df['reviews'] = reviews_3

    # Sentiment Analysis and finding polarity
    analyzer = SentimentIntensityAnalyzer()
    df['Negative_Score'] = df['reviews'].apply(lambda x: analyzer.polarity_scores(x)['neg'])
    df['Neutral_Score'] = df['reviews'].apply(lambda x: analyzer.polarity_scores(x)['neu'])
    df['Positive_Score'] = df['reviews'].apply(lambda x: analyzer.polarity_scores(x)['pos'])
    df['Compound_Score'] = df['reviews'].apply(lambda x: analyzer.polarity_scores(x)['compound'])

    print("Data Sentiment Analysis....")
    # Review Categories
    df.loc[df['Compound_Score'] > 0.2, "Sentiment"] = "Positive"
    df.loc[(df['Compound_Score'] >= -0.2) & (df['Compound_Score'] <= 0.2), "Sentiment"] = "Neutral"
    df.loc[df['Compound_Score'] < -0.2, "Sentiment"] = "Negative"

    # Percentages of Sentiment Calculation
    pos_review = round((len(df[df["Sentiment"] == "Positive"]) / len(df)) * 100)
    neu_review = round((len(df[df["Sentiment"] == "Neutral"]) / len(df)) * 100)
    neg_review = round((len(df[df["Sentiment"] == "Negative"]) / len(df)) * 100)
    print("Data compound Analysis....", pos_review, neu_review, neg_review)

    df_Postive = df[df['Sentiment'] == "Positive"]
    df_Neutral = df[df['Sentiment'] == "Neutral"]
    df_Negative = df[df['Sentiment'] == "Negative"]

    # Positive_Word_Cloud_Analysis
    Positive_Word_Cloud_Analysis = ' '.join(df_Postive['reviews'])
    if len(Positive_Word_Cloud_Analysis) == 0:
        Positive_Word_Cloud_Analysis = "NoPositive"
    wordcloud = WordCloud(
        background_color="white",
        max_words=150,
        max_font_size=40,
        scale=3,
        random_state=42
    ).generate(Positive_Word_Cloud_Analysis)

    wc = plt.figure(figsize=(15, 8))
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.tight_layout(pad=0)

    wcp = StringIO()
    wc.savefig(wcp, format='svg')
    wcp.seek(0)
    plt.close(wc)
    print("Data Positive word cloud....")

    # Negative_Word_Cloud_Analysis
    Negative_Word_Cloud_Analysis = ' '.join(df_Negative['reviews'])
    if len(Negative_Word_Cloud_Analysis) == 0:
        Negative_Word_Cloud_Analysis = "NoNegative"
    wordcloud = WordCloud(
        background_color="white",
        max_words=100,
        max_font_size=25,
        scale=2,
        random_state=42
    ).generate(Negative_Word_Cloud_Analysis)

    wc_n = plt.figure(figsize=(7, 4))
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.tight_layout(pad=0)

    wcn = StringIO()
    wc_n.savefig(wcn, format='svg')
    wcn.seek(0)
    plt.close(wc_n)
    print("Data Negative_Word_Cloud_Analysis....")

    # Review ratings
    rating_1 = df.loc[df['Star Rating'] == 1]
    rating_2 = df.loc[df['Star Rating'] == 2]
    rating_3 = df.loc[df['Star Rating'] == 3]
    rating_4 = df.loc[df['Star Rating'] == 4]
    rating_5 = df.loc[df['Star Rating'] == 5]

    r1_pos = rating_1.loc[rating_1["Sentiment"] == "Positive"]
    r1_neu = rating_1.loc[rating_1["Sentiment"] == "Neutral"]
    r1_neg = rating_1.loc[rating_1["Sentiment"] == "Negative"]
    r2_pos = rating_2.loc[rating_2["Sentiment"] == "Positive"]
    r2_neu = rating_2.loc[rating_2["Sentiment"] == "Neutral"]
    r2_neg = rating_2.loc[rating_2["Sentiment"] == "Negative"]
    r3_pos = rating_3.loc[rating_3["Sentiment"] == "Positive"]
    r3_neu = rating_3.loc[rating_3["Sentiment"] == "Neutral"]
    r3_neg = rating_3.loc[rating_3["Sentiment"] == "Negative"]
    r4_pos = rating_4.loc[rating_4["Sentiment"] == "Positive"]
    r4_neu = rating_4.loc[rating_4["Sentiment"] == "Neutral"]
    r4_neg = rating_4.loc[rating_4["Sentiment"] == "Negative"]
    r5_pos = rating_5.loc[rating_5["Sentiment"] == "Positive"]
    r5_neu = rating_5.loc[rating_5["Sentiment"] == "Neutral"]
    r5_neg = rating_5.loc[rating_5["Sentiment"] == "Negative"]

    Rating_list = [[len(r1_pos), len(r1_neu), len(r1_neg)], [len(r2_pos), len(r2_neu), len(r2_neg)],
                   [len(r3_pos), len(r3_neu), len(r3_neg)], [len(r4_pos), len(r4_neu), len(r4_neg)],
                   [len(r5_pos), len(r5_neu), len(r5_neg)]]

    star_df = pd.DataFrame([[Rating_list[0][0], Rating_list[0][1], Rating_list[0][2]],
                            [Rating_list[1][0], Rating_list[1][1], Rating_list[1][2]],
                            [Rating_list[2][0], Rating_list[2][1], Rating_list[2][2]],
                            [Rating_list[3][0], Rating_list[3][1], Rating_list[3][2]],
                            [Rating_list[4][0], Rating_list[4][1], Rating_list[4][2]]],
                           columns=['Positive', 'Neutral', 'Negative'])
    print("Review ratings Analysis....")

    date_based = pd.DataFrame(df["Review Date"].value_counts().rename_axis("Date").reset_index()).drop("Review Date",
                                                                                axis=1)
    date_based = date_based.merge(df_Postive["Review Date"].value_counts().rename_axis("Date"), on="Date", how="outer")
    date_based.columns = ['Date', 'Positive']
    date_based = date_based.merge(df_Neutral["Review Date"].value_counts().rename_axis("Date"), on="Date", how="outer")
    date_based.columns = ['Date', 'Positive', 'Neutral']
    date_based = date_based.merge(df_Negative["Review Date"].value_counts().rename_axis("Date"), on="Date", how="outer")
    date_based.columns = ['Date', 'Positive', 'Neutral', 'Negative']
    date_based = date_based.fillna("0")
    for value in ['Positive', 'Neutral', 'Negative']:
        date_based[value] = [int(x) for x in date_based[value]]
    date_based = date_based.sort_values(by="Date").reset_index(drop=True)

    print("Found the date DF")

    subset = df[df['Sentiment'] == "Positive"]
    dist_pos = list(subset["Compound_Score"])
    star_pos = list(star_df["Positive"])
    star_neu = list(star_df["Neutral"])
    star_neg = list(star_df["Negative"])
    dates = list(date_based["Date"])
    date_pos = list(date_based["Positive"])
    date_neu = list(date_based["Neutral"])
    date_neg = list(date_based["Negative"])
    print("Storing the values")

    results = {
        'wcp': wcp.getvalue(),
        'wcn': wcn.getvalue(),
        'pos_count': len(df[df["Sentiment"] == "Positive"]),
        'pos_per': pos_review,
        'neu_count': len(df[df["Sentiment"] == "Neutral"]),
        'neu_per': neu_review,
        'neg_count': len(df[df["Sentiment"] == "Negative"]),
        'neg_per': neg_review,
        'dist_pos': dist_pos,
        'star_pos': star_pos,
        'star_neu': star_neu,
        'star_neg': star_neg,
        'dates': dates,
        'date_pos': date_pos,
        'date_neu': date_neu,
        'date_neg': date_neg,
        'return_name': city_name,

    }

    return results

df = pd.read_excel("Feedback.xlsx", sheet_name="Feedback Details")
df = df[df['Feedback'] != "--"].reset_index(drop=True)

# replace "n't" with " not"
df['Feedback'] = df['Feedback'].str.replace("n\'t", " not")

# remove unwanted characters, numbers and symbols
df['Feedback'] = df['Feedback'].str.replace("[^a-zA-Z#]", " ")

# remove short words (length < 3)
df['Feedback'] = df['Feedback'].apply(lambda x: ' '.join([w for w in x.split() if len(w) > 2]))

# remove stopwords from the text
reviews = [remove_stopwords(r.lower().split()) for r in df['Feedback']]
tokenized_reviews = pd.Series(reviews).apply(lambda x: x.split())

print("Data Cleaning....")

def lemmatization(texts):
    output = []
    for sent in texts:
        doc = nlp(" ".join(sent))
        output.append([token.lemma_ for token in doc if token.pos_ in ['NOUN', 'ADJ']])
    return output

reviews_2 = lemmatization(tokenized_reviews)
print("Data lemmatization....")

reviews_3 = []
for i in range(len(reviews_2)):
    reviews_3.append(' '.join(reviews_2[i]))
df['reviews'] = reviews_3

# Sentiment Analysis and finding polarity
analyzer = SentimentIntensityAnalyzer()
df['Negative_Score'] = df['reviews'].apply(lambda x: analyzer.polarity_scores(x)['neg'])
df['Neutral_Score'] = df['reviews'].apply(lambda x: analyzer.polarity_scores(x)['neu'])
df['Positive_Score'] = df['reviews'].apply(lambda x: analyzer.polarity_scores(x)['pos'])
df['Compound_Score'] = df['reviews'].apply(lambda x: analyzer.polarity_scores(x)['compound'])

print("Data Sentiment Analysis....")
# Review Categories
df.loc[df['Compound_Score'] > 0.2, "Sentiment"] = "Positive"
df.loc[(df['Compound_Score'] >= -0.2) & (df['Compound_Score'] <= 0.2), "Sentiment"] = "Neutral"
df.loc[df['Compound_Score'] < -0.2, "Sentiment"] = "Negative"

def index(request):
    if request.method == "POST":
        try:
            print(request.POST['city_name'])
            if request.POST['city_name']:
                city_name = request.POST['city_name']
                return render(request, "index.html", get_reviews(request, city_name))
        except:
            print("error.......")
        try:
            print(request.POST['state_name'])
        except:
            pass
    # get_reviews(request, "Jacksonville")

    writer = pd.ExcelWriter('Dine_Brand.xlsx', engine='xlsxwriter')

    df.to_excel(writer, sheet_name="Dataset", index=False)

    # Percentages of Sentiment Calculation
    pos_review = [j for i, j in enumerate(df['Feedback']) if df['Compound_Score'][i] > 0.2]
    neu_review = [j for i, j in enumerate(df['Feedback']) if 0.2 >= df['Compound_Score'][i] >= -0.2]
    neg_review = [j for i, j in enumerate(df['Feedback']) if df['Compound_Score'][i] < -0.2]

    df_Postive = df[df['Sentiment'] == "Positive"]
    df_Neutral = df[df['Sentiment'] == "Neutral"]
    df_Negative = df[df['Sentiment'] == "Negative"]
    df_Postive.to_excel(writer, sheet_name="Positive Reviews", index=False)
    df_Neutral.to_excel(writer, sheet_name="Neutral Reviews", index=False)
    df_Negative.to_excel(writer, sheet_name="Negative Reviews", index=False)

    # Positive_Word_Cloud_Analysis
    Positive_Word_Cloud_Analysis = ' '.join(df_Postive['reviews'])
    wordcloud = WordCloud(
        background_color="white",
        max_words=150,
        max_font_size=40,
        scale=3,
        random_state=42
    ).generate(Positive_Word_Cloud_Analysis)

    wc = plt.figure(figsize=(7, 4))
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.tight_layout(pad=0)

    wcp = StringIO()
    wc.savefig(wcp, format='svg')
    wcp.seek(0)
    plt.close(wc)

    # Negative_Word_Cloud_Analysis
    Negative_Word_Cloud_Analysis = ' '.join(df_Negative['reviews'])
    wordcloud = WordCloud(
        background_color="white",
        max_words=100,
        max_font_size=25,
        scale=2,
        random_state=42
    ).generate(Negative_Word_Cloud_Analysis)

    wc_n = plt.figure(figsize=(7, 4))
    plt.imshow(wordcloud)
    plt.axis("off")
    plt.tight_layout(pad=0)

    wcn = StringIO()
    wc_n.savefig(wcn, format='svg')
    wcn.seek(0)
    plt.close(wc_n)
    print("Data Word_Cloud_Analysis....")

    # Review ratings
    rating_1 = df.loc[df['Star Rating'] == 1]
    rating_2 = df.loc[df['Star Rating'] == 2]
    rating_3 = df.loc[df['Star Rating'] == 3]
    rating_4 = df.loc[df['Star Rating'] == 4]
    rating_5 = df.loc[df['Star Rating'] == 5]

    r1_pos = rating_1.loc[rating_1["Sentiment"] == "Positive"]
    r1_neu = rating_1.loc[rating_1["Sentiment"] == "Neutral"]
    r1_neg = rating_1.loc[rating_1["Sentiment"] == "Negative"]
    r2_pos = rating_2.loc[rating_2["Sentiment"] == "Positive"]
    r2_neu = rating_2.loc[rating_2["Sentiment"] == "Neutral"]
    r2_neg = rating_2.loc[rating_2["Sentiment"] == "Negative"]
    r3_pos = rating_3.loc[rating_3["Sentiment"] == "Positive"]
    r3_neu = rating_3.loc[rating_3["Sentiment"] == "Neutral"]
    r3_neg = rating_3.loc[rating_3["Sentiment"] == "Negative"]
    r4_pos = rating_4.loc[rating_4["Sentiment"] == "Positive"]
    r4_neu = rating_4.loc[rating_4["Sentiment"] == "Neutral"]
    r4_neg = rating_4.loc[rating_4["Sentiment"] == "Negative"]
    r5_pos = rating_5.loc[rating_5["Sentiment"] == "Positive"]
    r5_neu = rating_5.loc[rating_5["Sentiment"] == "Neutral"]
    r5_neg = rating_5.loc[rating_5["Sentiment"] == "Negative"]

    Rating_list = [[len(r1_pos), len(r1_neu), len(r1_neg)], [len(r2_pos), len(r2_neu), len(r2_neg)],
                   [len(r3_pos), len(r3_neu), len(r3_neg)], [len(r4_pos), len(r4_neu), len(r4_neg)],
                   [len(r5_pos), len(r5_neu), len(r5_neg)]]

    star_df = pd.DataFrame([[Rating_list[0][0], Rating_list[0][1], Rating_list[0][2]],
                            [Rating_list[1][0], Rating_list[1][1], Rating_list[1][2]],
                            [Rating_list[2][0], Rating_list[2][1], Rating_list[2][2]],
                            [Rating_list[3][0], Rating_list[3][1], Rating_list[3][2]],
                            [Rating_list[4][0], Rating_list[4][1], Rating_list[4][2]]],
                           columns=['Positive', 'Neutral', 'Negative'])

    star_df_csv = star_df
    star_df_csv["Category"] = ["Star 1", "Star 2", "Star 3", "Star 4", "Star 5"]
    star_df_csv = star_df_csv.reindex(columns=['Category', 'Positive', 'Neutral', 'Negative'])
    star_df_csv.to_excel(writer, sheet_name="Star Rating", index=False)
    p = [int(x) for x in star_df["Positive"]]
    print(p)

    """workbook = writer.book
    star_chart = workbook.add_chart({'type': 'column'})
    star_chart.add_series({'values': '=Star Rating!$B$2:$B$8'})
    star_chart.add_series({'values': 'list(star_df["Neutral"])'})
    star_chart.add_series({'values': 'list(star_df["Negative"])'})

    worksheet = writer.sheets['Star Rating']
    worksheet.insert_chart('Star Rating', star_chart)"""

    pos_state_city = df.loc[df['Sentiment'] == "Positive"]
    neg_state_city = df.loc[df['Sentiment'] == "Negative"]
    top_pos_state = pd.DataFrame(
        pos_state_city["State"].value_counts().rename_axis('State').reset_index(name='Counts').head(5))
    top_pos_state['State'] = top_pos_state['State'].replace(us_state_to_abbrev)
    top_neg_state = pd.DataFrame(
        neg_state_city["State"].value_counts().rename_axis('State').reset_index(name='Counts').head(5))
    top_neg_state['State'] = top_neg_state['State'].replace(us_state_to_abbrev)
    top_pos_city = pd.DataFrame(
        pos_state_city["City"].value_counts().rename_axis('City').reset_index(name='Counts').head(5))
    top_neg_city = pd.DataFrame(
        neg_state_city["City"].value_counts().rename_axis('City').reset_index(name='Counts').head(5))

    top_pos_state.to_excel(writer, sheet_name="Top Positive States", index=False)
    top_neg_state.to_excel(writer, sheet_name="Top Negative States", index=False)
    top_pos_city.to_excel(writer, sheet_name="Top Positive City", index=False)
    top_neg_city.to_excel(writer, sheet_name="Top Negative City", index=False)

    date_based = pd.DataFrame(df["Review Date"].value_counts().rename_axis("Date").reset_index()).drop("Review Date",
                                                                                axis=1)
    date_based["Positive"] = list(df_Postive["Review Date"].value_counts())
    date_based["Neutral"] = list(df_Neutral["Review Date"].value_counts())
    date_based["Negative"] = list(df_Negative["Review Date"].value_counts())
    date_based = date_based.sort_values(by="Date").reset_index(drop=True)

    date_based.to_excel(writer, sheet_name="Date Based reviews", index=False)

    subset = df[df['Sentiment'] == "Positive"]
    dist_pos = list(subset["Compound_Score"])
    star_pos = list(star_df["Positive"])
    star_neu = list(star_df["Neutral"])
    star_neg = list(star_df["Negative"])
    dates = list(date_based["Date"])
    date_pos = list(date_based["Positive"])
    date_neu = list(date_based["Neutral"])
    date_neg = list(date_based["Negative"])
    print("Review ratings Analysis....")

    # Freq Positive
    positive_words = freq_words(df_Postive['reviews'], 20)
    pos_word_list = list(positive_words['word'])
    pos_freq_list = join_for_review(pos_word_list, df_Postive['reviews'])

    reviews_21 = lemmatization_noun(pd.Series(list(positive_words["word"])).apply(lambda x: x.split()))
    reviews_freq = []
    for i in range(len(reviews_21)):
        if len(reviews_21[i]) != 0:
            reviews_freq.append(reviews_21[i][0])
    to_merge = pd.DataFrame(reviews_freq)
    to_merge.columns = ["word"]
    pos_freq = positive_words.merge(to_merge, on="word", how="inner")

    pos_freq.to_excel(writer, sheet_name="Top positive keywords", index=False)

    # Freq Negative
    negative_words = freq_words(df_Negative['reviews'], 20)

    reviews_21_neg = lemmatization_noun(pd.Series(list(negative_words["word"])).apply(lambda x: x.split()))
    reviews_freq_neg = []
    for i in range(len(reviews_21_neg)):
        if len(reviews_21_neg[i]) != 0:
            reviews_freq_neg.append(reviews_21_neg[i][0])
    to_merge_neg = pd.DataFrame(reviews_freq_neg)
    to_merge_neg.columns = ["word"]
    neg_freq = negative_words.merge(to_merge_neg, on="word", how="inner")

    neg_freq.to_excel(writer, sheet_name="Top negative keywords", index=False)

    for x in pos_freq_list:
        to_freq.append(x)

    word = [x for x in pos_freq['word']]
    count = [x for x in pos_freq['count']]
    (Pos_Freq.objects.all()).delete()
    for i in range(len(pos_freq)):
        Pos_Freq.objects.create(
            word=word[i],
            freq=count[i],
        )

    writer.close()

    return render(request, "index.html", {
        'wcp': wcp.getvalue(),
        'wcn': wcn.getvalue(),
        'pos_count': len(pos_review),
        'pos_per': int(round(len(pos_review) * 100 / len(df['Feedback']))),
        'neu_count': len(neu_review),
        'neu_per': int(round(len(neu_review) * 100 / len(df['Feedback']))),
        'neg_count': len(neg_review),
        'neg_per': int(round(len(neg_review) * 100 / len(df['Feedback']))),
        'top_pos_state': top_pos_state.values,
        'top_neg_state': top_neg_state.values,
        'top_pos_city': top_pos_city.values,
        'top_neg_city': top_neg_city.values,
        'dist_pos': dist_pos,
        'star_pos': star_pos,
        'star_neu': star_neu,
        'star_neg': star_neg,
        'dates': dates,
        'date_pos': date_pos,
        'date_neu': date_neu,
        'date_neg': date_neg,
        'table_ok': 1,
        'pos_freq_word': list(pos_freq['word'])[0:7],
        'pos_freq_count': list(pos_freq['count'])[0:7],
        'neg_freq_word': list(neg_freq['word'])[0:7],
        'neg_freq_count': list(neg_freq['count'])[0:7],

    })

def lemmatization_noun(texts):
    output = []
    for sent in texts:
        doc = nlp(" ".join(sent))
        output.append([token.lemma_ for token in doc if token.pos_ in ['NOUN']])
    return output

def charts_sample(request):
    return render(request, "chart.html")

def freq(request):
    return render(request, "freq.html", {
        "top_pos_words": Pos_Freq.objects.all(),
    })

def join_for_review(word_list, reviews):
    rev_new = []
    for x in word_list:
        in_rev = [x]
        for line in reviews:
            x = x.lower()
            line = line.lower()
            if x in line:
                in_rev.append(line)
        rev_new.append(in_rev)
    return rev_new

def dataset(request):
    table_data = pd.read_csv("table_data.csv")
    print(table_data.columns)
    date = list(table_data['Review Date'])
    city = list(table_data['City'])
    star = list(table_data['Star Rating'])
    review = list(table_data['Feedback'])
    sentiment = list(table_data['Sentiment'])

    (Table_data.objects.all()).delete()
    count = 1
    for i in range(len(sentiment)):
        if count < 21:
            count += 1
            Table_data.objects.create(
                date=date[i],
                city=city[i],
                star=star[i],
                review=review[i][0:30]+"...",
                sentiment=sentiment[i],
            )
        else:
            break
    records = {"records": Table_data.objects.all()}
    return render(request, "dataset.html", records)

def total_dataset(request):
    response = HttpResponse(open('table_data.csv', 'rb').read(), content_type='text/csv')
    response['Content-Length'] = os.path.getsize('table_data.csv')
    response['Content-Disposition'] = 'attachment; filename=%s' % 'table_data.csv'
    return response

def welcome(request):
    return render(request, "welcome.html")


import torch
import torch.nn as nn
import torch.nn.functional as F
from taming.modules.vqvae.quantize import GumbelQuantize
from einops import rearrange, repeat
from einops.layers.torch import Rearrange

class LayerNormFunction(torch.autograd.Function):

    @staticmethod
    def forward(ctx, x, weight, bias, eps):
        ctx.eps = eps
        N, C, H, W = x.size()
        mu = x.mean(1, keepdim=True)
        var = (x - mu).pow(2).mean(1, keepdim=True)
        y = (x - mu) / (var + eps).sqrt()
        ctx.save_for_backward(y, var, weight)
        y = weight.view(1, C, 1, 1) * y + bias.view(1, C, 1, 1)
        return y

    @staticmethod
    def backward(ctx, grad_output):
        eps = ctx.eps

        N, C, H, W = grad_output.size()
        y, var, weight = ctx.saved_variables
        g = grad_output * weight.view(1, C, 1, 1)
        mean_g = g.mean(dim=1, keepdim=True)

        mean_gy = (g * y).mean(dim=1, keepdim=True)
        gx = 1. / torch.sqrt(var + eps) * (g - y * mean_gy - mean_g)
        return gx, (grad_output * y).sum(dim=3).sum(dim=2).sum(dim=0), grad_output.sum(dim=3).sum(dim=2).sum(
            dim=0), None

class LayerNorm2d(nn.Module):
    def __init__(self, channels, eps=1e-6):
        super(LayerNorm2d, self).__init__()
        self.register_parameter('weight', nn.Parameter(torch.ones(channels)))
        self.register_parameter('bias', nn.Parameter(torch.zeros(channels)))
        self.eps = eps

    def forward(self, x):
        return LayerNormFunction.apply(x, self.weight, self.bias, self.eps)

class Attention(nn.Module):
    def __init__(self, dim, shuffle_rate, heads = 1, dim_head = 64):
        super().__init__()
        self.inner_dim = dim_head *  heads

        self.heads = heads
        self.scale = dim_head ** -0.5

        # self.conv1_1 = nn.Conv2d(in_channels=dim, out_channels = dim // shuffle_rate,
        #                          kernel_size=1, padding=0, stride=1, groups=1, bias=True)
        self.down = nn.PixelUnshuffle(shuffle_rate)
        self.attend = nn.Softmax(dim = -1)
        self.to_qkv = nn.Linear(dim * shuffle_rate**2, self.inner_dim * 3, bias = False)
        self.to_out = nn.Linear(self.inner_dim, dim * shuffle_rate**2)
        self.up = nn.PixelShuffle(shuffle_rate)

        # self.conv1_2 = nn.Conv2d(in_channels=dim // shuffle_rate, out_channels=dim,
        #                          kernel_size=1, padding=0, stride=1, groups=1, bias=True)

    def forward(self, x):
        #x = self.conv1_1(x)
        x = self.down(x)

        B, C, H, W = x.shape
        x = x.flatten(2).transpose(1, 2).contiguous()

        qkv = self.to_qkv(x).chunk(3, dim = -1)
        q, k, v = map(lambda t: rearrange(t, 'b n (h d) -> b h n d', h = self.heads), qkv)
        dots = torch.matmul(q, k.transpose(-1, -2)) * self.scale
        attn = self.attend(dots)
        out = torch.matmul(attn, v)
        out = rearrange(out, 'b h n d -> b n (h d)')
        x = self.to_out(out)

        x = x.transpose(1, 2).contiguous().view(B, C, H, W)

        x = self.up(x)
        #x = self.conv1_2(x)

        return x

# Convolution Attention Module (CAM)
class CAM(nn.Module):
    def __init__(self, dim, shuffle_rate, exp_rate = 2):
        super(CAM, self).__init__()
        self.dim = dim
        self.shuffle_rate = shuffle_rate
        self.conv1_1 = nn.Conv2d(in_channels=dim, out_channels=dim,
                      kernel_size=1, padding=0, stride=1, groups=1, bias=True)
        self.norm = LayerNorm2d(dim)
        self.conv = nn.Sequential(
            nn.Conv2d(in_channels=self.dim // 2, out_channels=dim // 2 * exp_rate,
                      kernel_size=3, padding=1, stride=1, groups=1, bias=True),
            nn.GELU(),
            nn.Conv2d(in_channels=dim // 2 * exp_rate, out_channels=dim // 2,
                      kernel_size=3, padding=1, stride=1, groups=1, bias=True)
        )
        self.att = Attention(dim=dim//2, shuffle_rate=shuffle_rate)
        self.conv1_2 = nn.Conv2d(in_channels=dim, out_channels=dim,
                      kernel_size=1, padding=0, stride=1, groups=1, bias=True)

    def forward(self, x):
        att_x, conv_x = torch.split(self.norm(self.conv1_1(x)), (self.dim // 2, self.dim // 2), dim=1)
        att_x = self.att(att_x)
        conv_x = self.conv(conv_x)
        x = self.conv1_2(torch.cat([att_x, conv_x], 1)) + x

        return x

#Dual-Path Feed-Forward Network (DP-FFN)
class DP_FFN(nn.Module):
    def __init__(self, dim, exp_rate = 2):
        super(DP_FFN, self).__init__()

        self.dim = dim

        self.norm = LayerNorm2d(dim)
        self.conv = nn.Sequential(
            nn.Conv2d(in_channels=dim // 2, out_channels=dim // 2 * exp_rate,
                      kernel_size=1, padding=0, stride=1, groups=1, bias=True),
            nn.Conv2d(in_channels=dim // 2 * exp_rate, out_channels=dim // 2 * exp_rate,
                      kernel_size=3, padding=1, stride=1, groups=dim//2*exp_rate, bias=True),
            nn.GELU()
        )
        self.linear = nn.Sequential(
            nn.Conv2d(in_channels=dim // 2, out_channels=dim // 2 * exp_rate,
                      kernel_size=1, padding=0, stride=1, groups=1, bias=True),
            nn.GELU()
        )

        self.conv1_1 = nn.Conv2d(in_channels=dim*exp_rate, out_channels=dim,
                      kernel_size=1, padding=0, stride=1, groups=1, bias=True)

    def forward(self, x):
        conv_x, linear_x = torch.split(self.norm(x), (self.dim//2, self.dim//2), dim=1)
        conv_x = self.conv(conv_x)
        linear_x = self.linear(linear_x)
        x = self.conv1_1(torch.cat([conv_x, linear_x], 1)) + x

        return x

# Multi-Head Blend Block (MHBB)
class MHBBlock(nn.Module):
    def __init__(self, dim, n_head, shuffle_rate, exp_rate):
        super(MHBBlock, self).__init__()
        self.n_head = n_head
        self.cam = [CAM(dim // n_head, shuffle_rate) for _ in range(n_head)]
        self.cam = nn.ModuleList(self.cam)
        self.conv = nn.Conv2d(in_channels=dim, out_channels=dim, kernel_size=1, padding=0, stride=1, groups=1, bias=True)
        self.dp_ffn = DP_FFN(dim , exp_rate)

    def forward(self, x):
        inputs = torch.chunk(x, self.n_head, 1)
        features = []
        for i in range(self.n_head):
            feature = self.cam[i](inputs[i])
            features.append(feature)
        x = torch.cat([i for i in features], 1)
        x = self.conv(x)
        x = self.dp_ffn(x)

        return x

# Mapping Network
class MapNet(nn.Module):
    def __init__(self, dim, nz=256):
        super(MapNet, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(in_channels=dim, out_channels=nz,
                      kernel_size=1, padding=0, stride=1, groups=1, bias=True),
            nn.Conv2d(in_channels=nz, out_channels=nz,
                      kernel_size=3, padding=1, stride=1, groups=nz, bias=True),
            nn.GELU(),
            nn.Conv2d(in_channels=nz, out_channels=nz,
                      kernel_size=1, padding=0, stride=1, groups=1, bias=True),
            nn.Conv2d(in_channels=nz, out_channels=nz,
                      kernel_size=3, padding=1, stride=1, groups=nz, bias=True),
            nn.GELU()
        )
        self.att = nn.Sequential(
            Attention(dim=nz, shuffle_rate=2),
            Attention(dim=nz, shuffle_rate=2)
        )

        self.quantize = GumbelQuantize(nz, nz,
                                       n_embed=8192,
                                       kl_weight=1.0e-08, temp_init=1.0,
                                       remap=None)

    def forward(self, x):
        x = self.conv(x)
        x = self.att(x)
        quant, emb_loss, info = self.quantize(x)

        return quant

#Restoration Network
class RAHC(nn.Module):

    def __init__(self, img_channel=3, width=64, nz=256, middle_blk_num=8, exp_rate=2, enc_blk_nums=[2, 4, 6],
                 dec_blk_nums=[2, 2, 2], head_nums=[1, 2, 4, 8], shuffle_rates=[16, 8, 4, 2]):
        super().__init__()

        self.intro = nn.Conv2d(in_channels=img_channel, out_channels=width, kernel_size=3, padding=1, stride=1,
                               groups=1,
                               bias=True)
        self.ending = nn.Conv2d(in_channels=width, out_channels=img_channel, kernel_size=3, padding=1, stride=1,
                                groups=1,
                                bias=True)

        self.encoders = nn.ModuleList()
        self.decoders = nn.ModuleList()
        self.middle_pre = nn.ModuleList()
        self.middle_aft = nn.ModuleList()
        self.ups = nn.ModuleList()
        self.downs = nn.ModuleList()

        chan = width
        for i, num in enumerate(enc_blk_nums):
            self.encoders.append(
                nn.Sequential(
                    *[MHBBlock(chan, head_nums[i], shuffle_rates[i], exp_rate) for _ in range(num)]
                )
            )
            self.downs.append(
                nn.Conv2d(chan, 2 * chan, 2, 2)
            )
            chan = chan * 2

        self.middle_pre = \
            nn.Sequential(
                *[MHBBlock(chan, head_nums[-1], shuffle_rates[-1], exp_rate) for _ in range(middle_blk_num//2)]
            )

        self.mapping_network = MapNet(dim=chan, nz=nz)
        self.post_conv = nn.Conv2d(chan + nz, chan, 1)

        self.middle_aft = \
            nn.Sequential(
                *[MHBBlock(chan, head_nums[-1], shuffle_rates[-1], exp_rate) for _ in range(middle_blk_num // 2)]
            )

        for i, num in enumerate(dec_blk_nums):
            self.ups.append(
                nn.Sequential(
                    nn.Conv2d(chan, chan * 2, 1, bias=False),
                    nn.PixelShuffle(2)
                )
            )
            chan = chan // 2
            self.decoders.append(
                nn.Sequential(
                    *[MHBBlock(chan, head_nums[len(dec_blk_nums)-1-i], shuffle_rates[len(dec_blk_nums)-1-i], exp_rate) for _ in range(num)]
                )
            )

        self.padder_size = 2 ** len(self.encoders)

    def forward(self, inp):
        B, C, H, W = inp.shape
        inp = self.check_image_size(inp)

        x = self.intro(inp)

        encs = []

        for encoder, down in zip(self.encoders, self.downs):
            x = encoder(x)
            encs.append(x)
            x = down(x)

        mid_pre = self.middle_pre(x)
        f_rv = self.mapping_network(mid_pre.detach())
        x = self.middle_aft(self.post_conv(torch.cat([mid_pre, f_rv.detach()], 1)))

        for decoder, up, enc_skip in zip(self.decoders, self.ups, encs[::-1]):
            x = up(x)
            x = x + enc_skip
            x = decoder(x)

        x = self.ending(x)
        x = x + inp

        return x[:, :, :H, :W], f_rv

    def check_image_size(self, x):
        _, _, h, w = x.size()
        mod_pad_h = (self.padder_size - h % self.padder_size) % self.padder_size
        mod_pad_w = (self.padder_size - w % self.padder_size) % self.padder_size
        x = F.pad(x, (0, mod_pad_w, 0, mod_pad_h))
        return x

@torch.no_grad()
def default_init_weights(module_list, scale=1, bias_fill=0, **kwargs):
    """Initialize network weights.

    Args:
        module_list (list[nn.Module] | nn.Module): Modules to be initialized.
        scale (float): Scale initialized weights, especially for residual
            blocks. Default: 1.
        bias_fill (float): The value to fill bias. Default: 0
        kwargs (dict): Other arguments for initialization function.
    """
    if not isinstance(module_list, list):
        module_list = [module_list]
    for module in module_list:
        for m in module.modules():
            if isinstance(m, nn.Conv2d):
                init.kaiming_normal_(m.weight, **kwargs)
                m.weight.data *= scale
                if m.bias is not None:
                    m.bias.data.fill_(bias_fill)
            elif isinstance(m, nn.Linear):
                init.kaiming_normal_(m.weight, **kwargs)
                m.weight.data *= scale
                if m.bias is not None:
                    m.bias.data.fill_(bias_fill)

if __name__ == '__main__':
    net = RAHC().cuda()

    inp_shape = (3, 256, 256)

    from ptflops import get_model_complexity_info

    macs, params = get_model_complexity_info(net, inp_shape, verbose=False, print_per_layer_stat=False)

    params = float(params[:-3])
    macs = float(macs[:-4])

    print(macs, params)


"""Listing 2-3 to Listing 2-7
Written by Joshua Willman
Featured in "Beginning PyQt - A Hands-on Approach to GUI Programming, 2nd Ed."
"""

# Import necessary modules
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QLabel
from PyQt6.QtGui import QFont, QPixmap

class MainWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.initializeUI()

    def initializeUI(self):
        """Set up the application's GUI."""
        self.setGeometry(1170, 870, 720, 70)#(50, 50, 270, 450)
        self.setWindowTitle("Tarjeta de Identificacion")

        self.setUpMainWindow()
        self.show()

    def setUpMainWindow(self):
        """Create the labels to be displayed in the window."""
        self.createImageLabels()

        user_label = QLabel(self)
        user_label.setText("Klaus Iohannis")
        user_label.setFont(QFont("Arial", 20))
        user_label.move(40, 140)

        skills_label = QLabel(self)
        skills_label.setText("Presidente")
        skills_label.setFont(QFont('Arial', 17))
        skills_label.move(15, 170)

        languages_label = QLabel(self)
        languages_label.setText("Rumania")
        languages_label.move(15, 195)

        bio_label = QLabel(self)
        bio_label.setText("Bibliografia")
        bio_label.setFont(QFont("Arial", 17))
        bio_label.move(15, 220)

        about_label = QLabel(self)
        about_label.setText("Soy un político rumano con raíces alemanas ,\
            quien actualmente ostenta el cargo de presidente de Rumanía.")
        about_label.setWordWrap(True)
        about_label.move(15, 245)

        experience_label = QLabel(self)
        experience_label.setText("Experiencia")
        experience_label.setFont(QFont("Arial", 17))
        experience_label.move(15, 295)

        developer_label = QLabel(self)
        developer_label.setText("Presidente de Rumania")
        developer_label.move(15, 320)

        dev_dates_label = QLabel(self)
        dev_dates_label.setText("Dic 2014 - Present")
        dev_dates_label.setFont(QFont("Arial", 10))
        dev_dates_label.move(15, 340)

        driver_label = QLabel(self)
        driver_label.setText("Alcalde de Sibiu")
        driver_label.move(15, 360)

        driver_dates_label = QLabel(self)
        driver_dates_label.setText("Jun 2000 - Dic 2014")
        driver_dates_label.setFont(QFont("Arial", 10))
        driver_dates_label.move(15, 380)

        Lider = QLabel(self)
        Lider.setText("Líder del Partido Nacional Liberal")
        Lider.move(15, 400)

        lider_dates_label = QLabel(self)
        lider_dates_label.setText("Jun 2014 - Dic 2014")
        lider_dates_label.setFont(QFont("Arial", 10))
        lider_dates_label.move(15, 420)

    def createImageLabels(self):
        """Open image files and create image labels."""
        images = ["images/skyblue.png",
                  "images/profile_image.jpg"]

        for image in images:
            try:
                with open(image):
                    label = QLabel(self)
                    pixmap = QPixmap(image)
                    label.setPixmap(pixmap)
                    if image == "images/profile_image.jpg":
                        label.move(80, 20)
            except FileNotFoundError as error:
                print(f"Image not found.\nError: {error}")

# Run program
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())


import turtle

colors = ['red', 'purple', 'blue', 'green', 'yellow', 'orange']
t = turtle.Turtle()  # Create a turtle object

t.speed(0)
turtle.bgcolor('white')

for x in range(360):
    t.pencolor(colors[x % 6])
    t.width(x / 100 + 1)
    t.forward(x)
    t.left(59)


#!/usr/bin/python3
from functools import reduce

''' Write a program which returns a list of two tuples with (order number, total amount of order). '''

orders = [ [1, ("5464", 4, 9.99), ("8274",18,12.99), ("9744", 9, 44.95)],
           [2, ("5464", 9, 9.99), ("9744", 9, 44.95)],
           [3, ("5464", 9, 9.99), ("88112", 11, 24.99)],
           [4, ("8732", 7, 11.99), ("7733",11,18.99), ("88112", 5, 39.95)] ]

# b_list = reduce(lambda x: x if (x[0],  ,a_list)
a_list = reduce(lambda x, y: x + y, orders)
b_list = list(map(lambda x: x if isinstance(x, int) else x[1] * x[2], a_list))
c_list = []
d_list = []
c = reduce(lambda x, y: x if isinstance(x, int) or isinstance(y, int) else x + y, b_list)
del b_list[:1]
d = reduce(lambda n, m: n if isinstance(n, int) or isinstance(m, int) else n + m, b_list)
c_list.append(c)
d_list.append(d)
#b_list = list(map(lambda x: x[1] * x[2], reduce(lambda x, y: x + y, a_list)))

print("{}\n".format(a_list))
print("{}".format(b_list))
print("{}".format(c_list))
print("{}".format(d_list))


import media
import fresh_tomatoes

# Movie() args are in format title, storyline, poster url, and youtube url

annie_hall = media.Movie(
    "Annie Hall",
    """Neurotic New York comedian Alvy Singer falls in love
    with the ditzy Annie Hall.""",
    "https://sc-events.s3.amazonaws.com/4181858/main.jpg",
	"https://www.youtube.com/watch?v=OqVgCfZX-yE")

kill_bill = media.Movie(
	"Kill Bill Vol 1 & Vol 2",
	"""The Bride wakens from a four-year coma.
	The child she carried in her womb is gone.
	Now she must wreak vengeance on the team of assassins who betrayed her -
	a team she was once part of.""",
	"""https://i.pinimg.com/736x/64/82/ef/6482ef51ce0b437986ec477e0d46f30c--quentin-tarantino-tarantino-movies.jpg""",  # noqa
	"https://www.youtube.com/watch?v=ot6C1ZKyiME")

arsenic_and_old_lace = media.Movie(
	"Arsenic and Old Lace",
	"""A drama critic learns on his wedding day that his
	beloved maiden aunts are homicidal maniacs,
	and that insanity runs in his family.""",
	"http://avalonlibrary.org/wp-content/uploads/2014/04/arsenic-and-old-lace.jpg",  # noqa
	"https://www.youtube.com/watch?v=GCWBDwkhGN0")

# All movies above are compiled into a list and passed onto open_movies_page()
movies_list = [
	annie_hall,
	kill_bill,
	arsenic_and_old_lace
]

fresh_tomatoes.open_movies_page(movies_list)


import torch
import torch.optim as optim
from rlkit.torch.torch_rl_algorithm import TorchTrainer
from collections import OrderedDict
import rlkit.torch.pytorch_util as ptu

class TorchEncDecAWACTrainer(TorchTrainer):
    def __init__(
            self,
            policy,
            policy_lr,
            qf1,
            target_qf1,
            qf2,
            target_qf2,
            qf_lr,
            vae,
            latent_size,
            optimizer_class=optim.Adam,
            beta=0.01,
            temp=0.3,
            discount=0.99,
            sample=True,
            soft_target_tau=1e-2,
            target_update_period=1,
            incl_state=False
    ):
        super().__init__()

        self.policy = policy
        self.policy_optimizer = optimizer_class(
            self.policy.parameters(),
            lr=policy_lr,
        )
        self.eval_statistics = OrderedDict()

        self.vae = vae
        self.qf1 = qf1
        self.target_qf1 = target_qf1
        self.qf2 = qf2
        self.target_qf2 = target_qf2
        self.qf1_optimizer = optimizer_class(self.qf1.parameters(), lr=qf_lr)
        self.qf2_optimizer = optimizer_class(self.qf2.parameters(), lr=qf_lr)
        self.encoder_optimizer = optimizer_class(
            self.vae.encoder.parameters(),
            lr=policy_lr,
        )
        self.beta = beta
        self.discount = discount
        self.latent_size = latent_size
        self.sample = sample
        self.temp = temp
        self.qf_criterion = torch.nn.MSELoss()
        self._n_train_steps_total = 0
        self.soft_target_tau = soft_target_tau
        self.target_update_period = target_update_period
        self.incl_state = incl_state

    def train_from_torch(self, batch):
        obs = batch['observations']
        rewards = batch['rewards']
        terminals = batch['terminals']
        actions = batch['actions']
        next_obs = batch['next_observations']
        curr_goal = batch['curr_goal']
        next_goal = batch['next_goal']
        curr_goal_set = batch.get('curr_goal_set')
        next_goal_set = batch.get('next_goal_set')

        batch_size = obs.shape[0]
        has_goal_set = curr_goal_set is not None

        curr_encoder_features = [curr_goal]
        next_encoder_features = [next_goal]
        if self.incl_state:
            encoder_obs = batch.get('curr_encoder_obs', obs)
            next_encoder_obs = batch.get('next_encoder_obs', next_obs)
            curr_encoder_features.append(encoder_obs)
            next_encoder_features.append(next_encoder_obs)
            if has_goal_set:
                curr_encoder_features.append(curr_goal_set.reshape((batch_size, -1)))
                next_encoder_features.append(next_goal_set.reshape((batch_size, -1)))

        eps = torch.normal(ptu.zeros((batch_size, self.latent_size)), 1) if self.sample else None
        curr_latent, kl_loss = self.vae.sample(torch.cat(curr_encoder_features, dim=1), eps=eps, return_kl=True)
        next_latent = self.vae.sample(torch.cat(next_encoder_features, dim=1), eps=None, return_kl=False)

        next_latent = next_latent.detach()

        """
        Policy and Alpha Loss
        """
        if has_goal_set:
            curr_goal_set_flat = curr_goal_set.reshape((batch_size, -1))
            curr_policy_features = [obs, curr_goal_set_flat, curr_latent]
        else:
            curr_policy_features = [obs, curr_latent]

        dist = self.policy(*curr_policy_features)

        log_pi = dist.log_prob(actions)

        new_obs_actions, _ = dist.rsample_and_logprob()

        if has_goal_set:
            curr_qf_features = [obs, curr_goal_set_flat, curr_goal, actions]
            new_qf_features = [obs, curr_goal_set_flat, curr_goal, new_obs_actions]
            next_goal_set_flat = next_goal_set.reshape((batch_size, -1))
            next_policy_features = [next_obs, next_goal_set_flat, next_latent]
        else:
            curr_qf_features = [obs, curr_goal, actions]
            new_qf_features = [obs, curr_goal, new_obs_actions]
            next_policy_features = [next_obs, next_latent]

        q_estimates = self.qf1(*curr_qf_features)
        value_estimates = self.qf1(*new_qf_features)
        advantages = q_estimates - value_estimates
        policy_loss = -(log_pi * torch.exp(advantages / self.temp).detach().reshape(batch_size)).mean()

        q1_pred = self.qf1(*curr_qf_features)
        q2_pred = self.qf2(*curr_qf_features)
        next_dist = self.policy(*next_policy_features)

        new_next_actions, new_log_pi = next_dist.rsample_and_logprob()

        if has_goal_set:
            next_qf_features = [next_obs, next_goal_set_flat, next_goal, new_next_actions]
        else:
            next_qf_features = [next_obs, next_goal, new_next_actions]

        target_q_values = torch.min(
            self.target_qf1(*next_qf_features),
            self.target_qf2(*next_qf_features),
        )

        q_target = rewards + (1. - terminals) * self.discount * target_q_values
        qf1_loss = self.qf_criterion(q1_pred, q_target.detach())
        qf2_loss = self.qf_criterion(q2_pred, q_target.detach())

        """
        Update networks
        """
        self.policy_optimizer.zero_grad()
        self.encoder_optimizer.zero_grad()
        (policy_loss + self.beta * kl_loss).backward()
        self.policy_optimizer.step()
        self.encoder_optimizer.step()

        self.qf1_optimizer.zero_grad()
        qf1_loss.backward()
        self.qf1_optimizer.step()

        self.qf2_optimizer.zero_grad()
        qf2_loss.backward()
        self.qf2_optimizer.step()

        self._n_train_steps_total += 1
        self.try_update_target_networks()

    def try_update_target_networks(self):
        if self._n_train_steps_total % self.target_update_period == 0:
            self.update_target_networks()

    def update_target_networks(self):
        ptu.soft_update_from_to(
            self.qf1, self.target_qf1, self.soft_target_tau
        )
        ptu.soft_update_from_to(
            self.qf2, self.target_qf2, self.soft_target_tau
        )

    @property
    def networks(self):
        return [self.policy, self.qf1, self.qf2, self.target_qf1, self.target_qf2, self.vae]

    def get_snapshot(self):
        return dict(
            policy=self.policy,
            qf1=self.qf1,
            qf2=self.qf2,
            target_qf1=self.qf1,
            target_qf2=self.qf2,
            vae=self.vae
        )

    def get_diagnostics(self):
        return self.eval_statistics


from __future__ import annotations
from typing import TYPE_CHECKING

# Imports utilisés uniquement dans les annotations
if TYPE_CHECKING:
    from Old_Jeu.Controleur import Controleur
    from Old_Jeu.Labyrinthe.Structure_spatiale.Direction import Direction
    from Old_Jeu.Labyrinthe.Structure_spatiale.Position import Position

# Imports des classes parentes
from Old_Jeu.Entitee.Agissant.Humain.Humain import Humain

class Codeur(Humain): #Le cinquième humain du jeu, à l'étage 4 (répond au nom de Dev, quand Il n'est pas occupé à programmer un autre jeu)
    """Ma classe."""
    def __init__(self,controleur:Controleur,position:Position):

        self.identite = 'codeur'
        self.place = 4

        Humain.__init__(self,controleur,self.identite,1,1,position) #La notion de niveau n'a pas d'emprise sur Dev... Il peut modifier son niveau simple 'self.niveau = '

        self.appreciations = [5,0,0,0,0,0,0,0,0,0]

    def fuite(self,degats:float=0):
        return False

    def start_dialogue(self): #On commence un nouveau dialogue !
        #On initialise nos attributs
        self.replique_courante = 0
        #La plupart dépendent du dialogue
        if self.dialogue == -1: #Le joueur est venu nous voir de son propre chef (c'est la seule option pour parler à Dev dans le tuto)
            self.replique = "dialogue-1phrase1"
            self.repliques = ["dialogue-1reponse1.1","dialogue-1reponse1.2"]
        elif self.dialogue == -2: #Le joueur nous a dit qu'il s'était perdu
            self.replique = "dialogue-2phrase1"
            self.repliques = ["dialogue-2reponse1.1","dialogue-2reponse1.2"]
        elif self.dialogue == -3: #Le joueur ne s'intéresse qu'aux combats
            self.replique = "dialogue-3phrase1"
            self.repliques = ["dialogue-3reponse1.1"]
        elif self.dialogue == -4: #Le joueur est revenu mentir
            self.replique = "dialogue-4phrase1"
            self.repliques = ["dialogue-4reponse1.1"]
        elif self.dialogue == -5: #Le joueur a écouté nos conseils
            self.replique = "dialogue-5phrase1"
            self.repliques = ["dialogue-5reponse1.1","dialogue-5reponse1.2"]

    def interprete(self,replique:str):
        assert isinstance(self.controleur.joueur, Humain)

        #Premier dialogue
        #Le joueur arrive vers Dev
        if replique == "dialogue-1reponse1.1":
            self.replique="dialogue-1phrase1.1"
            self.repliques = ["dialogue-1reponse1.1.1"]
        elif replique == "dialogue-1reponse1.1.1":
            self.end_dialogue(-2)
        elif replique == "dialogue-1reponse1.2":
            self.replique="dialogue-1phrase1.2"
            self.repliques = ["dialogue-1reponse1.2.1","dialogue-1reponse1.2.2"]
        elif replique == "dialogue-1reponse1.2.1":
            self.replique="dialogue-1phrase1.2.1"
            self.repliques = ["dialogue-1reponse1.2.1.1"]
        elif replique == "dialogue-1reponse1.2.1.1":
            self.end_dialogue(-3)
        elif replique == "dialogue-1reponse1.2.2":
            self.replique="dialogue-1phrase1.2.2"
            self.repliques = ["dialogue-1reponse1.2.2.1"]
        elif replique == "dialogue-1reponse1.2.2.1":
            self.appreciations[self.controleur.joueur.place] += 0.5
            self.end_dialogue(-5)

        #Dialogue par défaut -2
        elif replique == "dialogue-2reponse1.1":
            self.replique="dialogue-2phrase1.1"
            self.repliques = ["dialogue-2reponse1.1.1"]
        elif replique == "dialogue-2reponse1.1.1":
            self.end_dialogue(-2)
        elif replique == "dialogue-2reponse1.2":
            self.replique="dialogue-2phrase1.2"
            self.repliques = ["dialogue-2reponse1.2.1"]
        elif replique == "dialogue-2reponse1.2.1":
            self.replique="dialogue-2phrase1.2.1"
            self.repliques = ["dialogue-2reponse1.2.1.1"]
        elif replique == "dialogue-2reponse1.2.1.1":
            self.replique="dialogue-2phrase1.2.1.1"
            self.repliques = ["dialogue-2reponse1.2.1.1.1"]
        elif replique == "dialogue-2reponse1.2.1.1.1":
            self.end_dialogue(-4)

        #Dialogue par défaut -3
        elif replique == "dialogue-3reponse1.1":
            self.end_dialogue(-3)

        #Dialogue par défaut -4
        elif replique == "dialogue-4reponse1.1":
            self.end_dialogue(-4)

        #Dialogue par défaut -5
        elif replique == "dialogue-5reponse1.2":
            self.replique="dialogue-5phrase1.2"
            self.repliques = ["dialogue-5reponse1.2.1"]
        elif replique == "dialogue-5reponse1.2.1":
            self.end_dialogue(-5)
        elif replique == "dialogue-5reponse1.1":
            self.replique="dialogue-5phrase1.1"
            self.repliques = ["dialogue-5reponse1.1.1"]
        elif replique == "dialogue-5reponse1.1.1":
            self.end_dialogue(-5)

        else:
            self.end_dialogue(self.dialogue)
            print("Je ne connais pas cette réplique !")

        self.replique_courante = 0

    def get_replique(self,code:str):
        return REPLIQUES_CODEUR[code]

    def get_skin(self):
        return SKIN_CODEUR

    def get_skins_vue(self):
        return [SKIN_CODEUR_VUE]

    def get_texte_descriptif(self):
        return ["Vous voulez bien éviter de fouiller la vie privée des gens ?"]

# Imports utilisés dans le code:
from Old_Affichage.Skins.Skins import SKIN_CODEUR, SKIN_CODEUR_VUE
from Old_Jeu.Dialogues.Dialogues_codeur import REPLIQUES_CODEUR


from random import random, uniform
# from tqdm import tqdm
import numpy as np

# visualisation
import seaborn as sns
import matplotlib.pyplot as plt

# SPEED
# from multiprocessing import Pool

# Nodes are required to have the following values:
# name
# decision - takes a value from [-1, 0, 1] (decline, undecided, buy))
# qexpectation - float between 0 and 1
# Percolation threshold = pc = 0.595

import igraph as ig
from random import uniform

class Model:
    # for lattice:
    def __init__(self, side_size: int):
        self.side_size = side_size
        self.graph = self._init_lattice()
        sx = side_size - 1
        sy = int(side_size / 2)
        self.graph.vs.find(f'{sx},{int(sy)}')['decision'] = 1

    # PRIVATE:
    def _init_lattice(self):
        lattice = ig.Graph()
        for i in range(self.side_size):
            for j in range(self.side_size):
                lattice.add_vertex(name=f"{i},{j}",
                                   qexpectation=random(),
                                   decision=0)
        for i in range(self.side_size - 1):
            for j in range(self.side_size - 1):
                lattice.add_edge(f"{i},{j}", f"{i + 1},{j}")
                lattice.add_edge(f"{i},{j}", f"{i},{j + 1}")
        for i in range(self.side_size - 1):
            lattice.add_edge(f"{i},{self.side_size - 1}", f"{i + 1},{self.side_size - 1}")
            lattice.add_edge(f"{self.side_size - 1},{i}", f"{self.side_size - 1},{i + 1}")
        return lattice

    def _decision(self, node, qexp, Q):
        #return qexp - (node * 0.05) < Q
        return qexp < Q

    # PUBLIC:
    def get_GC_size(self):
        return len(self.graph.vs.select(decision=1))

    def one_step(self, q):
        nodes = self.graph.vs.select(decision=1)  # Get nodes that bought product
        for node in nodes:  # iterate over each node
            neighbors = list(
                (filter(lambda x: x['decision'] == 0, node.neighbors())))  # Get its neighbors that not decided
            for neighbor in neighbors:  # iterate over each neighbor
                if self._decision(len([x for x in neighbor.neighbors() if x['decision'] == 1]), random(), q):
                    neighbor['decision'] = 1  # customer buys product
                else:
                    neighbor['decision'] = -1  # customer doesn't buy product

    def steps(self, prev_n: [ig.Vertex], q: float):
        if not prev_n:
            pass
        else:
            next_n = set()
            for n in prev_n:
                neighbours = n.neighbors()
                if self._decision(len([x for x in neighbours if x['decision'] == 1]), random(), q):
                    n['decision'] = 1
                    next_n.update(set(neighbours))
                else:
                    n['decision'] = -1
            next_n = list((filter(lambda x: x['decision'] == 0, next_n)))
            self.steps(next_n, q)

    def lattice_to_array(self):
        array = []
        for i in range(self.side_size):
            row = []
            for j in range(self.side_size):
                row.append(self.graph.vs.find(f'{i},{j}')['decision'])
            array.append(row)
        return array

    # def print_lattice(self):
    #     for i in range(self.side_size):
    #         for j in range(self.side_size):
    #             print(self.graph.vs.find(f'{i},{j}')['decision'], end=' ')
    #         print('')


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr  3 16:24:48 2018

@author: yiwei
"""

for i in range(1,int(input())+1):
	s, k = input().split()
	k = int(k)
	t = 0
	for j in range(len(s) - k + 1):
		# print(s)
		if s[j] == '-':
			s = s[:j] + ''.join('-+'[p == '-'] for p in s[j: j + k]) + s[j + k:]
			t += 1
	if '-' in s:
		t = 'IMPOSSIBLE'
	print('Case #{}: {}'.format(i, t))


# -*- coding: utf-8 -*-
import string
import sys
import math

import pygame
from pygame.locals import *

from config import *

class BandaBase(pygame.sprite.Sprite):

    def __init__(self, binary):
        pygame.sprite.Sprite.__init__(self)
        self.title = u"Banda Base"
        self.binary = binary
        self.size = 200
        self.step = 50
        self.ytopmargin = 60
        self.ybottommargin = 20
        self.amp = self.size - self.ytopmargin - self.ybottommargin
        self.bottom =  self.size - self.ybottommargin
        self.image = pygame.Surface((WINDOW[0], self.size))
        self.rect = self.image.get_rect().move(0,200)

    def update(self):
        self.image.fill(COLOR2)
        font = pygame.font.Font(None, 40)
        name = font.render(self.title, True, BLACK)
        self.image.blit(name, (10,10))
        x = self.step
        y = self.bottom
        self._update(x, y)

    def _update(self, x, y):
        for bit in self.binary.binary:
            if bit == '0':
                if y == self.ytopmargin:
                    pygame.draw.line(self.image, BLACK, (x,y), (x, self.bottom), 2)
                    y = self.bottom
                pygame.draw.line(self.image, BLACK, (x,y), (x + self.step, y), 2)
            else:   # bit == '1'
                if y != self.ytopmargin:
                    pygame.draw.line(self.image, BLACK, (x,y), (x, self.ytopmargin), 2)
                    y = self.ytopmargin
                pygame.draw.line(self.image, BLACK, (x,y), (x + self.step, y), 2)
            x += self.step

class CodificacionManchester(BandaBase):

    def __init__(self, binary):
        '''
        Los valores 1 o 0 se identifican por el flanco creciento o decreciente
        de la señal y no por el valor muestreado del pulso.
        '''
        super(CodificacionManchester, self).__init__(binary)
        self.title = u"Codificación Manchester"

    def _update(self, x, y):
        for bit in self.binary.binary:
            if bit == '0':
                if y != self.ytopmargin:
                    #si está abajo, primero subir a señal
                    pygame.draw.line(self.image, BLACK, (x,y), (x, self.ytopmargin), 2)
                    y = self.ytopmargin
                pygame.draw.line(self.image, BLACK, (x,y), (x + self.step / 2, y), 2)
                x += self.step / 2
                pygame.draw.line(self.image, BLACK, (x,y), (x, self.bottom), 2)
                y = self.bottom
                pygame.draw.line(self.image, BLACK, (x,y), (x + self.step / 2, y), 2)
                x += self.step / 2
            else:   # bit == '1'
                if y == self.ytopmargin:
                    #si está arriba, primero bajar la señal
                    pygame.draw.line(self.image, BLACK, (x,y), (x, self.bottom), 2)
                    y = self.bottom
                pygame.draw.line(self.image, BLACK, (x,y), (x + self.step / 2, y), 2)
                x += self.step / 2
                pygame.draw.line(self.image, BLACK, (x,y), (x, self.ytopmargin), 2)
                y = self.ytopmargin
                pygame.draw.line(self.image, BLACK, (x,y), (x + self.step / 2, y), 2)
                x += self.step / 2

class CodificacionAMI(BandaBase):

    def __init__(self, binary):
        '''
        AMI o Alternate Mark Inversion es una codificacion del tipo bipolar por que
        genera un valor +V o -V alternado a los valores binarios 1. También es llamada
        Bipolar NRZ (no retorno a cero).
        '''
        super(CodificacionAMI, self).__init__(binary)
        self.title = u"Codificación AMI"
        self.ycero = (self.ytopmargin + self.bottom) / 2

    def _update(self, x, y):
        uno = 1
        for bit in self.binary.binary:
            if bit == '0':
                if y in (self.ytopmargin, self.bottom):
                    #volver a cero
                    pygame.draw.line(self.image, BLACK, (x,y), (x, self.ycero), 2)
                    y = self.ycero
                pygame.draw.line(self.image, BLACK, (x,y), (x + self.step, y), 2)
            else:   # bit == '1'
                if uno == 1:
                    #subir
                    pygame.draw.line(self.image, BLACK, (x,y), (x, self.ytopmargin), 2)
                    y = self.ytopmargin
                else:   #-1
                    #bajar
                    pygame.draw.line(self.image, BLACK, (x,y), (x, self.bottom), 2)
                    y = self.bottom
                #pulso
                pygame.draw.line(self.image, BLACK, (x,y), (x + self.step, y), 2)
                uno *= -1   #alternar
            x += self.step

class CodificacionHDB3(BandaBase):

    def __init__(self, binary):
        '''
        Binario de alta densidad de 3 ceros permitidos.
        '''
        super(CodificacionManchester, self).__init__(binary)
        self.title = u"Codificación HDB3"

    def _update(self, x, y):
        pass

class ModulacionFrecuencia(pygame.sprite.Sprite):

    def __init__(self, binary):
        pygame.sprite.Sprite.__init__(self)
        self.binary = binary
        self.size = 200
        self.step = 50
        self.ytopmargin = 50
        self.ybottommargin = 20
        self.amp = self.size - self.ytopmargin - self.ybottommargin
        self.bottom =  self.size - self.ybottommargin
        self.image = pygame.Surface((WINDOW[0], self.size))
        self.rect = self.image.get_rect().move(0,200 + self.size)

    def update(self):
        self.image.fill(COLOR1)
        font = pygame.font.Font(None, 40)
        name = font.render(u"Modulación en frecuencia", True, BLACK)
        self.image.blit(name, (10,10))
        x = self.step
        y = self.bottom
        #for bit in self.binary.binary:
            #if bit == '0':
                #self._draw_sin(1, x)
                #x += self.step
            #else:   # bit == '1'
                #self._draw_sin(1, x)
                #x += self.step

    def _draw_sin(self, freq, x1):
        definicion = 1
        x2 = x1 + self.step
        _sin = self._gen_sin(x1, x2)
        for i,j in zip(range(x1, x2), range(x1 + 1, x2 + 1)):
            y1 = self.amp - _sin(i) + self.ytopmargin
            y2  = self.amp - _sin(j) + self.ytopmargin
            pygame.draw.line(self.image, BLACK, (i,y1), (j,y2), 2)

    def _gen_sin(self, x1, x2):
        return lambda i: math.sin((i - x1) / float((x2 - x1)) * math.pi) * self.amp

class ModulacionCuadratura(pygame.sprite.Sprite):

    def __init__(self, binary):
        pygame.sprite.Sprite.__init__(self)
        self.binary = binary
        self.size = 150
        self.image = pygame.Surface((WINDOW[0], self.size))
        self.image.fill(COLOR1)
        font = pygame.font.Font(None, 40)
        name = font.render(u"Modulación en cuadratura", True, BLACK)
        self.image.blit(name, (0,0))
        self.rect = self.image.get_rect().move(0,200 + self.size)

    def update(self):
        pass

class TestCod(pygame.sprite.Sprite):

    def __init__(self, binary):
        pygame.sprite.Sprite.__init__(self)
        self.binary = binary
        self.size = 55
        self.ideal = self.get_ideal(self.binary.binary)
        self.image = pygame.Surface((self.size, self.size))

    def update(self):
        font = pygame.font.Font(None, self.size)
        self.ideal = self.get_ideal(self.binary.binary)
        self.image = font.render("Ideal: %s" % self.ideal, True, BLACK)
        self.rect = self.image.get_rect().move(200,200)

    def get_ideal(self, binary):
        def t(i):
            if i == '1':
                return '-'
            else:
                return '_'
        return "".join([t(x) for x in binary])

class Binary(pygame.sprite.Sprite):

    def __init__(self, ascii):
        pygame.sprite.Sprite.__init__(self)
        self.ascii = ascii
        self.size = 55
        self.binary = self.get_binary(self.ascii.ascii)
        self.image = pygame.Surface((self.size, self.size))

    def update(self):
        font = pygame.font.Font(None, self.size)
        self.binary = self.get_binary(self.ascii.ascii)
        self.image = font.render("Binario: %s" % self.binary, True, BLACK)
        self.rect = self.image.get_rect().move(200,75)

    def get_binary(self, n):
        r = ""
        while n != 1:
            r = str(n % 2) + r
            n /= 2

        return "1" + r

class Ascii(pygame.sprite.Sprite):

    def __init__(self, letter):
        pygame.sprite.Sprite.__init__(self)
        self.letter = letter
        self.size = 55
        self.ascii = ord(self.letter.letter)
        self.image = pygame.Surface((self.size, self.size))

    def update(self):
        font = pygame.font.Font(None, self.size)
        self.ascii = ord(self.letter.letter)
        self.image = font.render("ASCII: %d" % self.ascii, True, BLACK)
        self.rect = self.image.get_rect().move(200,20)

class Letter(pygame.sprite.Sprite):

    def __init__(self, letter="A"):
        pygame.sprite.Sprite.__init__(self)
        self.letter = letter
        self.size = 100
        self.image = pygame.Surface((self.size, self.size))

    def update(self):
        font = pygame.font.Font(None, self.size)
        self.image = font.render(self.letter, True, BLACK)
        self.rect = self.image.get_rect().inflate(15,15).move(15,15)

    def next(self):
        '''
        >>> l = Letter("A")
        >>> l.next()
        >>> l.letter == "B"
        True
        >>> l = Letter("Z")
        >>> l.next()
        >>> l.letter == "a"
        True
        >>> l = Letter("z")
        >>> l.next()
        >>> l.letter == "A"
        True
        '''
        next = ord(self.letter) + 1
        if next == ord("z") + 1:
            self.letter = "A"
        elif next == ord("Z") + 1:
            self.letter = "a"
        else:
            self.letter = chr(next)

    def prev(self):
        '''
        >>> l = Letter("A")
        >>> l.prev()
        >>> l.letter == "z"
        True
        >>> l = Letter("Z")
        >>> l.prev()
        >>> l.letter == "Y"
        True
        >>> l = Letter("z")
        >>> l.prev()
        >>> l.letter == "y"
        True
        '''
        prev = ord(self.letter) - 1
        if prev == ord("a") - 1:
            self.letter = "Z"
        elif prev == ord("A") - 1:
            self.letter = "z"
        else:
            self.letter = chr(prev)

    def set(self, letter):
        '''
        >>> l = Letter("A")
        >>> l.set("j")
        >>> l.letter == "j"
        True
        >>> l = Letter("A")
        >>> l.set("Ñ")
        >>> l.letter == "Ñ"
        False
        '''
        if letter in string.letters:
            self.letter = letter

class Label(pygame.sprite.Sprite):

    def __init__(self, text="", xy=(0,0), size=25, color=BLACK):
        pygame.sprite.Sprite.__init__(self)
        self.text = text
        self.size = size
        self.x, self.y = xy    #topleft
        self.color = BLACK
        self.image = pygame.Surface((self.size, self.size))

    def update(self):
        font = pygame.font.Font(None, self.size)
        self.image = font.render(self.text, True, self.color)
        self.rect = self.image.get_rect().inflate(10,10).move(self.x, self.y)

CODIFICACIONES = (BandaBase, CodificacionManchester, CodificacionAMI)
MODULACIONES = ()

class App(object):

    def __init__(self, screen):
        self.screen = screen
        self.letter = Letter()
        self.ascii = Ascii(self.letter)
        self.binary = Binary(self.ascii)
        self.codificacion = CODIFICACIONES[2](self.binary)
        self.modulacion = ModulacionFrecuencia(self.binary)
        self.widgets = pygame.sprite.OrderedUpdates()
        self.widgets.add(self.letter, self.ascii, self.binary, self.codificacion, self.modulacion)
        labels = [Label(u"(para transmisión digital)", (530, 380)), Label(u"(para transmisión analógica)", (530, 580))]
        self.widgets.add(labels)
        self.exit = False
        self.clock = pygame.time.Clock()

    def loop(self):
       pygame.display.flip()
       while not self.exit:

            self.clock.tick(100)

            self.screen.fill(WHITE)

            for event in pygame.event.get():
                self.control(event)

            self.update()
            self.draw()

            pygame.display.flip()

    def control(self, event):
        if event.type == QUIT:
            sys.exit(0)
        elif event.type == KEYDOWN:
            self.keypress(event)
        elif event.type == MOUSEBUTTONDOWN:
            self.mouseclick(event)

    def update(self):
        self.widgets.update()

    def mouseclick(self, event):
        if self.letter.rect.collidepoint(event.pos):
            self.letter.next()

    def keypress(self, event):
        if event.unicode:
            self.letter.set(event.unicode)

    def draw(self):
        self.widgets.draw(self.screen)

def _test():
    import doctest
    doctest.testmod()

if __name__ == "__main__":
    _test()


from itertools import count
from pathlib import Path
from typing import Any, Dict, Iterator

from scrapy import Spider
from scrapy.crawler import Crawler
from xlsxwriter.workbook import Workbook
from xlsxwriter.worksheet import Worksheet

class ItemsToExcelPipeline:
  """Pipeline to save collected items into excel-file"""

  def __init__(self, output_filepath: Path) -> None:
    """
    Creates an Excel workbook using path from the project settings,
    in order to save the scraped cars in.

    :param output_filepath: path to the file to save scraped cars in
    """
    self.workbook: Workbook
    self.worksheet: Worksheet
    self.output_filepath: Path = output_filepath
    self.counter: Iterator[int] = count(0)

  @classmethod
  def from_crawler(cls, crawler: Crawler) -> 'ItemsToExcelPipeline':
    """Sets path to the Excel workbook from the project settings"""
    return cls(output_filepath=crawler.settings.get("OUTPUT_FILEPATH"))

  def open_spider(self, spider: Spider) -> None:
    """Inits & opens the Excel workbook in order to save scraped items in"""
    self.workbook = Workbook(self.output_filepath)
    self.worksheet = self.workbook.add_worksheet()

  def close_spider(self, spider: Spider) -> None:
    """Closes the Excel workbook at the end of the scraping process"""
    self.workbook.close()

  def process_item(self, item: Dict[str, Any], spider: Spider) -> None:
    """Saves info about scraped cars into Excel file"""
    headers = list(item.keys())
    _counter = next(self.counter)
    if _counter == 0:
      for col in headers:
        self.worksheet.write(_counter, headers.index(col), col)
    else:
      for k, v in item.items():
        self.worksheet.write(_counter, headers.index(k), v)
      next(self.counter)


import logging
from typing import Dict

from sqlalchemy.orm import Session

from boefjes.config import settings
from boefjes.katalogus.dependencies.context import get_context
from boefjes.katalogus.dependencies.encryption import (
    EncryptMiddleware,
    IdentityMiddleware,
    NaclBoxMiddleware,
)
from boefjes.katalogus.models import EncryptionMiddleware
from boefjes.katalogus.storage.interfaces import SettingsStorage, SettingNotFound
from boefjes.katalogus.storage.memory import SettingsStorageMemory
from boefjes.sql.db import ObjectNotFoundException
from boefjes.sql.db_models import SettingInDB, OrganisationInDB
from boefjes.sql.session import SessionMixin

logger = logging.getLogger(__name__)

class SQLSettingsStorage(SessionMixin, SettingsStorage):
    def __init__(self, session: Session, encryption: EncryptMiddleware):
        self.encryption = encryption

        super().__init__(session)

    def get_by_key(self, key: str, organisation_id: str, plugin_id: str) -> str:
        instance = self._db_instance_by_id(key, organisation_id, plugin_id)

        return self.encryption.decode(instance.value)

    def get_all(self, organisation_id: str, plugin_id: str) -> Dict[str, str]:
        query = (
            self.session.query(SettingInDB)
            .join(OrganisationInDB)
            .filter(SettingInDB.organisation_pk == OrganisationInDB.pk)
            .filter(SettingInDB.plugin_id == plugin_id)
            .filter(OrganisationInDB.id == organisation_id)
        )
        return {setting.key: self.encryption.decode(setting.value) for setting in query.all()}

    def create(self, key: str, value: str, organisation_id: str, plugin_id: str) -> None:
        logger.info("Saving setting: %s: %s for organisation %s", key, value, organisation_id)

        setting_in_db = self.to_setting_in_db(key, self.encryption.encode(value), organisation_id, plugin_id)
        self.session.add(setting_in_db)

    def update_by_key(self, key: str, value: str, organisation_id: str, plugin_id: str) -> None:
        instance = self._db_instance_by_id(key, organisation_id, plugin_id)

        instance.value = self.encryption.encode(value)

    def delete_by_key(self, key: str, organisation_id: str, plugin_id: str) -> None:
        instance = self._db_instance_by_id(key, organisation_id, plugin_id)

        self.session.delete(instance)

    def _db_instance_by_id(self, key: str, organisation_id: str, plugin_id: str) -> SettingInDB:
        instance = (
            self.session.query(SettingInDB)
            .join(OrganisationInDB)
            .filter(SettingInDB.key == key)
            .filter(SettingInDB.plugin_id == plugin_id)
            .filter(SettingInDB.organisation_pk == OrganisationInDB.pk)
            .filter(OrganisationInDB.id == organisation_id)
            .first()
        )

        if instance is None:
            raise SettingNotFound(key, organisation_id, plugin_id) from ObjectNotFoundException(
                SettingInDB, key=key, organisation_id=organisation_id
            )

        return instance

    def to_setting_in_db(self, key: str, value: str, organisation_id: str, plugin_id: str) -> SettingInDB:
        organisation = self.session.query(OrganisationInDB).filter(OrganisationInDB.id == organisation_id).first()

        return SettingInDB(key=key, value=value, plugin_id=plugin_id, organisation_pk=organisation.pk)

def create_setting_storage(organisation_id: str, session) -> SettingsStorage:
    if not settings.enable_db:
        return SettingsStorageMemory()

    encrypter = IdentityMiddleware()
    if get_context().env.encryption_middleware == EncryptionMiddleware.NACL_SEALBOX:
        encrypter = NaclBoxMiddleware(
            get_context().env.katalogus_private_key_b64,
            get_context().env.katalogus_public_key_b64,
        )

    return SQLSettingsStorage(session, encrypter)


# -*- coding: UTF-8 -*-
'''
下载网易 音乐,爬虫
'''
import requests
import urllib.request

r = requests.get("http://music.163.com/api/playlist/detail?id=378658225")
arr = r.json()['result']['tracks']
print (arr)
for i in range(2):
    name = str(i + 1) + ' ' + arr[i]['name'] + '.mp3'
    link = arr[i]['mp3Url']
    urllib.request.urlretrieve(link, "/music" + name)
    print(name + '  down')


from SimPEG import *

def run(N=100, plotIt=True):
    """
        Inversion: Linear Problem
        =========================

        Here we go over the basics of creating a linear problem and inversion.

    """

    class LinearSurvey(Survey.BaseSurvey):
        def projectFields(self, u):
            return u

    class LinearProblem(Problem.BaseProblem):

        surveyPair = LinearSurvey

        def __init__(self, mesh, G, **kwargs):
            Problem.BaseProblem.__init__(self, mesh, **kwargs)
            self.G = G

        def fields(self, m, u=None):
            return self.G.dot(m)

        def Jvec(self, m, v, u=None):
            return self.G.dot(v)

        def Jtvec(self, m, v, u=None):
            return self.G.T.dot(v)

    np.random.seed(1)

    mesh = Mesh.TensorMesh([N])

    nk = 20
    jk = np.linspace(1.,20.,nk)
    p = -0.25
    q = 0.25

    g = lambda k: np.exp(p*jk[k]*mesh.vectorCCx)*np.cos(2*np.pi*q*jk[k]*mesh.vectorCCx)

    G = np.empty((nk, mesh.nC))

    for i in range(nk):
        G[i,:] = g(i)

    mtrue = np.zeros(mesh.nC)
    mtrue[mesh.vectorCCx > 0.3] = 1.
    mtrue[mesh.vectorCCx > 0.45] = -0.5
    mtrue[mesh.vectorCCx > 0.6] = 0

    prob = LinearProblem(mesh, G)
    survey = LinearSurvey()
    survey.pair(prob)
    survey.makeSyntheticData(mtrue, std=0.01)

    M = prob.mesh

    reg = Regularization.Tikhonov(mesh)
    dmis = DataMisfit.l2_DataMisfit(survey)
    opt = Optimization.InexactGaussNewton(maxIter=35)
    invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
    beta = Directives.BetaSchedule()
    betaest = Directives.BetaEstimate_ByEig()
    inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest])
    m0 = np.zeros_like(survey.mtrue)

    mrec = inv.run(m0)

    if plotIt:
        import matplotlib.pyplot as plt

        fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2))
        for i in range(prob.G.shape[0]):
            axes[0].plot(prob.G[i,:])
        axes[0].set_title('Columns of matrix G')

        axes[1].plot(M.vectorCCx, survey.mtrue, 'b-')
        axes[1].plot(M.vectorCCx, mrec, 'r-')
        axes[1].legend(('True Model', 'Recovered Model'))
        plt.show()

    return prob, survey, mesh, mrec

if __name__ == '__main__':
    run()