import os
import options
import logging
import logger
import data
import models
import torch
import torch.multiprocessing as mp
import torch.distributed as dist
import numpy as np
from pathlib import Path
from visualize import calculate_confusion_matrix

def train_loop(rank, args):
    """
    Main training loop
    :param rank: id for distributed training. 0 is master.
    :param args: command line arguments
    :return:
    """
    # initialize
    args.rank = rank
    if args.gpu_id == "-1":
        args.device = "cpu"
    else:
        args.device = "cuda:{}".format(args.rank)
    setup(args)
    my_logger = logger.Logger(args)
    args.phase = "train"
    train_dataloader = data.MyDataLoader(args)
    args.phase = "val"
    val_dataloader = data.MyDataLoader(args)
    model = models.MyModel(args)
    # actual epoch loop
    for epoch in range(args.number_of_epochs):
        if args.distributed:
            dist.barrier()
            train_dataloader.dataloader.sampler.set_epoch(epoch)
        running_loss = 0.0
        running_corrects = 0
        num_datapoints = 0
        for batch_index, batch in enumerate(train_dataloader.dataloader):
            model.optimizer.zero_grad()
            output = model.network(batch)
            train_loss = model.loss_fn(output, batch["label"])
            _, predictions = torch.max(output, 1)
            train_loss.backward()
            model.optimizer.step()
            train_loss_np = train_loss.cpu().detach().numpy()
            correct = torch.sum(torch.eq(predictions, batch["label"])).item()
            my_logger.write_scaler("batch", "train_loss", train_loss_np, epoch*(len(train_dataloader.dataloader)) + batch_index)
            logging.info("train: epoch: {}, batch {} / {}, loss: {}, acc: {}".format(epoch,
                                                                                batch_index,
                                                                                len(train_dataloader.dataloader),
                                                                                train_loss_np,
                                                                                (correct / batch["label"].shape[0]) * 100))
            num_datapoints += batch["label"].shape[0]
            running_loss += train_loss.item() * batch["label"].shape[0]
            running_corrects += torch.sum(torch.eq(predictions, batch["label"])).item()
        epoch_loss = running_loss / num_datapoints
        epoch_acc = (running_corrects / num_datapoints) * 100
        my_logger.write_scaler("epoch", "train_loss", epoch_loss, epoch)
        my_logger.write_scaler("epoch", "train_acc", epoch_acc, epoch)
        logging.info("train: epoch: {}, training loss: {}".format(epoch,
                                                                  epoch_loss))
        logging.info("train: epoch: {}, training acc: {}".format(epoch,
                                                                 epoch_acc))
        val_loss_total = 0.
        if args.rank == 0:
            model.save_network(which_epoch=str(epoch))
            model.save_network(which_epoch="latest")
            model.network.train(mode=False)
            with torch.no_grad():
                running_loss = 0.0
                running_corrects = 0
                num_datapoints = 0
                for batch_index, batch in enumerate(val_dataloader.dataloader):
                    if args.distributed:  # might be unnecessary
                        output = model.network.module(batch)
                    else:
                        output = model.network(batch)
                    val_loss = model.loss_fn(output, batch["label"])
                    _, predictions = torch.max(output, 1)
                    num_datapoints += batch["label"].shape[0]
                    running_loss += val_loss.item() * batch["label"].shape[0]
                    running_corrects += torch.sum(torch.eq(predictions, batch["label"])).item()
                    logging.info("val: batch {} / {}".format(batch_index, len(val_dataloader.dataloader)))
            model.network.train(mode=True)
            val_loss_total = running_loss / num_datapoints
            val_acc_total = (running_corrects / num_datapoints) * 100
            my_logger.write_scaler("epoch", "val_loss", val_loss_total, epoch)
            my_logger.write_scaler("epoch", "val_acc", val_acc_total, epoch)
            logging.info("validation: epoch: {}, loss: {}".format(epoch, val_loss_total))
            logging.info("validation: epoch: {}, acc: {}".format(epoch, val_acc_total))
            my_logger.write_scaler("epoch", "learning rate", model.optimizer.param_groups[0]['lr'], epoch)
            logging.info("lr: {}".format(model.optimizer.param_groups[0]['lr']))
        if args.lr_policy == "plateau":
            if args.distributed:
                val_loss_total = torch.Tensor([val_loss_total]).to(args.rank)
                dist.broadcast(tensor=val_loss_total, src=0)
                model.scheduler.step(val_loss_total.item())
            else:
                model.scheduler.step(val_loss_total)
        else:
            model.scheduler.step()

def setup(args):
    if args.rank == 0:  # setup logging
        if args.log:
            logging_file = Path(args.experiment_path, "log")
            logging.basicConfig(filename=str(logging_file), filemode='w', level=args.verbosity.upper())
        else:
            logging.basicConfig(level=args.verbosity.upper())
    if args.distributed:
        os.environ['MASTER_ADDR'] = 'localhost'
        os.environ['MASTER_PORT'] = args.port
        # initialize the process group
        dist.init_process_group("nccl", rank=args.rank, world_size=args.world_size)  # gloo / nccl
    torch.cuda.manual_seed_all(args.seed)
    np.random.seed(args.seed)

def cleanup():
    dist.destroy_process_group()

def predict_on_preprocessed(args):
    """
    uses a simple "foward" on the validation set to estimate performance (prints confusion matrix)
    todo: move to test.py
    :param args:
    :return:
    """
    args.phase = "val"
    val_dataset = data.MyDataLoader(args)
    model = models.MyModel(args)
    model.network.train(mode=False)
    confusion_matrix = torch.zeros(3, 3)
    with torch.no_grad():
        # running_loss = 0.0
        running_corrects = 0
        num_datapoints = 0
        for i, batch in enumerate(val_dataset):
            logging.info("batch: {} / {}".format(i, len(val_dataset) // args.batch_size))
            output = model.network(batch)
            # val_loss = model.loss_fn(output, batch["label"])
            _, predictions = torch.max(output, 1)
            for t, p in zip(batch["label"].cpu().view(-1), predictions.cpu().view(-1)):
                confusion_matrix[t.long(), p.long()] += 1
            num_datapoints += batch["label"].shape[0]
            # running_loss += val_loss.item() * batch["label"].shape[0]
            running_corrects += torch.sum(torch.eq(predictions, batch["label"])).item()
    norm_mat, mat, total_acc = calculate_confusion_matrix(None, None,
                                                          Path(args.experiment_path, "confusion_matrix_{}.png".format(args.use_disjoint)),
                                                          confusion_matrix.numpy())
    # val_loss_total = running_loss / num_datapoints
    val_acc_total = (running_corrects / num_datapoints) * 100
    # logging.info("validation loss: {}".format(val_loss_total))
    logging.info("validation acc: {}%".format(val_acc_total))
    logging.info("per class acc: {}".format(norm_mat.diagonal()))
    logging.info("confusion matrix (normalized): {}".format(norm_mat))

if __name__ == "__main__":
    args = options.parse_arguments_for_training()
    if args.distributed:
        mp.spawn(train_loop,
                 args=(args,),
                 nprocs=args.world_size,
                 join=True)
    else:
        train_loop(0, args)


# coding=utf-8

import time
import config
import logging
import traceback

from excepts import ParamError, DBError
from utils.base import BaseHandler
from utils.decorator import check
from constants import MEMBER_AUTH, MEMBER_AUTH_UNSET, MEMBER_AUTH_ON, MEMBER_AUTH_OFF, DTM_FMT
from utils.qdconf_api import get_qd_conf_value

from qfcommon.base.qfresponse import success
from qfcommon.base.dbpool import get_connection_exception

log = logging.getLogger()

class GetInfo(BaseHandler):
    '''
    获取当前商户是否开启会员实名认证， 和会员总数，实名总数信息
    '''

    _base_err = '获取数据失败'

    def get_member_auth(self, userid):
        with get_connection_exception("qf_mchnt") as conn:
            row = conn.select_one("mchnt_control", fields="member_auth", where={
                "status": 1,
                "userid": userid
            })
        if row:
            return row['member_auth']
        else:
            return MEMBER_AUTH_UNSET

    def get_real_count(self, userid):
        with get_connection_exception('qf_mchnt') as db:
            where = {'userid': userid}
            # total_num
            total_num = db.select_one('member', where=where, fields='count(1) as num')['num']

            where.update({"submit": 1})
            real_num = db.select_one("member_tag",
                                     where=where,
                                     fields="count(1) as num")['num']

            return total_num, real_num

    @check('login')
    def GET(self):
        userid = self.user.userid

        # 先获取当前商户的 如果等于0 则去获取渠道的 如果渠道的也未设置 则给赋值配置文件的
        member_auth = self.get_member_auth(userid)
        if member_auth == MEMBER_AUTH_UNSET:
            groupid = self.get_groupid(userid=userid)
            qd_ext = get_qd_conf_value(groupid, mode=None, key='ext')
            if qd_ext:
                member_auth = qd_ext.get('need_auth', MEMBER_AUTH_OFF)
            else:
                member_auth = getattr(config, "DEFAULT_MEMBER_AUTH", MEMBER_AUTH_OFF)

        count, real_count = self.get_real_count(userid)
        return self.write(success(data={
            "is_real_auth": 1 if member_auth == MEMBER_AUTH_ON else 0,
            "count": count,
            "real_count": real_count
        }))

class SetMemberAuth(BaseHandler):
    '''
    设置商户的实名认证状态
    '''

    @check('login')
    def POST(self):

        params = self.req.input()
        status = params.get("status", "")
        try:
            status = int(status)
        except:
            raise ParamError("参数不合法")

        if status == "":
            raise ParamError("参数为空")

        if status not in (0, 1):
            raise ParamError("参数错误")

        member_auth = MEMBER_AUTH_ON if int(status) == 1 else MEMBER_AUTH_OFF

        userid = self.user.userid

        where = {
            "userid": userid,
            "status": 1
        }
        curr_time = time.strftime(DTM_FMT)
        with get_connection_exception("qf_mchnt") as conn:
            num = conn.select_one("mchnt_control", where=where, fields="count(1) as num")['num']
            if num > 0:
                affected_line = conn.update("mchnt_control", values={"member_auth": member_auth},
                                            where=where)
                if affected_line >= 1:
                    return self.write(success(data={}))
                else:
                    raise DBError("更新数据库失败")
            else:
                try:
                    conn.insert("mchnt_control", values={
                        "userid": userid,
                        "member_auth": member_auth,
                        "ctime": curr_time
                    })
                    return self.write(success(data={}))
                except Exception as e:
                    log.debug(traceback.format_exc())
                    raise DBError("插入数据库失败")

class GetDocAndImg(BaseHandler):
    '''
    获取描述页面的内容和图片
    '''

    @check("login")
    def GET(self):
        return self.write(success(data=getattr(config, 'MEMBER_AUTH_CONTENT', '未设置')))


from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import os
import random
#
# path to fonts ttf directory
fontspath = "..\Data\Fonts"

# create directory to save the test images
if not os.path.exists("../Data/TestImages"):
    os.mkdir("../Data/TestImages")

listSize = [30, 50, 20, 60, 15] #the different sizes of fonts to be created
X = [50, 100, 200, 20, 300] # x-coordinates of fonts
Y = [150,25,350,250,120] #y-coordinates of fonts

#loop to create 20 images of test fonts
for it in  range (20):
    blankImg = Image.new('RGB', (512, 512), (255, 255, 255))
    for i, l, x,y in zip(range(5),listSize,X,Y):
        random_file=random.choice(os.listdir(fontspath)) #randomly picks fonts from the set
        fontStyle = os.path.join(fontspath, random_file)
        draw = ImageDraw.Draw(blankImg)
        fontSize = l
        font = ImageFont.truetype(fontStyle, fontSize)
        draw.text((x, y), "Hello, World!", (0, 0, 0), font=font)
    blankImg.save("../Data/TestImages/"+str(it) +".jpg") #saves the font


from app import app, db
from app.models import Note
from app.forms import NoteForm
from flask import render_template, flash, redirect, url_for

@app.route('/')
@app.route('/index')
def index():
    query = db.session.execute("SELECT name, message, timestamp FROM note ORDER BY timestamp desc")
    entries = [dict(name=row[0], message=row[1], timestamp=row[2]) for row in query]
    return render_template('index.html', title='boop the world', noun='guestbook', entries=entries)

@app.route('/easter')
def easter():
    return render_template('easter.html', body="If I write something here will it print?")

@app.route('/note', methods=['GET', 'POST'])
def submit_note():
    form = NoteForm()
    if form.validate_on_submit():
        flash('Message {} received! Redirecting ...'.format(
            form.message.data))
        note = Note(name=form.name.data, message=form.message.data)
        db.session.add(note)
        db.session.commit()
        return redirect(url_for('index'))
    return render_template('note.html', title='Leave a note', form=form)


"""
Name:       Linh Tran
CS230:      Section SN5
Data:       ridesharesample.csv
URL:        https://ridesharing-final-project.herokuapp.com/

Description:
This program summarizes the statistics of ridesharing data, graphs bar charts
to display the change in number of rides by day or hour. It also displays
pickups and destinations on the map, and graphs a scatterplot that shows the
relationship between demand, hour, and outside temperature.
"""

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import streamlit as st
import pydeck as pdk

MENU_1 = {0: "Rides Summary",
          1: "Pickups and Destinations",
          2: "Ridesharing Demand"}

MENU_2 = {0: "Uber",
          1: "Lyft",
          2: "Both apps"}

MENU_3 = {'By day': 'day',
          'By hour': 'hour'}

LOCATIONS = {'Back Bay': [42.3503,-71.0810], 'Beacon Hill': [42.3588,-71.0707],
             'Boston University': [42.3505,-71.1054], 'Fenway': [42.3429,-71.1003],
             'Financial District': [42.3559,-71.0550], 'Haymarket Square': [42.3634,-71.0586],
             'Northeastern University': [42.3398,-71.0892], 'North End': [42.3647,-71.0542],
             'North Station': [42.3661,-71.0631], 'South Station': [42.3519,-71.0551],
             'Theatre District': [42.3519,-71.0643], 'West End': [42.3644,-71.0661]}

MAPKEY = "pk.eyJ1IjoiY2hlY2ttYXJrIiwiYSI6ImNrOTI0NzU3YTA0azYzZ21rZHRtM2tuYTcifQ.6aQ9nlBpGbomhySWPF98DApk.eyJ1IjoiY2hlY2ttYXJrIiwiYSI6ImNrOTI0NzU3YTA0azYzZ21rZHRtM2tuYTcifQ.6aQ9nlBpGbomhySWPF98DA"

#########################################################
## helpers
#########################################################
def read_data(app):
    fname = "ridesharesample.csv"
    df = pd.read_csv(fname)
    df = df.sort_values(by='timestamp', ignore_index=True)  # sort data by timestamp

    if app == "Uber":   # filtering data
        df = df[df.cab_type == "Uber"]
    elif app == "Lyft":
        df = df[df.cab_type == "Lyft"]

    return df

def get_dates(df):
    lst1 = []
    lst2 = []
    for index, row in df.iterrows():
        date = []
        date.append(row['month'])
        date.append(row['day'])
        date = tuple(date)
        if date not in lst1:
            lst1.append(date)
    for i in lst1:
        date = ""
        for j in range(2):
            s = str(i[j])
            if len(s) == 1:
                s = s.replace(s, "0"+s)
            date += s
            if j == 1:
                continue
            else:
                date += '/'
        lst2.append(date)

    return lst2  # a list of dates (MM/DD)

def get_hours(df):
    lst = []
    first = df.hour.min()
    last = df.hour.max()
    for i in np.arange(first, last+1):
        if len(str(i)) == 1 and i != 9:
            s = '0'+str(i)+'-0'+str(i+1)
        elif i == 9:
            s = '0'+str(i)+'-'+str(i+1)
        else:
            s = str(i)+'-'+str(i+1)
        lst.append(s)

    return lst  # a list of timeframe (HH-HH)

def time_select(df, format):
    time_list = []
    if format == 'day':
        time_list = get_dates(df)
    elif format == 'hour':
        time_list = get_hours(df)
    # slider that specifies desired timeframe
    time = st.select_slider(f"Slider by {format}:", options=time_list, value=time_list[0])
    return time, time_list

def display_map(df1):
    locations = [[index, row] for index, row in df1.iteritems()]
    coordinates = [loc+LOCATIONS[loc[0]] for loc in locations]
    df2 = pd.DataFrame(coordinates, columns=['loc','rides','lat','lon'])

    view_state = pdk.ViewState(latitude=df2['lat'].mean(),
                               longitude=df2['lon'].mean(),
                               zoom=12,
                               pitch=0
                               )
    layer1 = pdk.Layer('ScatterplotLayer',
                       data=df2,
                       get_position='[lon, lat]',
                       get_radius=70,
                       get_color=[255,0,0],
                       pickable=True
                       )
    tool_tip = {"html": "{loc}
({lat}, {lon})
{rides} rides ", # text format
                "style": {"backgroundColor": "red",  # box color red
                          "color": "white"}          # text color white
                }
    map = pdk.Deck(
        map_style='mapbox://styles/mapbox/light-v9',
        initial_view_state=view_state,
        mapbox_key=MAPKEY,
        layers=[layer1],
        tooltip=tool_tip)

    st.pydeck_chart(map)

#########################################################
## graphing charts
#########################################################
def bar_chart(format, x_val, y_val, avg):
    if format == 'By day':
        xlabel = 'Date'
        title = 'day'
    else:
        xlabel = 'Timeframe'
        title = 'hour'

    avg_list = [avg for i in np.arange(len(x_val))]
    lst = list(zip(y_val, avg_list))
    df = pd.DataFrame(lst, columns=['Number of rides','Average rides'], index=x_val)

    df['Number of rides'].plot(kind='bar', color='r', figsize=(8,6))
    df['Average rides'].plot(kind='line')
    plt.xticks(rotation=-90)
    plt.ylabel('Number of rides')
    plt.xlabel(xlabel)
    plt.title(f"Change in number of rides by {title}")
    plt.legend(loc='best')
    st.pyplot(plt)

def scatter_plot(lst1, lst2, lst3):
    s = [(i*5)**2 for i in lst3]
    fig, ax = plt.subplots(figsize=(10, 7))
    scatter = ax.scatter(lst1, lst2, c='r', s=s)  # color: red, size of each dot: s

    handles, labels = scatter.legend_elements(prop='sizes',
                                              alpha=0.2,
                                              fmt='{x:.2f}',
                                              func=lambda s: np.sqrt(s)/5)  # displaying surge value
    ax.legend(handles, labels, loc='best', title='Surge')
    plt.xticks(np.arange(0,24,1))
    plt.xlabel('Hour')
    plt.ylabel('Temperature')
    plt.title('Scatterplot of demand, hour, and outside temperature')
    st.pyplot(plt)

#########################################################
## menu
#########################################################
def part1(app, app_name):
    st.header("Part 1: Rides Summary")
    st.write(f"_A summary of total, average, min, max number of {app_name} rides in Boston_")
    df = read_data(app)
    st.write("")

    # total sum
    st.write(f"**Total number of sample {app_name} rides:**")
    count = len(df)
    st.write(count)
    st.write("")

    # select time format
    format = st.selectbox('Time selection by day or hour:', list(MENU_3.keys()))
    time, time_list = time_select(df, MENU_3[format])
    st.write("")

    # number of rides by day or by our
    st.write(f"**Number of {app_name} rides by day or by hour:**")

    y_val = []  # list of y values for graphing later
    if format == 'By day':
        for t in time_list:
            month = int(t.split("/")[0])
            day = int(t.split("/")[1])
            df1 = df[(df.month == month) & (df.day == day)][['cab_type', 'source', 'destination']]
            count1 = len(df1)
            y_val.append(count1)

            if t == time:  # only displays info with the specified time from slider
                st.write(f"There were **{count1}** {app_name} rides on **{time}**.")
                st.write(df1)
    else:
        for t in time_list:
            hour = int(t.split("-")[0])
            df1 = df[df.hour == hour][['cab_type', 'source', 'destination']]
            count1 = len(df1)
            y_val.append(count1)

            if t == time:  # only displays info with the specified time from slider
                st.write(f"There were **{count1}** {app_name} rides between timeframe **{time}**.")
                st.write(df1)
    st.write("")

    # average rides per day or per hour & max, min number of rides
    st.write(f"**{app_name}'s average rides per day or per hour & max, min number of rides:**")
    avgRides = int(count/(len(time_list)))
    max_val = max(y_val)
    min_val = min(y_val)
    max_pos = y_val.index(max_val)
    min_pos = y_val.index(min_val)

    st.write(f"There were **{avgRides}** {app_name} rides per {MENU_3[format]}.")
    st.write(f"Max number of rides is **{max_val}** on **{time_list[max_pos]}**.")
    st.write(f"Min number of rides is **{min_val}** on **{time_list[min_pos]}**.")
    st.write("")

    # visualization
    st.write(f"**Visualization:**")
    bar_chart(format, time_list, y_val, avgRides)

def part2(app, app_name):
    st.header("Part 2: Pickups and Destinations")
    st.write(f"_{app_name}'s most requested pickups and destinations in Boston_")
    df = read_data(app)
    st.write("")

    df2_pickup = df['source'].value_counts().sort_values(ascending=False)
    top_pickup = df2_pickup.head(3)
    st.write("**Top 3 pickups (total rides):**", top_pickup)
    display_map(top_pickup)
    st.write("")

    df2_destination = df['destination'].value_counts().sort_values(ascending=False)
    top_destination = df2_destination.head(3)
    st.write("**Top 3 destinations (total rides):**", top_destination)
    display_map(top_destination)

def part3(app, app_name):
    st.header("Part 3: Ridesharing Demand")
    st.write(f"_{app_name} ridesharing traffic by hour in Boston_")
    df = read_data(app)
    st.write("")
    with st.beta_expander("Demand and surge multiplier?"):  # expander to explain
        st.write("""
        The higher the surge multiplier, the higher the demand of ridesharing.
         """)
    st.write("")

    # find surge multiplier greater than 1
    st.write("**Rides with surge multipliers greater than 1:**")
    df3 = df[df.surge_multiplier > 1][['cab_type', 'hour', 'temperature', 'surge_multiplier']] # filering data with surge multiplier > 1

    if len(df3) == 0:
        st.write(f"There were no {app} rides that have surge multipliers greater than 1 in the sample data.")
        st.write("Please select the other app.")
    else:
        st.write(df3)
        st.write("")

        # relationship between hour, temperature, and demand
        st.write('**Visualization:**')

        surge_list = [row['surge_multiplier'] for index, row in df3.iterrows()]
        time_list = [row['hour'] for index, row in df3.iterrows()]
        temp_list = [row['temperature'] for index, row in df3.iterrows()]

        scatter_plot(time_list, temp_list, surge_list)

#########################################################
## web interface
#########################################################
def main():
    st.title("Ride Sharing Sample Data")
    st.sidebar.header("Final Project")
    st.sidebar.write("""
    Name:   Linh Tran\n
    CS230:  Section SN5\n
    Data:   ridesharesample.csv\n
    URL:    https://ridesharing-final-project.herokuapp.com/""")

    st.sidebar.header("Inputs")
    analysis = st.sidebar.radio("Select an analysis:", list(MENU_1.values()))
    app = st.sidebar.radio("Select an app:", list(MENU_2.values()))

    if app == "Both apps":
        app_name = "Uber and Lyft"
    else:
        app_name = app

    if analysis == MENU_1[0]:
        part1(app, app_name)
    elif analysis == MENU_1[1]:
        part2(app, app_name)
    else:
        part3(app, app_name)

main()


import tensorflow as tf
from tensorflow import keras

import numpy as np
import matplotlib.pyplot as plt

from skimage import io
img = io.imread('hood.jpg', as_grey=True)
nx, ny = img.shape
img_flat = img.reshape(nx * ny)
IMG = np.reshape(img,(1,784))
answer = session.run(train_prediction, feed_dict={tf_train_dataset: IMG})
print(answer)

fashion_mnist = keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels) = fashion_mnist.load_data()

train_labels[:10]  # let's have a look at the first 10 training labels
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

train_images = train_images / 255.0
test_images = test_images / 255.0

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28,28)),
    keras.layers.Dense(128,activation = 'relu'),
    keras.layers.Dense(10,activation = 'softmax')
])

model.compile(optimizer='adam',
              loss = 'sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(train_images,train_labels,epochs=3)
test_loss,test_acc = model.evaluate(test_images,test_labels,verbose=1)
print("Accuracy:",test_acc)
predictions = model.predict(test_images)
print(predictions[0])

COLOR = 'white'
plt.rcParams['text.color'] = COLOR
plt.rcParams['axes.labelcolor'] = COLOR

def predict(model, image, correct_label):
  class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
  prediction = model.predict(np.array([image]))
  predicted_class = class_names[np.argmax(prediction)]

  show_image(image, class_names[correct_label], predicted_class)

def show_image(img, label, guess):
  plt.figure()
  plt.imshow(img, cmap=plt.cm.binary)
  plt.title("Excpected: " + label)
  plt.xlabel("Guess: " + guess)
  plt.colorbar()
  plt.grid(False)
  plt.show()

def get_number():
  while True:
    num = input("Pick a number: ")
    if num.isdigit():
      num = int(num)
      if 0 <= num <= 1000:
        return int(num)
    else:
      print("Try again...")

num = get_number()
image = test_images[num]
label = test_labels[num]
predict(model, image, label)
print(class_names[np.argmax(predictions[num])])


import os
from PIL import Image
import numbers
from normalizing import *

inPath = './originalImages/'
outPath = './normalizedImages/'

def getContrast(image):
    returnImage = image.copy()
    for i in range(returnImage.size[0]): # for every pixel:
        for j in range(returnImage.size[1]):
            pixel = returnImage.getpixel((i, j))
            isMostlyBlue = (pixel[2] > pixel[1] and pixel[2] > pixel[0])
            isTransparent = pixel[3] < 255
            blueToGreen = abs(pixel[1] - pixel[2])
            bluetoRed = abs(pixel[0] - pixel[2])
            isGray = blueToGreen < 50 and bluetoRed < 50
            if((isMostlyBlue and not isGray) or isTransparent):
                returnImage.putpixel((i, j), (0,0,0))
            else:
                returnImage.putpixel((i, j), (0xFF, 0xFF, 0xFF))
    return returnImage

for root, dirs, files in os.walk(inPath):
    for file in files:
        image = Image.open(inPath + file)
        image = getContrast(image)
        image = getBoundedImage(image)
        image = proportionalResize(image)
        image = placeOntoCentered(image)
        image.save(f'{outPath}{file}')


from django.urls import path, include

from webapp.views import IndexView, ProductView, ProductCreateView, \
    ProductUpdateView, ProductDeleteView, ReviewCreateView, ReviewDeleteView, ReviewUpdateView

app_name = 'webapp'

urlpatterns = [
    path('', IndexView.as_view(), name='index'),

    path('product/', include([
        path('add/', ProductCreateView.as_view(), name='product_create'),
        path('<int:pk>/', include([
            path('', ProductView.as_view(), name='product_view'),
            path('update/', ProductUpdateView.as_view(), name='product_update'),
            path('delete/', ProductDeleteView.as_view(), name='product_delete'),
            path('add_review/', ReviewCreateView.as_view(), name='review_create'),
        ])),
    ])),
    path('review/', include([
        path('<int:pk>/', include([
            path('delete/', ReviewDeleteView.as_view(), name='review_delete'),
            path('update/', ReviewUpdateView.as_view(), name='review_update'),
        ])),
    ])),
]


#!/usr/bin/env python3

import os, sys, yaml, json, subprocess, datetime

import manifest

cwd = os.getcwd()

def run_os_command(command, environment=None, shell=False):
    if shell:
        cmd = command
    else:
        cmd = command.split()

    try:
        command_output = subprocess.run(
            cmd,
            env=environment,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            shell=shell
        )
    except Exception as e:
        print(e)
        print(command_output)

    return command_output.stdout.decode('utf8'), command_output.stderr.decode('utf8'), command_output.returncode

def build_plugin(project):
    # Schema:
    # build_type: dotnet|docker|script
    # dotnet_runtime: the runtime for dotnet builds
    # dotnet_configuration: the configuration for dotnet builds
    # dotnet_framework: the framework for dotnet builds
    # docker_file: the Dockerfile for docker builds
    # script_path: the path for script builds

    # Extract our name and type
    project_name = project['name']
    project_type = project['type']
    # Set out the directories
    type_dir = "{}/projects/{}".format(cwd, project_type)
    project_dir = "{}/projects/{}/{}".format(cwd, project_type, project_name)
    # Check if a build configuration exists and load it
    manifest_file = '{}/build.yaml'.format(project_dir)
    if not os.path.exists(manifest_file):
        print("ERROR: Project {} does not contain a valid 'build.yaml' file.".format(project['name']))
        return False
    build_cfg = manifest.load_manifest(manifest_file)

    project_version = "{}.0.0.0".format(build_cfg['version'])

    # move into the project directory
    revdir = os.getcwd()
    os.chdir(project_dir)

    if build_cfg['build_type'] == 'dotnet':
        restore_command = "dotnet restore --no-cache"
        stdout, stderr, retcode = run_os_command(restore_command)
        if retcode:
            print(stdout)
            print(stderr)
            exit(1)

        build_command = "dotnet publish --configuration {} --framework {} --output ./bin/".format(
            build_cfg['dotnet_configuration'],
            build_cfg['dotnet_framework']
        )
        stdout, stderr, retcode = run_os_command(build_command)
        if retcode:
            print(stdout)
            print(stderr)
            exit(1)
        print(stdout)
    elif build_cfg['build_type'] == 'build.py':
        build_command = "python3 build.py"
        stdout, stderr, retcode = run_os_command(build_command)
        if retcode:
            print(stdout)
            print(stderr)
            exit(1)
    else:
        print("ERROR: Unsupported build type.")
        return False

    raw_bin_dir = "{}/bin".format(project_dir)
    os.chdir(raw_bin_dir)

    # Get a sensible name
    new_name = "{}_{}.zip".format(project_name, project_version)
    # Move out the artifacts
    artifacts_list = list()
    for artifact in build_cfg['artifacts']:
        artifacts_list.append("{}".format(artifact))
    stdout, stderr, retcode = run_os_command("zip {} {}".format(new_name, ' '.join(artifacts_list)))
    if retcode:
        print('Could not archive artifacts: {}'.format(stdout))
        return False

    # Move back to the previous directory
    os.chdir(revdir)

    # Collect artifacts
    src_dir = "{}/bin".format(project_dir)
    target_dir = "./bin/plugin/{}".format(project_name)
    # Make the type dir if it doesn't exist
    if not os.path.isdir(target_dir):
        os.makedirs(target_dir)

    stdout, stderr, retcode = run_os_command("mv {}/{} {}/".format(src_dir, new_name, target_dir))
    if retcode:
        print('Could not move archive: {}'.format(stderr))
        return False

    # Remove build junk
    run_os_command("rm -rf {}".format(src_dir))

    bin_md5sum = run_os_command("md5sum {}/{}".format(target_dir, new_name))[0].split()[0]

    generate_plugin_manifest(project, build_cfg, bin_md5sum, project_version)

    return True

def generate_plugin_manifest(project, build_cfg, bin_md5sum, project_version):
    # Extract our name, type, and plugin_id
    project_name = project['name']
    project_plugin_guid = build_cfg['guid']
    project_plugin_overview = build_cfg['overview']
    project_plugin_description = build_cfg['description']
    project_plugin_category = build_cfg['category']
    project_plugin_owner = build_cfg['owner']

    target_abi = build_cfg['targetAbi']

    build_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    target_dir = "./bin/plugin/{}".format(project_name)
    manifest_fragment_file_name = "{}/{}.manifest.json".format(target_dir, project_name)

    plugin_manifest_versions = list()
    plugin_manifest_existing_version_fragments = list()
    if os.path.isfile(manifest_fragment_file_name):
        with open(manifest_fragment_file_name, 'r') as manifest_fragment_file:
            old_config = json.load(manifest_fragment_file)
            for version in old_config['versions']:
                if version['versionStr'] != project_version:
                    plugin_manifest_existing_version_fragments.append(version)

    plugin_manifest_new_version_fragment = [{
        "version": project_version,
        "changelog": "changelog",
        "targetAbi": target_abi,
        "sourceUrl": "https://repo.jellyfin.org/releases/plugin/{0}/{0}_{1}.zip".format(project_name, project_version),
        "checksum": bin_md5sum,
        "timestamp": build_date
    }]
    plugin_manifest_versions = plugin_manifest_new_version_fragment + plugin_manifest_existing_version_fragments

    plugin_manifest_fragment = {
        "guid": project_plugin_guid,
        "name": project_plugin_nicename,
        "description": project_plugin_description,
        "overview": project_plugin_overview,
        "owner": project_plugin_owner,
        "category": project_plugin_category,
        "versions": plugin_manifest_versions
    }
    with open(manifest_fragment_file_name, 'w') as manifest_fragment_file:
        json.dump(plugin_manifest_fragment, manifest_fragment_file, sort_keys=True, indent=4)
    print("Wrote plugin manifest fragment to {}".format(manifest_fragment_file_name))


import pygame
import sys
import os
import pygame_gui
from Game_Over import GameOver
from Titles_show import Titles
from Pause import Pause

def level3(LANGUAGE, size, width, height):
    global isJump, jumpCount, x, fall, dead, run_away, show_titles, running, y
    SOUND_TITLES = True
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption('Level 3')
    screen.fill((0, 0, 0))
    FPS = 50
    clock = pygame.time.Clock()
    directory = os.path.join(os.getcwd(), 'data')
    achievements = []
    x, y = 500, 485

    def load_image(name, colorkey=None):
        fullname = os.path.join('data', name)
        if not os.path.isfile(fullname):
            print(f"Файл с изображением '{fullname}' не найден")
            sys.exit()
        image = pygame.image.load(fullname)
        if colorkey is not None:
            image = image.convert()
            if colorkey == -1:
                colorkey = image.get_at((0, 0))
            image.set_colorkey(colorkey)
        else:
            image = image.convert_alpha()
        return image

    walk_left = [load_image('R1.png'), load_image('R2.png'), load_image('R3.png'),
                load_image('R4.png'), load_image('R5.png'), load_image('R6.png'),
                load_image('R7.png'), load_image('R8.png'), load_image('R9.png'),
                load_image('R10.png')]
    walk_right = [pygame.transform.flip(load_image('R1.png'), 90, 0),
                 pygame.transform.flip(load_image('R2.png'), 90, 0),
                 pygame.transform.flip(load_image('R3.png'), 90, 0),
                 pygame.transform.flip(load_image('R4.png'), 90, 0),
                 pygame.transform.flip(load_image('R5.png'), 90, 0),
                 pygame.transform.flip(load_image('R6.png'), 90, 0),
                 pygame.transform.flip(load_image('R7.png'), 90, 0),
                 pygame.transform.flip(load_image('R8.png'), 90, 0),
                 pygame.transform.flip(load_image('R9.png'), 90, 0),
                 pygame.transform.flip(load_image('R10.png'), 90, 0)]
    jump_left = [load_image('J1.png'), load_image('J2.png'), load_image('J3.png'),
                load_image('J4.png'), load_image('J5.png'), load_image('J6.png'),
                load_image('J7.png'), load_image('J8.png'), load_image('J9.png'),
                load_image('J10.png')]
    jump_right = [pygame.transform.flip(load_image('J1.png'), 90, 0),
                 pygame.transform.flip(load_image('J2.png'), 90, 0),
                 pygame.transform.flip(load_image('J3.png'), 90, 0),
                 pygame.transform.flip(load_image('J4.png'), 90, 0),
                 pygame.transform.flip(load_image('J5.png'), 90, 0),
                 pygame.transform.flip(load_image('J6.png'), 90, 0),
                 pygame.transform.flip(load_image('J7.png'), 90, 0),
                 pygame.transform.flip(load_image('J8.png'), 90, 0),
                 pygame.transform.flip(load_image('J9.png'), 90, 0),
                 pygame.transform.flip(load_image('J10.png'), 90, 0)]
    enemy_walk = [pygame.transform.scale(load_image('demon_walk_1.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_2.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_3.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_4.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_5.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_6.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_7.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_8.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_9.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_10.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_11.png'), (400, 300)),
                  pygame.transform.scale(load_image('demon_walk_12.png'), (400, 300))]
    bg = load_image('bg.jpg')

    isJump = False
    jumpCount = 10
    fall = False

    class Hero(pygame.sprite.Sprite):
        def __init__(self, x, y, where, *group):
            super().__init__(*group)
            self.i = 0
            self.where = where
            if where == 'right':
                self.image = pygame.transform.scale(walk_right[0], (100, 100))
            else:
                self.image = pygame.transform.scale(walk_left[0], (100, 100))
            self.mask = pygame.mask.from_surface(self.image)
            self.rect = self.image.get_rect()
            self.rect.x = x
            self.rect.y = y
            self.k = 4
            self.foot = 5

        def update(self, where, move=True):
            global isJump, jumpCount, x, fall, dead, run_away, show_titles, running
            x_new = x
            fall = True
            for sprite in pads:
                if pygame.sprite.collide_mask(self, sprite):
                    fall = sprite.rect.y - sprite.rect.height / 2 <= self.rect.y <= \
                           sprite.rect.y + sprite.rect.height
                    if fall:
                        self.rect.y += 4
            if fall and not isJump:
                isJump = True
                jumpCount = -1
            if not fall and jumpCount <= 0:
                isJump = False
                jumpCount = 10
            if not isJump:
                if move:
                    self.i += 1
                    self.i = self.i % len(walk_right)
                    if self.where != where:
                        self.i = 0
                        self.where = where
                    if where == 'right':
                        self.image = pygame.transform.scale(walk_right[self.i], (100, 100))
                        x_new += self.foot
                    else:
                        self.image = pygame.transform.scale(walk_left[self.i], (100, 100))
                        x_new -= self.foot
                else:
                    self.i = 0
                    if where == 'right':
                        self.image = pygame.transform.scale(walk_right[self.i], (100, 100))
                    else:
                        self.image = pygame.transform.scale(walk_left[self.i], (100, 100))
            else:
                if jumpCount >= -10 or fall:
                    jumpCount -= 0.5
                    self.i += 1
                    y_down = 0
                    self.i = self.i % len(walk_right)
                    if move:
                        if where == 'right':
                            self.image = pygame.transform.scale(jump_right[self.i], (100, 100))
                            y_down -= jumpCount * self.k
                            x_new += self.foot
                        else:
                            self.image = pygame.transform.scale(jump_left[self.i], (100, 100))
                            y_down -= jumpCount * self.k
                            x_new -= self.foot
                    else:
                        if where == 'right':
                            self.image = pygame.transform.scale(jump_right[self.i], (100, 100))
                        else:
                            self.image = pygame.transform.scale(jump_left[self.i], (100, 100))
                        y_down -= jumpCount * self.k
                    y_down = int(y_down)
                    if y_down < 0:
                        end = 0
                        while y_down != 0:
                            self.rect.y -= 1
                            y_down += 1
                            for sprite in pads:
                                if pygame.sprite.collide_mask(self, sprite):
                                    if sprite.rect.y - sprite.rect.height / 2 <= self.rect.y <= \
                                            sprite.rect.y + sprite.rect.height:
                                        jumpCount = -1
                                        end = 1
                                        break
                                    else:
                                        jumpCount = 10
                                        isJump = False
                                        y_down = 0
                                        self.i = 0
                                        break
                            if end == 1:
                                break
                    else:
                        end = 0
                        while y_down != 0:
                            self.rect.y += 1
                            y_down -= 1
                            for sprite in pads:
                                if pygame.sprite.collide_mask(self, sprite):
                                    if sprite.rect.y - sprite.rect.height / 2 <= self.rect.y <= \
                                            sprite.rect.y + sprite.rect.height:
                                        jumpCount = -1
                                        end = 1
                                        break
                                    else:
                                        jumpCount = 10
                                        isJump = False
                                        y_down = 0
                                        self.i = 0
                                        break
                            if end == 1:
                                break
                else:
                    jumpCount = 10
                    isJump = False
                    self.i = 0
            self.mask = pygame.mask.from_surface(self.image)
            if not run_away and x_new < -645:
                x_new = -645
            if run_away and x_new < -670 and self.rect.y >= 550:
                sea.stop()
                splash.play()
                screen.fill((0, 0, 0))
                pygame.display.flip()
                clock.tick(0.5)
                get_achievement.play()
                return 3, achievements
            for sprite in enemies:
                if pygame.sprite.collide_mask(self, sprite):
                    dead = True
                    if self.rect.y < -50:
                        achievements.append('Вне границ')
                        get_achievement.play()
            if self.rect.y >= 650:
                dead = True
            if (500 <= x_new <= 600 and not first_titles_shown) or \
                    (x_new >= 9100 and not second_titles_shown and not isJump) or \
                    (500 <= x_new <= 600 and not isJump and not third_titles_shown and run_away):
                show_titles = True
            return x_new, self.rect.y

        def stay(self):
            self.i = 0
            if self.where == 'right':
                self.image = pygame.transform.scale(walk_right[self.i], (100, 100))
            else:
                self.image = pygame.transform.scale(walk_left[self.i], (100, 100))

        def change_jump(self):
            global isJump
            isJump = not isJump
            self.i = 0

    class Pad(pygame.sprite.Sprite):
        image = pygame.transform.scale(load_image('Pad_3_3.png'), (415, 65))
        image1 = pygame.transform.scale(load_image('Pad_3_3.png'), (350, 80))

        def __init__(self, place, y, type):
            super().__init__(all_sprites)
            if type == 1:
                self.image = Pad.image
            else:
                self.image = Pad.image1
            self.rect = self.image.get_rect()
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.x = 1000
            self.rect.y = y
            self.add(pads)
            self.place = place

        def update(self):
            global x, y
            # Для расположения менять здесь
            self.rect.x = self.place - x

    class Sea(pygame.sprite.Sprite):
        image = load_image('sea.png')

        def __init__(self):
            super().__init__(all_sprites)
            self.image = Sea.image
            self.rect = self.image.get_rect()
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.x = 1000
            self.rect.y = 560
            self.add(static_objects)
            self.sound = pygame.mixer.Sound(os.path.join(directory, 'WindySea.wav'))
            self.play = False

        def update(self):
            global x, y
            # Для расположения менять здесь
            self.rect.x = -1200 - x
            if self.rect.x > -980:
                if not self.play:
                    self.sound.play(-1)
                    self.play = True
            else:
                self.sound.stop()
                self.play = False

        def stop(self):
            self.sound.stop()
            self.play = False

    class Enemy(pygame.sprite.Sprite):

        def __init__(self, start, end, y):
            super().__init__(all_sprites)
            self.i = 0
            self.place_x = start
            self.move = 'right'
            self.image = pygame.transform.flip(enemy_walk[self.i], 90, 0)
            self.rect = self.image.get_rect()
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.y = y
            self.start = start
            self.end = end
            self.add(enemies)
            self.foot = 4

        def update(self):
            global x
            self.i += 1
            self.i %= len(enemy_walk)
            if self.place_x > self.end:
                self.move = 'left'
                self.i = 0
            elif self.place_x < self.start:
                self.move = 'right'
                self.i = 0
            if self.move == 'right':
                self.image = pygame.transform.flip(enemy_walk[self.i], 90, 0)
                self.place_x += self.foot
            else:
                self.image = enemy_walk[self.i]
                self.place_x -= self.foot
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.x = self.place_x - x

    class Pursuit(pygame.sprite.Sprite):
        def __init__(self, start, end, y, y_up):
            super().__init__(all_sprites)
            self.frames_run = cut_sheet(load_image('Run.png'), 1, 6)
            self.frames_attack = cut_sheet(load_image('All Attacks.png'), 1, 29)
            self.i = 0
            self.place_x = end
            self.move = 'left'
            self.image = pygame.transform.scale(pygame.transform.flip(
                enemy_walk[self.i], 90, 0), (200, 300))
            self.rect = self.image.get_rect()
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.y = y
            self.start = start
            self.end = end
            self.add(enemies)
            self.foot = 6
            self.y_up = y_up
            self.attack = False

        def update(self):
            global x, y
            if not self.attack:
                if self.start - 450 <= x <= self.end - 555 and y > self.y_up:
                    if self.move == 'left':
                        near = 0 <= abs(abs(self.place_x - x) - 300) - 20 <= 50
                    else:
                        near = 0 <= abs(self.place_x - x) <= 50
                    if near:
                        if self.place_x < x:
                            self.move = 'left'
                        else:
                            self.move = 'right'
                        self.attack = True
                        self.i = 0
                    else:
                        self.i += 1
                        self.i %= len(self.frames_run)
                        if self.place_x < x and self.move != 'right':
                            self.move = 'right'
                            self.i = 0
                        elif self.place_x > x and self.move != 'left':
                            self.move = 'left'
                            self.i = 0
                        if self.move == 'left':
                            self.image = pygame.transform.scale(pygame.transform.flip(
                                self.frames_run[self.i], 90, 0), (300, 300))
                            self.place_x -= self.foot
                        else:
                            self.image = pygame.transform.scale(self.frames_run[self.i], (300, 300))
                            self.place_x += self.foot
                else:
                    self.i += 1
                    self.i %= len(self.frames_run)
                    if self.place_x > self.end:
                        self.move = 'left'
                        self.i = 0
                    elif self.place_x < self.start:
                        self.move = 'right'
                        self.i = 0
                    if self.move == 'left':
                        self.image = pygame.transform.scale(pygame.transform.flip(
                            self.frames_run[self.i], 90, 0), (300, 300))
                        self.place_x -= self.foot
                    else:
                        self.image = pygame.transform.scale(self.frames_run[self.i], (300, 300))
                        self.place_x += self.foot
            else:
                self.i += 1
                if self.move == 'left':
                    self.image = pygame.transform.scale(pygame.transform.flip(
                        self.frames_attack[self.i], 90, 0), (300, 300))
                else:
                    self.image = pygame.transform.scale(self.frames_attack[self.i], (300, 300))
                if self.i + 1 >= len(self.frames_attack):
                    self.attack = False
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.x = self.place_x - x

    def cut_sheet(sheet, columns, rows):
        rect = pygame.Rect(0, 0, sheet.get_width() // columns,
                           sheet.get_height() // rows)
        frames = []
        for j in range(rows):
            for i in range(columns):
                frame_location = (rect.w * i, rect.h * j)
                frames.append(sheet.subsurface(pygame.Rect(
                    frame_location, rect.size)))
        return frames

    class RunningShootingGuy(pygame.sprite.Sprite):
        def __init__(self, start, end, y, points):
            super().__init__(all_sprites)
            self.frames_run = cut_sheet(load_image('Sci-fi Samurai Bandit-Spritet.png'), 6, 6)[:12]
            self.frames_attack = cut_sheet(load_image('blood explosion gun spell-Sheet.png'), 1, 19)
            self.i = 0
            self.place_x = end
            self.move = 'left'
            self.image = pygame.transform.scale(
                pygame.transform.flip(self.frames_run[self.i], 90, 0),
                (300, 300))
            self.rect = self.image.get_rect()
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.y = y
            self.start = start
            self.end = end
            self.add(enemies)
            self.foot = 4
            self.points = points
            self.next = self.points[-1]
            self.i_next = -1
            self.shoot = False
            self.were = [0]

        def update(self):
            if self.move == 'right':
                rule = self.next - self.foot <= self.place_x <= self.next + self.foot
            else:
                rule = self.next - self.foot <= self.place_x + 300 <= self.next + self.foot
            if rule:
                self.shoot = True
                if self.move == 'left':
                    self.i_next -= 1
                    if abs(self.i_next) > len(self.points):
                        self.i_next = -1
                    self.place_x -= 800
                else:
                    self.i_next += 1
                    if self.i_next >= len(self.points):
                        self.i_next = 0
                self.next = self.points[self.i_next]
                self.i = 0
            if self.shoot:
                tm = pygame.time.get_ticks() // 100
                if tm not in self.were:
                    self.i += 1
                    if self.i >= len(self.frames_attack):
                        self.shoot = False
                        if self.move == 'left':
                            self.place_x += 800
                    else:
                        if self.move == 'left':
                            self.image = pygame.transform.scale(
                                pygame.transform.flip(self.frames_attack[self.i], 90, 0),
                                (1200, 300))
                        else:
                            self.image = pygame.transform.scale(self.frames_attack[self.i],
                                                                (1200, 300))
                    del self.were[-1]
                    self.were.append(tm)
            if not self.shoot:
                self.i += 1
                self.i %= len(self.frames_run)
                if self.place_x > self.end:
                    self.move = 'left'
                    self.i = 0
                    self.i_next = -1
                    self.next = self.points[self.i_next]
                elif self.place_x < self.start:
                    self.move = 'right'
                    self.i = 0
                    self.i_next = 0
                    self.next = self.points[self.i_next]
                if self.move == 'left':
                    self.image = pygame.transform.scale(
                        pygame.transform.flip(self.frames_run[self.i], 90, 0), (300, 300))
                    self.place_x -= self.foot
                else:
                    self.image = pygame.transform.scale(self.frames_run[self.i], (300, 300))
                    self.place_x += self.foot
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.x = self.place_x - x

    class WaitBomb(pygame.sprite.Sprite):
        def __init__(self, place_x, y):
            super().__init__(all_sprites)
            self.frames_stay = cut_sheet(load_image('Idle.png'), 1, 4)
            self.frames_attack = cut_sheet(load_image('Attack.png'), 1, 9)
            self.i = 0
            self.place_x = place_x
            self.image = pygame.transform.scale(self.frames_stay[self.i], (400, 300))
            self.rect = self.image.get_rect()
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.y = y
            self.add(enemies)
            self.shoot = False
            self.were = [0]
            self.pause = 0

        def update(self):
            if 80 <= self.rect.x <= 680 and not self.shoot:
                self.i = 0
                self.shoot = True
            tm = pygame.time.get_ticks() // 200
            if tm not in self.were:
                if not self.shoot and not self.pause:
                    self.i += 1
                    self.i %= len(self.frames_stay)
                    self.image = pygame.transform.scale(self.frames_stay[self.i], (400, 300))
                elif self.pause:
                    self.i = 0
                    self.image = pygame.transform.scale(self.frames_stay[self.i], (400, 300))
                    self.pause -= 1
                else:
                    self.i += 1
                    self.image = pygame.transform.scale(self.frames_attack[self.i], (600, 300))
                    if self.i + 1 >= len(self.frames_attack):
                        self.i = 0
                        self.shoot = False
                        self.pause = 15
                del self.were[-1]
                self.were.append(tm)
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.x = self.place_x - x

    class AnimatedSprite(pygame.sprite.Sprite):
        def __init__(self, sheet, columns, rows, x, y, size, mirror=False, ps=False):
            super().__init__(all_sprites)
            self.frames = []
            self.cut_sheet(sheet, columns, rows)
            self.cur_frame = 0
            self.image = self.frames[self.cur_frame]
            self.mask = pygame.mask.from_surface(self.image)
            self.rect.move(x, y)
            self.place_x = x
            self.rect.y = y
            self.add(static_objects)
            self.size = size
            self.were = [0]
            if mirror:
                new_frames = self.frames.copy()
                for elem in self.frames:
                    new_frames.append(pygame.transform.flip(elem, 90, 0))
                self.frames = new_frames.copy()
            self.ps = ps
            self.stopped = 0

        def cut_sheet(self, sheet, columns, rows):
            self.rect = pygame.Rect(0, 0, sheet.get_width() // columns,
                                    sheet.get_height() // rows)
            for j in range(rows):
                for i in range(columns):
                    frame_location = (self.rect.w * i, self.rect.h * j)
                    self.frames.append(sheet.subsurface(pygame.Rect(
                        frame_location, self.rect.size)))

        def update(self):
            global x
            tm = pygame.time.get_ticks() // 100
            if tm not in self.were:
                if self.ps and (self.cur_frame + 1) % len(self.frames) == 1 and self.stopped < 15:
                    self.cur_frame -= 1
                    self.stopped += 1
                else:
                    self.stopped = 0
                self.cur_frame = (self.cur_frame + 1) % len(self.frames)
                self.image = pygame.transform.scale(self.frames[self.cur_frame], self.size)
                del self.were[-1]
                self.were.append(tm)
            self.mask = pygame.mask.from_surface(self.image)
            # Для расположения менять здесь
            self.rect.x = self.place_x - x

    class BlackSquare(pygame.sprite.Sprite):
        def __init__(self, size_x, size_y, pos):
            super().__init__(all_sprites)
            self.size_x = size_x
            self.size_y = size_y
            self.place_x = pos[0]
            self.image = pygame.Surface((size_x, size_y),
                                        pygame.SRCALPHA, 32)
            pygame.draw.rect(self.image, pygame.Color("black"), (0, 0, size_x, size_y))
            self.rect = pygame.Rect(self.place_x, -100, size_x, size_y)
            self.mask = pygame.mask.from_surface(self.image)
            self.add(enemies)
            self.foot = 1.9

        def update(self):
            global x
            if run_away:
                self.size_x += self.foot
                self.place_x -= self.foot
                self.image = pygame.Surface((self.size_x, self.size_y),
                                            pygame.SRCALPHA, 32)
                pygame.draw.rect(self.image, pygame.Color("black"),
                                 (0, 0, self.size_x, self.size_y))
                self.rect = pygame.Rect(self.place_x - x, -100, self.size_x, self.size_y)
                self.mask = pygame.mask.from_surface(self.image)

    all_sprites = pygame.sprite.Group()
    pads = pygame.sprite.Group()
    static_objects = pygame.sprite.Group()
    enemies = pygame.sprite.Group()
    Enemy(-80, 215, 105)
    Enemy(1620, 1900, -145)
    Enemy(3850, 4110, 205)
    sea = Sea()
    start = -100
    for i in range(4):
        Pad(start + i * 415, 590, 1)
    for i in range(3):
        Pad(2400 + i * 325, 500, 2)
    Pad(1400, 400, 2)
    Pad(100, 400, 2)
    Pad(1800, 150, 2)
    Pad(1700, 600, 2)
    Pad(2100, 450, 2)
    Pad(3200, 250, 2)
    Pad(3600, 400, 1)
    Pad(4000, 500, 2)
    for i in range(15):
        Pad(4300 + i * 340, 600, 2)
    for i in range(4):
        Pad(4810 + i * 1400, 350, 2)
    Pad(9500, 450, 2)

    jump_where = 'right'
    hero = Hero(x, y, jump_where, all_sprites)
    dead = False
    pause = False
    run_away = False
    running = True
    showed_death = False
    show_titles = False
    pressed_enter = False
    end_screen = GameOver(width, height)
    pause_screen = Pause(width, height)
    manager_game_over = pygame_gui.UIManager((width, height))
    manager_pause = pygame_gui.UIManager((width, height))
    game_over_sound = pygame.mixer.Sound(os.path.join(directory, 'Game over.mp3'))
    splash = pygame.mixer.Sound(os.path.join(directory, 'Jumping into water.mp3'))
    typing = pygame.mixer.Sound(os.path.join(directory, 'Typing.mp3'))
    end_typing = pygame.mixer.Sound(os.path.join(directory, 'End typing.mp3'))
    get_achievement = pygame.mixer.Sound(os.path.join(directory, 'Achievement.wav'))
    game_over_sound.set_volume(3)
    Pursuit(4300, 9100, 350, 300)
    RunningShootingGuy(4300, 9400, 350, [4300, 5000, 5700, 6400, 7100, 8800, 9400])
    for i in range(3):
        WaitBomb(5600 + i * 1350, 380)
    BlackSquare(1000, 1000, (9700, -100))
    portal = AnimatedSprite(load_image("Purple Portal Sprite Sheet.png"), 8, 1, 800, 350,
                            (300, 300))
    drone_portal = AnimatedSprite(load_image('Guardian Sprite-Sheet.png'), 1, 39, 1710, 480,
                                  (350, 200), True)
    drone_portal1 = AnimatedSprite(load_image('Guardian Sprite-Sheet.png'), 1, 39, 3600, 280,
                                   (350, 200), True)
    shooter = AnimatedSprite(
        pygame.transform.flip(load_image('blood explosion gun spell-Sheet.png'),
                              90, 0), 1, 19, 2300, 300, (1200, 300), ps=True)
    drone_portal.add(enemies)
    drone_portal1.add(enemies)
    shooter.add(enemies)
    first_titles = Titles(
        '[Главный герой:] Где это я?|| И что с моим телом?£ '
        '[Смерть:] Ты в магическом мире, это последнее испытание.| &Я перенес тебя в другое тело, так '
        'как твое слишком дряхлое.£ '
        '[Главный герой:] Хорошо, нужно будет занятся спортом.| Еще чуть-чуть и я смогу вернуться.£ '
        '[Смерть:] Опасайся монстров, они убьют тебя без раздумий и меч тут не поможет.£ ' * (
                LANGUAGE == 'Русский') +
        "[Main hero:] Where am I? What's with my body?£ "
        "[Death:] You're in the magic world. It's your last trial.| &I transferred you to another body "
        "because yours is too decrepit.£ "
        "[Main hero:] Ok, I'll need to do some sports after return.| Just a little more and I can come "
        "back.£ "
        "[Death:] Be careful, monsters can easily kill you and your sword won't help you.£ " * (
                LANGUAGE == 'English'), width, height,
        os.path.join(directory, 'CinecavXSans-Regular.ttf'))
    first_titles_shown = False
    second_titles = Titles(
        '[Главный герой:] И куда теперь?£ '
        '[Смерть:] Хм|.|.|.| Все должно было быть по другому£ '
        '[Неизвестный голос:] Ты отсюда никогда не выберешься!| &Ты не заботился о своих близких и '
        'думал только о себе!£ '
        '[Смерть:] Что-то надвигается, беги обратно в портал!£ ' * (
                LANGUAGE == 'Русский') +
        "[Main hero:] So where should I go?£ "
        "[Death:] Hmm|.|.|.| Everything should have been different£ "
        "[Unknown:] You'll never get out!| &You didn't care about your loved ones and thought only "
        "about yourself!£ "
        "[Death:] Something is happening, run back to the portal!£ " * (
                LANGUAGE == 'English'), width, height,
        os.path.join(directory, 'CinecavXSans-Regular.ttf'))
    second_titles_shown = False
    third_titles = Titles(
        '[Главный герой:] Я не могу зайти в портал!£ '
        '[Смерть:] Я не могу ничего с этим сделать!| Видимо, придется прыгать в воду.£ ' * (
                LANGUAGE == 'Русский') +
        "[Main hero:] I can't enter the portal!£ "
        "[Death:] I can do nothing!| Apparently, you'll have to jump into water.£ " * (
                LANGUAGE == 'English'), width, height,
        os.path.join(directory, 'CinecavXSans-Regular.ttf'))
    third_titles_shown = False
    button_back_main_window = pygame_gui.elements.UIButton(
        relative_rect=pygame.Rect((400, 355, 200, 50)),
        text='На главный экран' * (LANGUAGE == 'Русский') + 'Main Window' * (LANGUAGE == 'English'),
        manager=manager_game_over
    )
    button_last_save = pygame_gui.elements.UIButton(
        relative_rect=pygame.Rect((400, 300, 200, 50)),
        text='К последнему сохранению' * (LANGUAGE == 'Русский') + 'Last checkpoint' * (
                LANGUAGE == 'English'),
        manager=manager_game_over
    )

    button_back_main_window_pause = pygame_gui.elements.UIButton(
        relative_rect=pygame.Rect((25, 575, 200, 50)),
        text='На главный экран' * (LANGUAGE == 'Русский') + 'Main Window' * (LANGUAGE == 'English'),
        manager=manager_pause
    )
    button_last_save_pause = pygame_gui.elements.UIButton(
        relative_rect=pygame.Rect((400, 270, 200, 50)),
        text='К последнему сохранению' * (LANGUAGE == 'Русский') + 'Last checkpoint' * (
                LANGUAGE == 'English'),
        manager=manager_pause
    )
    if SOUND_TITLES:
        button_sound_titles = pygame_gui.elements.UIButton(
            relative_rect=pygame.Rect((775, 575, 200, 50)),
            text='Звук титров: включён' * (LANGUAGE == 'Русский') + 'Caption sound: on' * (
                    LANGUAGE == 'English'),
            manager=manager_pause
        )
    else:
        button_sound_titles = pygame_gui.elements.UIButton(
            relative_rect=pygame.Rect((775, 575, 200, 50)),
            text='Звук титров: выключен' * (LANGUAGE == 'Русский') + 'Caption sound: off' * (
                    LANGUAGE == 'English'),
            manager=manager_pause
        )
    while running:
        time_delta = clock.tick(60) / 1000.0
        for event in pygame.event.get():
            if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and
                                             event.key == pygame.K_ESCAPE):
                pause = not pause
            if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
                pressed_enter = True
            if event.type == pygame.USEREVENT:
                if event.user_type == pygame_gui.UI_BUTTON_PRESSED:
                    if event.ui_element in (
                            button_back_main_window, button_back_main_window_pause):
                        return 0, achievements
                    elif event.ui_element in (button_last_save, button_last_save_pause):
                        return 1, achievements
                    if event.ui_element == button_sound_titles:
                        SOUND_TITLES = not SOUND_TITLES
                        button_sound_titles.kill()
                        if SOUND_TITLES:
                            button_sound_titles = pygame_gui.elements.UIButton(
                                relative_rect=pygame.Rect((775, 575, 200, 50)),
                                text='Звук титров: включён' * (
                                        LANGUAGE == 'Русский') + 'Caption sound: on' * (
                                             LANGUAGE == 'English'),
                                manager=manager_pause
                            )
                        else:
                            button_sound_titles = pygame_gui.elements.UIButton(
                                relative_rect=pygame.Rect((775, 575, 200, 50)),
                                text='Звук титров: выключен' * (
                                        LANGUAGE == 'Русский') + 'Caption sound: off' * (
                                             LANGUAGE == 'English'),
                                manager=manager_pause
                            )
            manager_game_over.process_events(event)
            manager_pause.process_events(event)
        if dead:
            if not showed_death:
                sea.stop()
                game_over_sound.play()
                clock.tick(0.5)
                showed_death = True
            end_screen.update(time_delta, screen, manager_game_over)
        elif pause:
            sea.stop()
            for elem in [first_titles, second_titles]:
                elem.pause(typing, end_typing)
            pause_screen.update(time_delta, screen, manager_pause)
        else:
            if not show_titles:
                keys = pygame.key.get_pressed()
                if not isJump and keys[pygame.K_SPACE]:
                    hero.change_jump()
                if keys[pygame.K_LEFT]:
                    jump_where = 'left'
                    x, y = hero.update(jump_where)
                elif keys[pygame.K_RIGHT]:
                    jump_where = 'right'
                    x, y = hero.update(jump_where)
                else:
                    x, y = hero.update(jump_where, move=False)
                for sprite in pads:
                    sprite.update()
                for sprite in static_objects:
                    sprite.update()
                for sprite in enemies:
                    sprite.update()
                screen.fill('black')
                screen.blit(bg, (0, 0))
                all_sprites.draw(screen)
            else:
                x, y = hero.update(jump_where, move=False)
                screen.fill('black')
                screen.blit(bg, (0, 0))
                all_sprites.draw(screen)
                if 500 <= x <= 600 and not first_titles_shown:
                    if SOUND_TITLES:
                        first_titles_shown, pressed_enter = first_titles.update(screen, clock,
                                                                                pressed_enter,
                                                                                'black',
                                                                                typing,
                                                                                end_typing)
                    else:
                        first_titles_shown, pressed_enter = first_titles.update(screen, clock,
                                                                                pressed_enter,
                                                                                'black')
                    if first_titles_shown:
                        show_titles = False
                        pressed_enter = False
                if x >= 9100 and not second_titles_shown and not isJump:
                    if SOUND_TITLES:
                        second_titles_shown, pressed_enter = second_titles.update(screen, clock,
                                                                                pressed_enter,
                                                                                'black',
                                                                                typing,
                                                                                end_typing)
                    else:
                        second_titles_shown, pressed_enter = second_titles.update(screen, clock,
                                                                                pressed_enter,
                                                                                'black')
                    if second_titles_shown:
                        show_titles = False
                        pressed_enter = False
                        run_away = True
                if 500 <= x <= 600 and not isJump and not third_titles_shown and run_away:
                    if SOUND_TITLES:
                        third_titles_shown, pressed_enter = third_titles.update(screen, clock,
                                                                                pressed_enter,
                                                                                'black',
                                                                                typing,
                                                                                end_typing)
                    else:
                        third_titles_shown, pressed_enter = third_titles.update(screen, clock,
                                                                                pressed_enter,
                                                                                'black')
                    if third_titles_shown:
                        show_titles = False
                        pressed_enter = False
        pygame.display.flip()
        clock.tick(FPS)
    pygame.quit()


import sys
import re
import glob
from collections import Counter

# files = glob.glob(sys.argv[1])

skipList = []

words = []
phrases = {1:[],2:[],3:[],4:[],5:[]}

print('Files Checked:')
for filename in sys.argv[1:]:
	if filename in skipList:
		continue

	print('\t'+filename)
	with open(filename, 'r') as fin:
	    content = fin.read()

	## Chew up new lines replacing them with spaces and also remove comments
	lines = content.split('\n')
	content = ''
	sep = ''
	for line in lines:
		lineWithComment = line.split('%')[0]
		if len(lineWithComment):
			content += sep + lineWithComment
			sep = ' '

	## Replace latex newlines with spaces
	content = content.replace('\\\\', ' ')

	## Remove punctuation for our needs, this can lead to potentially misleading
	## results since it will potentially put ends of sentences together with
	## beginnings of sentences for phrases, but I care less about false positives,
	## and would prefer to err on the side of reporting too much, remember the job
	## is to make the writing more distinct.
	punctuation = '\.|!|`|,|\?|;|:|\"|\'|\(|\)'
	content = re.sub(punctuation, ' ', content)

	## Make all of the opening and closing brackets their own token for easing the
	## handling later
	content = re.sub('\{', ' { ', content)
	content = re.sub('\}', ' } ', content)
	content = re.sub('\[', ' [ ', content)
	content = re.sub('\]', ' ] ', content)

	## Let us begin the counting
	tokens = re.split('~| ', content)

	## Are we currently inside a command? If so, then ignore everything until we are
	## back at the base level
	insideCommand = 0

	## Are we currently inside a command? If so, then ignore everything until we are
	## back at the base level
	insideBracket = 0

	for i in range(len(tokens)):
		token = tokens[i]
		if not len(token):
			continue

		if token in '{}[]':
			if token == '{':
				insideCommand += 1
			elif token == '}':
				insideCommand -= 1
				if insideCommand < 0:
					print('Error where text resembles: '+' '.join(tokens[(i-5):(i+5)]))
			elif token == '[':
				insideBracket += 1
			else:
				insideBracket -= 1
				if insideBracket < 0:
					print('Error where text resembles: '+' '.join(tokens[(i-5):(i+5)]))
		elif token.startswith('\\'):
			pass
		else:
			if not (insideCommand+insideBracket):
				words.append(token.lower())
			else:
				pass

## Again can cause potentially misleading results since file order is not
## specified, and we will group words together that are from different files,
## but the goal is to identify repeated phrases, if these so happen to generate
## real phrases, then it will not hurt to show them. More likely, they will
## create non-sense phrases that will be filtered out when we look at the
## highest frequency occurences. Basically, not worth the effort to do
## it correctly.
for count in phrases.keys():
	for i in range(len(words)-count):
		phrases[count].append(' '.join(words[i:(i+count)]))

rankLimit = 20

print('\nTotal word count: %d' % len(words))
for count,phraseC in phrases.items():
	commonCounts = Counter(phraseC).most_common(rankLimit)
	print('\n%d most common %d-word phrases:' % (rankLimit,count))
	for key,val in commonCounts:
		print('\t%s: %d' % (key,val))