import os
import numpy as np
import torch
import torch.utils.data
import matplotlib.pyplot as plt
from PIL import Image

#データセットの定義
class DroneDataset(torch.utils.data.Dataset):
    def __init__(self, root, transforms=None):
        self.root = root
        self.transforms = transforms
        # load all image files, sorting them to
        # ensure that they are aligned
        self.imgs = list(sorted(os.listdir(os.path.join(root, "images")))) #images
        self.txt_files = list(sorted(os.listdir(os.path.join(root, "annotations")))) #bounding boxes and labels

    def __getitem__(self, idx):
        # load images ad masks
        img_path = os.path.join(self.root, "images", self.imgs[idx]) #get path of image with idx
        txt_path = os.path.join(self.root, "annotations", self.txt_files[idx]) #get path of txt with idx
        img = Image.open(img_path).convert("RGB") #open the image and convert it to RGB

        obj_ids=np.arange(12) #ids are 0 ~ 11, as listed below.
        """
        ignored regions(0), pedestrian(1),people(2), bicycle(3), car(4), van(5),
        truck(6), tricycle(7), awning-tricycle(8), bus(9), motor(10),
        others(11)
        """

        # get every bounding box coordinate from the txt file.
        num_objs = len(obj_ids)
        boxes = []
        labels = []
        with open(txt_path) as f:
            for line in f:
                x, y, w, h, score,category,l3,l4 = line.split(",")
                xmin = int(x)
                ymin = int(y)
                xmax = int(x) + int(w) #int(x+w)
                ymax = int(y) + int(h)
                boxes.append([xmin, ymin, xmax, ymax])
                labels.append(int(category))

        # create mask image
        width,height = img.size
        bbmasks = []
        for box in boxes:
            bbmask = np.zeros((height, width))
            bbmask = bbmask.astype(int)
            #bb = box#.astype(np.int)
            bbmask[box[1]:box[3], box[0]:box[2]] = int(1.) #set the area of the bounding box to 1
            bbmasks.append(bbmask)

        #convert everything into a torch.tensor type
        boxes = torch.as_tensor(boxes, dtype=torch.float32)
        labels = torch.as_tensor(labels, dtype=torch.float32)
        bbmasks = torch.as_tensor(bbmasks, dtype=torch.uint8)
        # ? change later
        #labels = torch.ones((num_objs,), dtype=torch.int64)
#         masks = torch.as_tensor(masks, dtype=torch.uint8)

        image_id = torch.tensor([idx])
        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
        # suppose all instances are not crowd
        iscrowd = torch.zeros((num_objs,), dtype=torch.int64)

        target = {}
        target["boxes"] = boxes
        target["masks"] = bbmasks
        target["labels"] = labels
        target["image_id"] = image_id
        target["area"] = area
        target["iscrowd"] = iscrowd
        #no keypoints for this excercise
        """
        target["boxes"] = boxes
        target["labels"] = labels
        target["masks"] = masks
        target["image_id"] = image_id
        target["area"] = area
        target["iscrowd"] = iscrowd
        """
        if self.transforms is not None:
            img, target = self.transforms(img, target)

        return img, target

    def __len__(self):
        return len(self.imgs)

#maskとbounding boxを相互に変換するための関数
def bb_to_rect(box): #take in 'boxes' item from dataset
    box = np.array(box, dtype=np.float32) #convert from tensor to numpy array
    #box: array([6.84000e+02, 8.00000e+00, 6.84273e+05, 8.11600e+03], dtype=float32)
    return plt.Rectangle((box[0], box[1]), box[2]-box[0], box[3]-box[1], color='red',fill=False, lw=1)

#def mask_to_bb():

def show_one_bb(image,box):
    fig,ax = plt.subplots(1)
    ax.imshow(image)
    rect = bb_to_rect(box = box)
    ax.add_patch(rect)
    return plt.show()

def show_all_bb(image,boxes):
    fig,ax = plt.subplots(1)
    ax.imshow(image)
    for box in boxes:
        ax.add_patch(bb_to_rect(box = box))
    return plt.show()

"""
#データセットの作成
dataset = DroneDataset('VisDrone2019-DET-train/')
print("dataset created")
"""

#pretrain 済みのmodelを引っ張り出す
import torchvision
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
from torchvision.models.detection.mask_rcnn import MaskRCNNPredictor

def get_instance_segmentation_model(num_classes):
    # load an instance segmentation model pre-trained on COCO
    model = torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True)

    # get the number of input features for the classifier
    in_features = model.roi_heads.box_predictor.cls_score.in_features
    # replace the pre-trained head with a new one
    model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)

    # now get the number of input features for the mask classifier
    in_features_mask = model.roi_heads.mask_predictor.conv5_mask.in_channels
    hidden_layer = 256
    # and replace the mask predictor with a new one
    model.roi_heads.mask_predictor = MaskRCNNPredictor(in_features_mask,
                                                       hidden_layer,
                                                       num_classes)
    return model
print("got the pretrained model")

#データのaugmentation, transformation.
from engine import train_one_epoch, evaluate
import utils
import transforms as T

def get_transform(train):
    transforms = []
    # converts the image, a PIL image, into a PyTorch Tensor
    transforms.append(T.ToTensor())
    if train:
        # during training, randomly flip the training images
        # and ground-truth for data augmentation
        transforms.append(T.RandomHorizontalFlip(0.5))
    return T.Compose(transforms)

#構築
# use our dataset and defined transformations
dataset = DroneDataset('VisDrone2019-DET-train/', get_transform(train=True))
dataset_test = DroneDataset('VisDrone2019-DET-train/', get_transform(train=False))
print("split the dataset into training and testing")
# split the dataset in train and test set
torch.manual_seed(1)
indices = torch.randperm(len(dataset)).tolist() #returns a list of indexes.
dataset = torch.utils.data.Subset(dataset, indices[:-50]) #exclude last 50
dataset_test = torch.utils.data.Subset(dataset_test, indices[-50:])
print("excluded last 50")

# define training and validation data loaders
data_loader = torch.utils.data.DataLoader(
    dataset, batch_size=2, shuffle=True, num_workers=4,
    collate_fn=utils.collate_fn)

data_loader_test = torch.utils.data.DataLoader(
    dataset_test, batch_size=1, shuffle=False, num_workers=4,
    collate_fn=utils.collate_fn)
print("set data loaders")

#GPU環境の整備
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')

# our dataset has two classes only - background and person
num_classes = 1

# get the model using our helper function
model = get_instance_segmentation_model(num_classes)# the one we defined
# move model to the right device
model.to(device)

# construct an optimizer
params = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.SGD(params, lr=0.005,
                            momentum=0.9, weight_decay=0.0005)

# and a learning rate scheduler which decreases the learning rate by
# 10x every 3 epochs
lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                               step_size=3,
                                               gamma=0.1)
print("setup GPU environment")

#10 epoch 分の訓練
num_epochs = 10
print("starting training")
for epoch in range(num_epochs):
    # train for one epoch, printing every 10 iterations
    train_one_epoch(model, optimizer, data_loader, device, epoch, print_freq=10)
    # update the learning rate
    lr_scheduler.step()
    # evaluate on the test dataset
    evaluate(model, data_loader_test, device=device)
print("finished training")

#結果を見てみる。
# pick one image from the test set
img, _ = dataset_test[0]
# put the model in evaluation mode
model.eval()
with torch.no_grad():
    prediction = model([img.to(device)])

# prediction
Image.fromarray(img.mul(255).permute(1, 2, 0).byte().numpy()).save(fp="output/image.jpg")
Image.fromarray(prediction[0]['masks'][0, 0].mul(255).byte().cpu().numpy()).save(fp="output/mask.jpg")
"""
image  = dataset[0][0]
boxes  = dataset[0][1]["boxes"]
show_all_bb(image,boxes)
"""

"""
in the pytorch tutorial the masks are images with different colors for each mask.
in the 前処理段階 it splits each color into different binary masks

in the pytorch tutorial the masks rarely overlap, and every instance in a certain category is put into one mask. For example, if there are 3 people in an image, only one mask is generated for the category "people" with all 3 people on that mask. (i.e. only 1 mask is generated, not 3.)
Here I've made an individual mask for each instance, and have not been able to link the category labels to each instance.

"""


# _*_ coding:utf-8 _*_
# __Author__： zizle
import json
import os
import datetime
from django.conf import settings
from django.core.paginator import Paginator
from django.views.generic import View
from django.http.response import HttpResponse
from .forms import NewsBulletinForm, AdvertisementForm, NormalReportForm, TransactionNoticeForm
from .models import NewsBulletin, Advertisement, DataCategory, NormalReport, TransactionNotice, SpotCommodity, FinanceCalendar
from .serializers import NewsBulletinSerializer, AdvertisementSerializer, DataCategorySerializer, NormalReportSerializer,\
    TransactionNoticeSerializer, SpotCommoditySerializer, FinanceCalendarSerializer
from basic.models import Variety
from utils.client import get_client
from utils.auth import variety_user_accessed

# 新闻公告视图
class NewsBulletinView(View):
    def get(self, request):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        if not client:
            news = NewsBulletin.objects.none()
        else:
            news = NewsBulletin.objects.order_by('-create_time').all()[:30]  # 返回前30条
        serializer = NewsBulletinSerializer(instance=news, many=True)
        return HttpResponse(
            content=json.dumps({"message": '获取公告数据成功!', "data": serializer.data}),
            content_type="application/json; charset=utf-8",
            status=200
        )

    def post(self, request):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            if not request_user or not request_user.is_operator:
                raise ValueError('还未登录或不能进行这项操作!')
            title = request.POST.get('title', None)
            if not title:
                raise ValueError('请输入公告标题!')
            file = request.FILES
            if file:
                # 组织好数据
                data_to_save = {
                    'title': title,
                    'creator': request_user.id,
                    'content': '',
                }
                form = NewsBulletinForm(data_to_save, request.FILES)
                if form.is_valid():
                    form.save()
                    message = '上传文件成功!'
                    status_code = 201
                else:
                    raise ValueError(form.errors)
            else:

                content_text = request.POST.get('content', None)
                if not content_text:
                    raise ValueError('请输入公告内容!')
                news = NewsBulletin(
                    title=title,
                    creator_id=request_user.id,
                    content=content_text
                )
                news.save()
                message = '上传成功!'
                status_code = 201
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": {}}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 单个新闻公告视图
class NewsBulletinRetrieveView(View):
    def get(self, request, nid):
        # 获取当前公告数据返回
        try:
            news = NewsBulletin.objects.get(id=int(nid))
            serializer = NewsBulletinSerializer(instance=news)
            data = serializer.data
            message = '获取公告成功!'
            status_code = 200
        except NewsBulletin.DoesNotExist:
            message = '当前公告不存在!'
            status_code = 400
            data ={}
        return HttpResponse(
            content=json.dumps({"message": message, "data": data}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

    def delete(self, request, nid):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            if not request_user or not request_user.is_operator:
                raise ValueError('还没登录或不能进行这项操作!')
            news = NewsBulletin.objects.get(id=int(nid))
            if news.file:  # 删除原文件
                file_path = settings.MEDIA_ROOT + news.file.name
                if os.path.exists(file_path):
                    os.remove(file_path)
            news.delete()
            status_code = 200
            message = '删除公告成功!'
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": {}}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 更多新闻视图
class MoreNewsView(View):
    def get(self, request):
        machine = request.GET.get('mc', None)
        client = get_client(machine)
        try:
            if not client:
                raise ValueError('INVALIE CLIENT.')
            news = NewsBulletin.objects.order_by('-create_time').all()
            current_page = request.GET.get('page', 1)
            paginator = Paginator(object_list=news, per_page=25)
            news_list = paginator.get_page(current_page)
            serializer = NewsBulletinSerializer(instance=news_list, many=True)
            data = dict()
            data['contacts'] = serializer.data
            data['total_page'] = paginator.num_pages
            message = '获取新闻公告成功.'
            status_code = 200
        except Exception as e:
            message = str(e)
            status_code = 400
            data = dict()
            data['contacts'] = []
            data['total_page'] = 1
        return HttpResponse(
            content=json.dumps({"message": message, "data": data}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 广告视图
class AdvertiseView(View):
    def get(self, request):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        if not client:
            ads = Advertisement.objects.none()
        else:
            ads = Advertisement.objects.all()
        serializer = AdvertisementSerializer(instance=ads, many=True)
        return HttpResponse(
            content=json.dumps({"message": '获取广告数据成功!', "data": serializer.data}),
            content_type="application/json; charset=utf-8",
            status=200
        )

    def post(self, request):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            if not request_user or not request_user.is_operator:
                raise ValueError('还未登录或不能进行这项操作!')
            name = request.POST.get('name', None)
            if not name:
                raise ValueError('请输入广告标题!')
            files = request.FILES
            if files:
                # 组织好数据
                data_to_save = {
                    'name': name,
                    'creator': request_user.id,
                    'content': request.POST.get('content', ''),
                }
                form = AdvertisementForm(data_to_save, request.FILES)
                if form.is_valid():
                    form.save()
                else:
                    raise ValueError(form.errors)
            message = '上传成功!'
            status_code = 201
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": {}}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 单个广告视图
class AdvertiseRetrieveView(View):
    def get(self, request, aid):
        # 获取当前广告数据返回
        try:
            ad = Advertisement.objects.get(id=int(aid))
            serializer = AdvertisementSerializer(instance=ad)
            data = serializer.data
            message = '获取广告成功!'
            status_code = 200
        except NewsBulletin.DoesNotExist:
            message = '当前广告不存在!'
            status_code = 400
            data = {}
        return HttpResponse(
            content=json.dumps({"message": message, "data": data}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

    def delete(self, request, aid):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            if not request_user or not request_user.is_operator:
                raise ValueError('还没登录或不能进行这项操作!')
            advertisement = Advertisement.objects.get(id=int(aid))
            # 删除图片
            image_path = settings.MEDIA_ROOT + advertisement.image.name
            os.remove(image_path)
            if advertisement.file:  # 删除原文件
                file_path = settings.MEDIA_ROOT + advertisement.file.name
                os.remove(file_path)
            advertisement.delete()
            status_code = 200
            message = '删除广告成功!'
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": {}}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 使用图片名称找到广告
class AdvertiseWithNameView(View):
    def get(self, request, name):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        if not client:
            return HttpResponse(
                content=json.dumps({"message": 'INVALID CLIENT!', "data": {}}),
                content_type="application/json; charset=utf-8",
                status=400
            )
        image = 'home/advertisement/image/' + name
        # print(image)
        try:
            ad = Advertisement.objects.get(image=image)
            print(ad)
            serializer = AdvertisementSerializer(instance=ad)
            message = '获取数据成功!'
            status_code = 200
            data = serializer.data
        except Advertisement.DoesNotExist:
            message = '不存在当前数据!'
            status_code = 400
            data = {}
        return HttpResponse(
            content=json.dumps({"message": message, "data": data}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 数据分类视图
class DataCategoryView(View):
    def get(self, request, group):
        machine_code = request.GET.get('mc')
        client = get_client(machine_code)
        if not client or group not in [couple[0] for couple in DataCategory.GROUPS] + ['all']:
            categories = DataCategory.objects.none()
        else:
            categories = DataCategory.objects.all()
            if group != 'all':
                categories = categories.filter(group=group)
            else:
                categories.query.group_by = ['group']
        serializer = DataCategorySerializer(instance=categories, many=True)
        return HttpResponse(
            content=json.dumps({"message": '获取分类成功!', "data": serializer.data}),
            content_type="application/json; charset=utf-8",
            status=200
        )

    def post(self, request, group):
        machine_code = request.GET.get('mc')
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            # 验证group
            if group not in [couple[0] for couple in DataCategory.GROUPS]:
                raise ValueError('错误的请求.')
            if not request_user or not request_user.is_operator:
                raise ValueError('登录已过期或您还不能进行这个操作!')
            body_data = json.loads(request.body)
            name = body_data.get('name', None)
            if not name:
                raise ValueError('请输入正确的分组名称!')
            # 创建分组
            category = DataCategory(
                name=name,
                group=group
            )
            category.save()
            message = '创建分类成功!'
            status_code = 201
        except Exception as e:
            message = str(e)
            status_code = 400

        return HttpResponse(
            content=json.dumps({"message": message, "data": {}}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 常规报告视图
class NormalReportView(View):
    def get(self, request):
        machine_code = request.GET.get('mc')
        client = get_client(machine_code)
        try:
            if not client:
                raise ValueError('INVALID CLIENT!')
            body_data = json.loads(request.body)
            category = body_data.get('category')
            params = dict()
            if category == 0:  # 获取全部
                pass
            elif category == -1:  # 获取其他
                params['category'] = None
            else:  # 根据分类条件获取
                params['category_id'] = category
            # 查询
            variety = int(body_data.get('variety'))
            current_page = request.GET.get('page', 1)
            if variety != 0:
                instances = list()
                for report in NormalReport.objects.filter(**params).order_by('-date'):
                    related_vids = [v.id for v in report.varieties.all()]
                    if variety in related_vids:
                        instances.append(report)
                paginator = Paginator(object_list=instances, per_page=50)
                reports = paginator.get_page(current_page)

            else:
                instances = NormalReport.objects.filter(**params).order_by('-date')
                paginator = Paginator(object_list=instances, per_page=50)
                reports = paginator.get_page(current_page)
            serializer = NormalReportSerializer(instance=reports, many=True)
            data = dict()
            data['contacts'] = serializer.data
            data['total_page'] = paginator.num_pages
            message = '获取常规报告成功！'
            status_code = 200
        except Exception as e:
            message = str(e)
            status_code = 400
            data = dict()
            data['contacts'] = []
            data['total_page'] = 1
        return HttpResponse(
            content=json.dumps({'message': message, 'data': data}),
            content_type='application/json; charset=utf-8',
            status=status_code
        )

    def post(self, request):
        # 重新过滤组织数据
        machine_code = request.GET.get('mc', '')
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT.')
            if not request_user or not request_user.is_researcher:
                raise ValueError('未登录或不能进行这个操作!')
            file_name = request.POST.get('name', '')
            if not file_name:
                file_name = request.FILES.name
            date = request.POST.get('date', '')
            if not date:
                raise ValueError('该报告没有设置日期')
            date = datetime.datetime.strptime(date, '%Y-%m-%d')
            cid = int(request.POST.get('category_id', 0))  # 数据分类
            # 关联品种的id列表
            related_vids = eval(request.POST.get('variety_ids', 0))
            if not related_vids:
                raise ValueError('请选择所属品种!')
            for vid in related_vids:
                variety_instance = Variety.objects.get(id=vid)
                # 验证用户品种权限
                if not variety_user_accessed(variety=variety_instance, user=request_user):
                    raise ValueError('您还没这个品种权限.')
            # 组织好数据
            data_to_save = {
                'name': file_name,
                'date': date,
                'uploader': request_user.id,
                'category': cid if cid else None,
                'varieties': related_vids
            }
            form = NormalReportForm(data_to_save, request.FILES)
            if form.is_valid():
                form.save()
                message = '上传成功!'
                status_code = 201
            else:
                raise ValueError(form.errors)
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({'message': message, 'data': {}}),
            content_type='application/json; charset=utf-8',
            status=status_code
        )

# 单个常规报告视图
class NormalReportRetrieveView(View):
    def delete(self, request, rid):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            if not request_user or not request_user.is_operator:
                raise ValueError('还没登录或不能进行这项操作!')
            report = NormalReport.objects.get(id=int(rid))
            # 删除文件
            file_path = settings.MEDIA_ROOT + report.file.name
            os.remove(file_path)
            report.delete()
            status_code = 200
            message = '删除报告成功!'
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": {}}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 交易通知视图
class TransactionNoticeView(View):
    def get(self, request):
        machine_code = request.GET.get('mc')
        client = get_client(machine_code)
        try:
            if not client:
                raise ValueError('INVALID CLIENT!')
            body_data = json.loads(request.body)
            category = int(body_data.get('category_id'))
            params = dict()
            if category == 0:
                pass
            elif category == -1:
                params['category'] = None
            else:
                params['category_id'] = category
            # 查询
            notices = TransactionNotice.objects.filter(**params).order_by('-create_time')
            # 分页
            current_page = request.GET.get('page', 1)
            paginator = Paginator(object_list=notices, per_page=50)
            notice_list = paginator.get_page(current_page)
            serializer = TransactionNoticeSerializer(instance=notice_list, many=True)
            data = dict()
            data['contacts'] = serializer.data
            data['total_page'] = paginator.num_pages
            message = '获取交易通知成功!'
            status_code = 200
        except Exception as e:
            message = str(e)
            status_code = 400
            data = dict()
            data['contacts'] = []
            data['total_page'] = 1
        return HttpResponse(
            content=json.dumps({'message': message, 'data': data}),
            content_type='application/json; charset=utf-8',
            status=status_code
        )

    def post(self, request):
        # 重新过滤组织数据
        machine_code = request.GET.get('mc', '')
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT.')
            if not request_user or not request_user.is_collector:
                raise ValueError('未登录或不能进行这个操作!')
            file_name = request.POST.get('name', '')
            if not file_name:
                file_name = request.FILES.name
            date = request.POST.get('date', '')
            if not date:
                raise ValueError('该通知没有设置日期')
            date = datetime.datetime.strptime(date, '%Y-%m-%d')
            cid = int(request.POST.get('category_id', 0))  # 数据分类
            # 组织好数据
            data_to_save = {
                'name': file_name,
                'date': date,
                'uploader': request_user.id,
                'category': cid if cid else None,
            }
            form = TransactionNoticeForm(data_to_save, request.FILES)
            if form.is_valid():
                form.save()
                message = '上传成功!'
                status_code = 201
            else:
                raise ValueError(form.errors)
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({'message': message, 'data': {}}),
            content_type='application/json; charset=utf-8',
            status=status_code
        )

# 单个交易通知视图
class TransactionNoticeRetrieveView(View):
    def delete(self, request, nid):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            if not request_user or not request_user.is_operator:
                raise ValueError('还没登录或不能进行这项操作!')
            notice = TransactionNotice.objects.get(id=int(nid))
            # 删除文件
            file_path = settings.MEDIA_ROOT + notice.file.name
            os.remove(file_path)
            notice.delete()
            status_code = 200
            message = '删除通知成功!'
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": {}}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 现货报表视图
class SpotCommodityView(View):
    def get(self, request):
        machine_code = request.GET.get('mc', None)
        date = request.GET.get('date', None)
        client = get_client(machine_code)
        if not all([client, date]):
            spot_objs = SpotCommodity.objects.none()
        else:
            spot_objs = SpotCommodity.objects.filter(date=date)
        serializer = SpotCommoditySerializer(instance=spot_objs, many=True)

        return HttpResponse(
            content=json.dumps({"message": '获取现货报表成功!', "data": serializer.data}),
            content_type="application/json; charset=utf-8",
            status=200
        )

    def post(self, request):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            print(request_user.is_collector)
            if not request_user or not request_user.is_collector:
                raise ValueError('未登录或不能进行这项操作！')
            body_data = json.loads(request.body)
            commodity_list = body_data.get('commodity_list', None)
            if not commodity_list:
                raise ValueError('还没有上传任何数据.')
            instance_list = list()
            for item in commodity_list:
                item['date'] = datetime.datetime.strptime(item['date'], '%Y-%m-%d')
                item['uploader_id'] = request_user.id  # 加入上传者
                instance = SpotCommodity(**item)
                instance_list.append(instance)
            SpotCommodity.objects.bulk_create(instance_list)
            message = "上传成功!"
            status_code = 201
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": []}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 单条报表记录视图
class SpotCommodityRetrieveView(View):
    def delete(self, request, sid):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            if not request_user or not request_user.is_operator:
                raise ValueError('还没登录或不能进行这项操作!')
            spot_commodity = SpotCommodity.objects.get(id=int(sid))
            spot_commodity.delete()
            status_code = 200
            message = '删除记录成功!'
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": {}}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 财经日历视图
class FinanceCalendarView(View):
    def get(self, request):
        machine_code = request.GET.get('mc', None)
        date = request.GET.get('date', None)
        client = get_client(machine_code)
        if not all([client, date]):
            finance_objs = FinanceCalendar.objects.none()
        else:
            finance_objs = FinanceCalendar.objects.filter(date=date).order_by('date','time')
        serializer = FinanceCalendarSerializer(instance=finance_objs, many=True)

        return HttpResponse(
            content=json.dumps({"message": '获取财经日历成功!', "data": serializer.data}),
            content_type="application/json; charset=utf-8",
            status=200
        )

    def post(self, request):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            if not request_user or not request_user.is_collector:
                raise ValueError('未登录或不能进行这项操作！')
            body_data = json.loads(request.body)
            finance_list = body_data.get('finance_list', None)
            if not finance_list:
                raise ValueError('还没有上传任何数据.')
            instance_list = list()
            for item in finance_list:
                item['date'] = datetime.datetime.strptime(item['date'], '%Y-%m-%d')
                item['time'] = datetime.datetime.strptime(item['time'], '%H:%M:%S')
                item['uploader_id'] = request_user.id  # 加入上传者
                instance = FinanceCalendar(**item)
                instance_list.append(instance)
            FinanceCalendar.objects.bulk_create(instance_list)
            message = "上传成功!"
            status_code = 201
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": []}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )

# 单条财经日历视图
class FinanceCalendarRetrieveView(View):
    def delete(self, request, fid):
        machine_code = request.GET.get('mc', None)
        client = get_client(machine_code)
        request_user = request.user
        try:
            if not client or not client.is_manager:
                raise ValueError('INVALID CLIENT!')
            if not request_user or not request_user.is_operator:
                raise ValueError('还没登录或不能进行这项操作!')
            finance_calendar = FinanceCalendar.objects.get(id=int(fid))
            finance_calendar.delete()
            status_code = 200
            message = '删除日历事件成功!'
        except Exception as e:
            message = str(e)
            status_code = 400
        return HttpResponse(
            content=json.dumps({"message": message, "data": {}}),
            content_type="application/json; charset=utf-8",
            status=status_code
        )


from time import localtime as ltime
from time import strftime as ftime

class TimeProvider(object):
    hour = property(lambda self: ltime().tm_hour)
    minute = property(lambda self: ltime().tm_min)
    period = property(lambda self: ftime("%p", ltime()))

class TimeDisplay(object):
    def __init__(self, provider=None):
        if not provider:
            provider = TimeProvider()
        self._provider = provider

    def get_time_as_html(self):
        p = self._provider
        ret = ""
        if p.hour == 0 and p.minute <= 1:
            ret += "Midnight"
        elif p.hour == 12 and p.minute <= 1:
            ret += "Noon"
        else:
            ret += "%02d:%02d %s" % (p.hour, p.minute, p.period)
        return ret + ""

import mocker
class DisplayTest(mocker.MockerTestCase):
    def _get_mock(self, h, m, p="AM"):
        mock = self.mocker.mock()

        mock.hour   # access hour
        self.mocker.count(0, 3); self.mocker.result(h)
        mock.minute # access minute
        self.mocker.count(0, 3); self.mocker.result(m)
        mock.period # access period
        self.mocker.count(0, 3); self.mocker.result(p)

        self.mocker.replay()
        return mock

    def tearDown(self):
        self.mocker.verify()

    def test_display_current_time_at_midnight(self):
        sut = TimeDisplay(self._get_mock(0,0))
        self.assertEquals('Midnight',
                            sut.get_time_as_html())

    def test_display_current_time_at_noon(self):
        sut = TimeDisplay(self._get_mock(12,0))
        self.assertEquals('Noon',
                            sut.get_time_as_html())

    def test_display_current_time_whenever(self):
        sut = TimeDisplay(self._get_mock(2,2))
        self.assertEquals('02:02 AM',
                            sut.get_time_as_html())


# Updated from pyscriptv4-1.py:
#     (1) added encoding so that user can still type in non-ENG characters under editURL()
#     (2) when stopwatch is running, a text 'tictoc' will blink to indicate function is on
#     (3) Help menu has been revised by adding a. Show Information b. Show Instruction c. Show Full Code

#1. Libraries
from pathlib import Path
from tkinter import messagebox, Menu
import datetime
import os
import subprocess
import tempfile
import threading
import time
import tkinter as tk
import webbrowser

#2. Functions
## Variables
alarm_thread = None
sum_min_list = []
sum_sec_list = []

## Function to define subwindow's attributes
def sub_window(sub_window_title):
    global sub_window_global
    sub_window_global = tk.Toplevel(root)
    sub_window_global.title(sub_window_title)

    main_x = root.winfo_x()
    main_y = root.winfo_y()

    sub_window_x = main_x + 195
    sub_window_y = main_y
    sub_window_global.geometry("+{}+{}".format(sub_window_x, sub_window_y))

## Function to alert before closing the app (purpose: avoid accidental closure)
def on_closing():
    if messagebox.askokcancel("Quit", "Are you sure you want to quit?"):
        global running
        running = False
        root.destroy()

## Function for "Calculate Lunch" button(purpose: calculate)
def lunch_cal(entry_lstart, entry_lend, l_result_label):
    try:
        lstime_str = entry_lstart.get()
        s_hour, s_minute = map(int, lstime_str.split(":"))
        #allow user to type 1:15 instead of 13:15
        if s_hour < 7:
            s_hour +=12

        letime_str = entry_lend.get()
        e_hour, e_minute = map(int, letime_str.split(":"))
        #allow user to type 1:15 instead of 13:15
        if e_hour < 7:
            e_hour +=12

        l_total_minute = (e_hour*60 + e_minute)- (s_hour*60 + s_minute)
        l_result_label.config(text=f" Total {l_total_minute:02d} Minutes")

        entry2.delete(0, tk.END)
        entry2.insert(0, str(l_total_minute))
    except ValueError:
        messagebox.showinfo("Alert", "[ERROR] Enter Time Correctly!")

## Function for "Calculate Lunch" button(purpose: show window)
def lunch_submit():
    global sub_window_global
    sub_window("Calculate Lunch")
    sub_window_global.geometry("180x150")

    label_lstart = tk.Label(sub_window_global, text="Started (HH:MM)")
    label_lstart.pack()

    entry_lstart = tk.Entry(sub_window_global)
    entry_lstart.pack()

    label_lend = tk.Label(sub_window_global, text="Finished (HH:MM)")
    label_lend.pack()

    entry_lend = tk.Entry(sub_window_global)
    entry_lend.pack()

    lunch_gl_label = tk.Label(sub_window_global, text="Hit Enter to Calculate Time", fg="gray")
    lunch_gl_label.pack()

    l_result_label = tk.Label(sub_window_global, text="", fg="#009900")
    l_result_label.pack()
    entry_lend.bind("<Return>", lambda event: lunch_cal(entry_lstart, entry_lend, l_result_label))

## Function for "Set Alarm" button(purpose: calculate)
def punch_calculator():
    try:
        time_str = entry1.get()
        hour, minute = map(int, time_str.split(":"))
        lunch_minute = int(entry2.get())
        total_minute = hour*60 + minute + 8*60+ lunch_minute
        hour = total_minute // 60
        minute = total_minute % 60
        result_label.config(text=f"Record Out at {hour:02d}:{minute:02d}")
        messagebox.showinfo("Confirmation", "Alarm set!")
    except ValueError:
        messagebox.showinfo("Alert", "[ERROR] Enter Time Correctly!")
        return

## Function for "Set Alarm" button(purpose: validate entries)
def set_alarm():
    global alarm_thread

    if entry1.get() == "" or entry2.get() == "":
        messagebox.showinfo("Alert", "[ERROR] Missing Time!")
        return
    else:
        if alarm_thread and alarm_thread.is_alive():
            global running
            running = False
            alarm_thread.join()
            punch_calculator()
        else:
            punch_calculator()

    set_time = result_label["text"][13:]
    alarm_thread = threading.Thread(target=check_current_time, args=(set_time,))
    alarm_thread.start()

## Function for "Set Alarm" button(purpose: ring alarm)
def check_current_time(set_time):
    global running  #to prevent from running even after closure
    running = True
    while running:
        now = datetime.datetime.now()
        current_time = f"{now.hour:02d}:{now.minute:02d}"
        if current_time == set_time:
            cmd = """
                   do shell script "afplay /System/Library/Sounds/Funk.aiff"
                   display dialog ¬
                   "Time to Go Home!"
                        """
            result = subprocess.run(['osascript', '-e', cmd], capture_output=True)
            os.system("open -a 'Time'")

            entry1.delete(0, tk.END)
            entry2.delete(0, tk.END)
            result_label.config(text="")

            return result.stdout
            break
        time.sleep(1)

## Function to alert before closing stopwatch
def close_window(sub_window_global):
    result = messagebox.askquestion("Confirmation", "Are you sure you want to close?")
    if result == "yes":
        sub_window_global.destroy()

# Function for "Stopwatch" button
def stopwatch():
    global sub_window_global
    sub_window("Stopwatch")

    sst1 = ""
    sst2 = ""
    label_row = 2  # Initial row index for label_records

    def stamp_start_time():
        nonlocal sst1
        stamp_start_time = datetime.datetime.now()
        sst1 = stamp_start_time.strftime("%H:%M:%S")
        label_start.config(text=sst1)
        update_indicator()

    def stamp_end_time():
        nonlocal sst2
        stamp_end_time = datetime.datetime.now()
        sst2 = stamp_end_time.strftime("%H:%M:%S")

        try:
            if label_start.cget("text") != "":
                nonlocal label_row  # Access the label_row variable from the outer scope
                sst1_h, sst1_m, sst1_s = map(int, sst1.split(":"))
                sst2_h, sst2_m, sst2_s = map(int, sst2.split(":"))

                if sst2_s > sst1_s:
                    time_diff_s = sst2_s - sst1_s
                    records_m = (sst2_h * 60 + sst2_m) - (sst1_h * 60 + sst1_m)
                else:
                    time_diff_s = sst2_s + 60 - sst1_s
                    records_m = (sst2_h * 60 + sst2_m - 1) - (sst1_h * 60 + sst1_m)

                label_records = tk.Label(sub_window_global, text=f"{sst1} - {sst2} Total {records_m} minutes {time_diff_s} seconds")
                label_records.grid(row=label_row, column=0, columnspan=4)

                label_row += 1  # Increment the row index for the next label_records

                sum_min_list.append(records_m)
                sum_sec_list.append(time_diff_s)

                label_start.config(text="")
                update_indicator()

        except Exception as e:
            pass

    def sumup():
        initial_min_stopwatch = sum(sum_min_list)
        additional_min_stopwatch = sum(sum_sec_list) // 60
        total_min_stopwatch = initial_min_stopwatch + additional_min_stopwatch
        total_sec_stopwatch = sum(sum_sec_list) % 60

        label_total_time = tk.Label(
            sub_window_global,
            text=f"Total {total_min_stopwatch} minutes {total_sec_stopwatch} seconds",
            fg="#009900"
        )
        label_total_time.grid(row=label_row, column=0, columnspan=4)

    def reset_start_button():
        label_start.config(text="")
        indicator_label.config(text="")

    def update_indicator():
        indicator_text = "tic" + "toc" * (int(time.time()) % 2 == 0)
        indicator_label.config(text=indicator_text)
        if label_start.cget("text") == "":
            indicator_label.config(text="")
        else:
            sub_window_global.after(1000, update_indicator)

    stopwatch_start_button = tk.Button(sub_window_global, text="Start", command=stamp_start_time)
    stopwatch_start_button.grid(row=0, column=0)

    stopwatch_end_button = tk.Button(sub_window_global, text="End", command=stamp_end_time)
    stopwatch_end_button.grid(row=0, column=1)

    sumup_button = tk.Button(sub_window_global, text="Sum Up", command=sumup)
    sumup_button.grid(row=0, column=2)

    stopwatch_reset_button = tk.Button(sub_window_global, text="Reset", command=reset_start_button)
    stopwatch_reset_button.grid(row=0, column=3)

    label_start = tk.Label(sub_window_global, text=sst1, fg="#009900")
    label_start.grid(row=1, column=0)

    indicator_label = tk.Label(sub_window_global, text="", fg="#009900")
    indicator_label.grid(row=1, column=1)

    sub_window_global.protocol("WM_DELETE_WINDOW", lambda: close_window(sub_window_global))
    sub_window_global.mainloop()

## Function for "Open URL" button
def openURL():
    file_path = get_file_path()
    if not os.path.exists(file_path):
        with open(file_path, "w", encoding="utf-8") as f:
            f.write("https://google.com\n")

    with open(file_path, "r", encoding="utf-8") as f:
        urls = f.read().splitlines()

    for url in urls:
        if not url.startswith("https://") and url:
            full_url="https://" + url
        else:
            full_url = url

        webbrowser.open_new_tab(full_url)

def editURL():
    global sub_window_global
    sub_window("Edit URL")

    lab_url1 = tk.Label(sub_window_global, text="Your URL(s)")
    lab_url1.pack()

    file_path = get_file_path()
    if not os.path.exists(file_path):
        with open(file_path, "w", encoding="utf-8") as f:
            f.write("https://google.com\n")

    with open(file_path, "r", encoding="utf-8") as f:
        urls = f.read().splitlines()

    num_entries = len(urls)
    entries = []

    for i in range(num_entries):
        entry = tk.Entry(sub_window_global)
        entry.insert(0, urls[i])
        entry.pack()
        entries.append(entry)

    def create_new_field():
        new_entry = tk.Entry(sub_window_global)
        new_entry.pack()
        entries.append(new_entry)
        add_button.pack(side=tk.BOTTOM)

    def save_urls():
        urls = [entry.get() for entry in entries]
        with open(file_path, "w", encoding="utf-8") as f:
            for url in urls:
                f.write(url + "\n")
        sub_window_global.destroy()

    add_button = tk.Button(sub_window_global, text="Add", command=create_new_field)
    add_button.pack(side=tk.BOTTOM)

    sub_window_global.protocol("WM_DELETE_WINDOW", save_urls)

def get_file_path():
    home_dir = str(Path.home())
    file_path = os.path.join(home_dir, "url_list.txt")
    return file_path

#3. Main Window
root = tk.Tk()
root.protocol("WM_DELETE_WINDOW", on_closing)
root.title("Ops Helper")

#4. Labels and Entries
label1 = tk.Label(root, text="Start Time (HH:MM)")
label1.pack()

entry1 = tk.Entry(root)
entry1.pack()

label2 = tk.Label(root, text="Lunch Time (MM)")
label2.pack()

entry2 = tk.Entry(root)
entry2.pack()

entry2.bind("<Return>", lambda event: set_alarm())

result_label = tk.Label(root, text="", fg="#009900")
result_label.pack()

#5. Buttons
button_lcal = tk.Button(root, width=10, text="Calculate Lunch", command=lunch_submit)
button_lcal.pack()

button1 = tk.Button(root, width=10, text="Set Alarm", command=set_alarm)
button1.pack()

button3 = tk.Button(root, width=10, text="Stopwatch", command=stopwatch)
button3.pack()

button2 = tk.Button(root, width=10, text="Open URL", command=openURL)
button2.pack()

button2_edit = tk.Button(root, width=10, text="Edit URL", command=editURL)
button2_edit.pack()

version_label = tk.Label(root, text="Sylvia-GUI-prj-June2023", fg="gray")
version_label.pack()

#6. Help Menu
def show_help():
    help_text = """
    Added app information here
    """

    help_window = tk.Toplevel(root)
    help_window.title("Help")

    help_label = tk.Label(help_window, text=help_text, padx=10, pady=10, justify='left')
    help_label.pack()

def show_instruction():
    help_text = """
    Added instruction here
    """

    help_window = tk.Toplevel(root)
    help_window.title("Help")

    help_label = tk.Label(help_window, text=help_text, padx=10, pady=10, justify='left')
    help_label.pack()

def show_fullcode():
    help_text = """
    Added full code here
    """

    help_window = tk.Toplevel(root)
    help_window.title("Help")

    # Create a scrollable text area
    scroll_text = tk.Text(help_window, padx=10, pady=10, wrap="word")
    scroll_text.insert("1.0", help_text)
    scroll_text.pack(side="left", fill="both", expand=True)

    # Add a scrollbar to the text area
    scrollbar = tk.Scrollbar(help_window, command=scroll_text.yview)
    scrollbar.pack(side="right", fill="y")
    scroll_text.config(yscrollcommand=scrollbar.set)

menu_bar = Menu(root)
root.config(menu=menu_bar)

help_menu = Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Help", menu=help_menu)

help_menu.add_command(label="Show Information", command=show_help)
help_menu.add_command(label="Show Instruction", command=show_instruction)
help_menu.add_command(label="Show Full Code", command=show_fullcode)

root.mainloop()


from django.db import models
from doctor.models.customer import Customer

class Register(models.Model):
    doctor = models.CharField(max_length=256, verbose_name='主治医生')
    time = models.DateTimeField(max_length=19, verbose_name='挂号时间')
    price = models.FloatField(default=0.0, verbose_name='价钱')
    customer = models.ForeignKey('Customer', on_delete=models.CASCADE, verbose_name='用户')

    class Meta:
        verbose_name = '挂号信息'
        verbose_name_plural = '挂号信息'

    def __str__(self):
        return str(self.id)


from flask import Flask,request
import numpy as np
import re
import base64
import os
from mnist_model import model
from scipy.misc import imread, imresize,imshow

app = Flask(__name__)
model = model()

@app.route('/', methods=['GET'])
def home():
    return {'message':'home'}

@app.route('/predict/', methods=['POST'])
def predict():
    img = request.files['image']
    img.save(os.path.join('./', 'output.png'))

    x = imread('output.png', mode='L')
    x = np.invert(x)
    x = imresize(x,(28,28))
    x = x.reshape(1,28,28,1)

    out = model.predict(x)
    response = np.array_str(np.argmax(out, axis=1))

    return {'response':response}

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)


#!/usr/bin/env python
import socket
import time

MY_IFACE = ''
TCP_PORT = 5005
BUFFER_SIZE = 20

sockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sockfd.bind((MY_IFACE, TCP_PORT))

sockfd.listen(5)

newfd, addr = sockfd.accept()
print('Connection address:', addr)

data = newfd.recv(BUFFER_SIZE)
print("received data:", data.decode())

newfd.send(data.upper())  # echo

newfd.close()
sockfd.close()


import sys
import re

filename = "kind2_models/Mode_Logic"
num_props = 118

for i in range(1, num_props+1):
  f = open(filename + ".lus", "r")
  f_new = open(filename + "__" + str(i) + ".lus", "w")
  j = 0
  for line in f:
    if "--%PROPERTY" in line.strip():
      j += 1
      if j == i:
        f_new.write(line)
      else:
        continue
    else:
      f_new.write(line)


import os
import uuid
import telebot, json, requests, librosa, librosa.display

import torch
from transformers import Speech2TextProcessor, Speech2TextForConditionalGeneration
from datasets import load_dataset
import soundfile as sf

token = 'FILL IT'
bot = telebot.TeleBot(token)

model = Speech2TextForConditionalGeneration.from_pretrained("facebook/s2t-small-mustc-en-ru-st")
processor = Speech2TextProcessor.from_pretrained("facebook/s2t-small-mustc-en-ru-st")

def query(filename):
    API_TOKEN = 'FILL IT'
    API_URL = "https://api-inference.huggingface.co/models/facebook/s2t-small-mustc-en-ru-st"
    headers = {"Authorization": f"Bearer {API_TOKEN}"}
    with open(filename, "rb") as f:
        data = f.read()
    response = requests.request("POST", API_URL, headers=headers, data=data)
    return json.loads(response.content.decode("utf-8"))

@bot.message_handler(commands=['start'])
def start_message(message):
    bot.send_message(message.chat.id, 'Скажите текст на английском')

@bot.message_handler(content_types=['voice'])
def send_text(message):
    action_function(message)

def action_function(message):
    filename = str(uuid.uuid4())
    file_name_full="./voice/"+filename+".ogg"
    file_name_full_converted="./ready/"+filename+".wav"
    file_info = bot.get_file(message.voice.file_id)
    downloaded_file = bot.download_file(file_info.file_path)
    with open(file_name_full, 'wb') as new_file:
        new_file.write(downloaded_file)
    os.system("ffmpeg -i "+file_name_full+"  "+file_name_full_converted)
    output = query(file_name_full_converted)
    i = list(output.values())
    print(i)
    bot.reply_to(message, i)
    os.remove(file_name_full)
    os.remove(file_name_full_converted)

import time
if __name__=='__main__':
    while True:
        try:
            bot.polling(non_stop=True, interval=0)
        except Exception as e:
            print(e)
            time.sleep(5)
            continue


import random
trouve = 0
echange = 0

num=int(input("un nombre entre 5 et 10"))

tableau = num * [0]

for i in range (len(tableau)):
    tableau[i]=random.randint(0,num*5)
    trouve = tableau [i]
    tempo = -1
    while (tempo<i-1) :
        tempo += 1
        if ( tableau [tempo] == trouve ) :
            tableau[i]=random.randint(0,num*5)
            trouve = tableau [i]
            tempo = -1
        if (tableau [tempo] > trouve) :
            echange = tableau[tempo]
            tableau [tempo] = tableau [i]
            tableau [i] = echange

print (tableau)


from tkinter import Tk, Canvas, Frame, BOTH, filedialog
import tkinter as tk
import HeaderReading as FITS
root = Tk()  # pointing root to Tk() to use it as Tk() in program.
root.withdraw()  # Hides small tkinter window.

def open_folder():
    """
    :return foldername:
    """
    foldername = filedialog.askdirectory(title="Select Folder To Scan")
    if not foldername:
        print("No Folder Selected")
        return 0
    FITS.Directory = foldername
    return foldername

def on_closing():
    window.destroy()
    root.destroy()

def on_list_creation():
    if FITS.Output:
        for record in FITS.Output:
            txt_edit.insert('end', str(record[0]))
            txt_edit.insert('end', '\n')
            for subrecord in record[1]:
                txt_edit.insert('end', '+ ')
                txt_edit.insert('end', str(subrecord[0]))
                txt_edit.insert('end', ' , ')
                txt_edit.insert('end', str(round(subrecord[1], 3)))
                txt_edit.insert('end', '\n')
            txt_edit.insert('end', '\n')

            #txt_edit.insert('end', str.join(str(record[0]), '\n'))
            #txt_edit.insert('end', str.join(str(record[1:]), '\n'))

window = tk.Tk()
window.title("Simple Text Editor")

window.rowconfigure(0, minsize=480, weight=1)
window.columnconfigure(1, minsize=480, weight=1)

txt_edit = tk.Text(window)
frm_buttons = tk.Frame(window, relief=tk.RAISED, bd=2)
btn_open = tk.Button(frm_buttons, text="Open", command=open_folder)
btn_save = tk.Button(frm_buttons, text="Process", command=FITS.make_overlap_list)
btn_update = tk.Button(frm_buttons, text="Update", command=on_list_creation)

btn_open.grid(row=0, column=0, sticky="ew", padx=5, pady=5)
btn_save.grid(row=1, column=0, sticky="ew", padx=5)
btn_update.grid(row=2, column=0, sticky="ew", padx=5)

frm_buttons.grid(row=0, column=0, sticky="ns")
txt_edit.grid(row=0, column=1, sticky="nsew")

canvas = Canvas(txt_edit,width=400,height=400,background='white')
canvas.grid(row=0,column=0)
#canvas.create_line(100,100,300,100,200,300,100,100,fill='blue',width=4)

window.protocol("WM_DELETE_WINDOW", on_closing)
window.mainloop()


from cap6635.environment.map import Map2D
from cap6635.utilities.plot import MazeAnimator
from cap6635.utilities.constants import (
    MOVE_UP, MOVE_DOWN, MOVE_LEFT, MOVE_RIGHT
)
import math
import matplotlib.pyplot as plt
import numpy as np
import os
import sys

from agents import MazeRunner

get_action = {MOVE_UP: '^', MOVE_DOWN: 'v', MOVE_LEFT: '<', MOVE_RIGHT: '>'}
hw1_usage = (
    'Usage:\n'
    'python3 hw1_dynamic_programming.py <elements_in_row> <algorithm>\n'
    '     <deterministic(y/n)> <simulation(y/n)> [starting_state]\n\n'
    'algorithms to choose from:\n'
    '(v) Value Iteration\n'
    '(p) Policy Iteration\n'
    '(e) Policy Evaluation\n')
hw2_usage = (
    'Usage:\n'
    'python3 hw2_sarsa.py <elements_in_row> <algorithm>\n'
    '     <deterministic(y/n)> <simulation(y/n)> [starting_state]\n\n'
    'algorithms to choose from:\n'
    '(q) Q-Learning\n'
    '(s) SARSA\n'
    'NOTE: deterministic is the only supported option.')

def pretty_policy(P, elements_in_row, E, B, text):
    policy = Map2D(elements_in_row + 2, elements_in_row + 2)
    for i, s in enumerate(P):
        action = np.where(s == 1)[0][0]
        y = (i % elements_in_row) + 1
        x = (math.floor(i / elements_in_row)) + 1
        if i in E:
            plt.text(y, x, "x", color='green')
        elif i in B:
            plt.text(y, x, "o", color='green')
        else:
            plt.text(y, x, get_action[action], color='green')
        plt.imshow(policy.map, 'pink')
    plt.savefig('policy_%s.png' % (text))
    plt.clf()

def gather_inputs(usage):
    # States: size of your Grid (|column| * |row|)
    try:
        elements_in_row = int(sys.argv[1])
    except ValueError:
        elements_in_row = 10
    except IndexError:
        elements_in_row = 10

    try:
        algo = sys.argv[2]
    except IndexError:
        algo = 'v'
    try:
        if sys.argv[3] == 'n':
            deterministic = False
        else:
            deterministic = True
    except BaseException:
        print(usage)
        sys.exit(1)

    try:
        if sys.argv[4] == 'n':
            gui = False
        else:
            gui = True
            try:
                start_pos = int(sys.argv[5])
            except ValueError:
                start_pos = 0
    except BaseException:
        print(usage)
        sys.exit(1)

    return elements_in_row, algo, deterministic, gui, start_pos

def animate(start_pos, E, B, elements_in_row, algo, P, maze_name):
    maze = Map2D(elements_in_row + 2, elements_in_row + 2)
    for e in E:
        maze.map[
            (math.floor(e / elements_in_row)) + 1][
            (e % elements_in_row) + 1
            ] = 20
    for b in B:
        maze.map[
            (math.floor(b / elements_in_row)) + 1][
            (b % elements_in_row) + 1
            ] = 5

    sx = math.floor(start_pos / elements_in_row) + 1
    sy = math.floor(start_pos % elements_in_row) + 1
    a = MazeRunner(maze, P, state=start_pos, start=(sx, sy),
                   elements_in_row=elements_in_row)
    i = 0
    animator = MazeAnimator(os.getcwd(), maze_name)
    animator.temp = '/temp/'
    animator.save_state(i, maze, a)
    while a.state not in E:
        # Starting position
        a.move()
        maze.map[a._x_path[0], a._y_path[0]] = 30
        maze.map[a._x_path[-1], a._y_path[-1]] = 10
        maze.map[a._x_path[-2], a._y_path[-2]] = 0
        animator.save_state(i, maze, a)
        i += 1

    animator.make_gif()
    del animator.temp


import argparse
import numpy as np
import cv2, os, time
from meta import sample_filepath
import matplotlib
matplotlib.use('agg') # fix pyplot hangs in wsl2 https://github.com/matplotlib/matplotlib/issues/22385
import matplotlib.pyplot as plt
from IPython.display import clear_output

path = "/mnt/i/dataset-processed"
filepaths = os.listdir(path)
filepaths = [os.path.join(path, f) for f in filepaths if f.split(".")[-1].lower() in ["jpeg","jpg","png"]]
print(f"Found {len(filepaths)} images from {path}")

sample_indices = []
for idf, f in enumerate(filepaths):
    for i in range(len(sample_filepath)):
        if sample_filepath[i] == f.split("/")[-1]:
            sample_indices.append(idf)

W = np.load("./MU_L30/weights/matrix_W.npy")
H = np.load("./MU_L30/weights/matrix_H.npy")

X_reconst = np.matmul(W, H)

# generate plots
fig, axes = plt.subplots(3,10, figsize=(20, 6))
axes = axes.ravel()
for i in range(len(axes)):
    axes[i].imshow(W[:,i].reshape((112,112)), cmap='gray')
    axes[i].axis('off')
plt.subplots_adjust(wspace=0.1, hspace=0)
fig.tight_layout()
fig.savefig("./NMF_components.png")

fig, axes = plt.subplots(5,10, figsize=(20,10))
axes = axes.ravel()
for i in range(len(axes)):
    axes[i].imshow(X_reconst[:,sample_indices[i]].reshape((112,112)), cmap="gray")
    axes[i].axis('off')
plt.subplots_adjust(wspace=0, hspace=0)
fig.tight_layout()
fig.savefig("./Sample_reconstruction.png")


# Ampel Projekt
# Ich habe "Enum-Klasse" in dieser Datei für das Ampelprojekt verwendet.

from enum import Enum, auto # Die Auto-Funktion vergibt die Nummerierung selbst.Aber hier werde ich die Zahlen selbst einstellen
import time

class Ampel(Enum):
    ROT = 10 # Damit das rote Licht 10 Sekunden lang aufleuchtet
    GELB = 1 # Damit das gelbe Licht 1 Sekunden lang aufleuchtet
    GRUN = 15 #Damit das grüne Licht 15 Sekunden lang aufleuchtet

while True:
    for farben in Ampel:
        if farben == Ampel.ROT:
            print(farben.name)
            time.sleep(farben.value)
        elif farben == Ampel.GELB:
            print(farben.name)
            time.sleep(farben.value)
        elif farben == Ampel.GRUN:
            print(farben.name)
            time.sleep(farben.value)


import re
from flask import Flask, jsonify, request, send_file
import nltk
from flask import request
from flasgger import Swagger, LazyString, LazyJSONEncoder
from flasgger import swag_from
import csv
import pandas as pd
import io
import os

app = Flask(__name__)

with open('src/new_kamusalay.csv', encoding = 'latin-1', mode='r') as infile:
    reader = csv.reader(infile)
    ids = {rows[0]:rows[1] for rows in reader}

app.json_encoder = LazyJSONEncoder
swagger_template = dict(
    info = {
        'title' : LazyString(lambda: 'API Documentation for Cleaning Text'),
        'version' : LazyString(lambda: '1.0.0'),
        'description' : LazyString(lambda: 'Dokumentasi API untuk kebutuhan Cleaning Text'),
    },
    host = LazyString(lambda: request.host)
    )

swagger_config = {
    'headers': [],
    'specs':[
        {
            'endpoint': 'docs',
            'route': '/docs.json',
        }
        ],
    'static_url_path': '/flasgger_static',
    'swagger_ui': True,
    'specs_route': '/docs'
}

swagger = Swagger(app, template=swagger_template, config=swagger_config)

def casefolding(review):
    review = review.lower()
    return review

def tokenize(review):
    token = nltk.word_tokenize(review)
    return token

def filtering(review):
    # Remove angka termasuk angka yang berada dalam string
    # Remove non ASCII chars
    review = re.sub(r'[^\x00-\x7f]', r'', review)
    review = re.sub(r'(\\u[0-9A-Fa-f]+)', r'', review)
    review = re.sub(r"[^A-Za-z0-9^,!.\/'+-=]", " ", review)
    review = re.sub(r'\\u\w\w\w\w', '', review)
    # Remove link web
    review = re.sub(r'http\S+', '', review)
    # Remove @username
    review = re.sub('@[^\s]+', '', review)
    # Remove #tagger
    review = re.sub(r'#([^\s]+)', '', review)
    # Remove simbol, angka dan karakter aneh
    review = re.sub(r"[.,:;+!\-_<^/=?\"'\(\)\d\*]", " ", review)
    return review

def replaceThreeOrMore(review):
    # Pattern to look for three or more repetitions of any character, including newlines (contoh goool -> gol).
    pattern = re.compile(r"(.)\1{1,}", re.DOTALL)
    return pattern.sub(r"\1", review)

def convertToSlangword(review):
    kamus_slangword = ids
    pattern = re.compile(r'\b( ' + '|'.join (kamus_slangword.keys())+r')\b') # Search pola kata (contoh kpn -> kapan)
    content = []
    for kata in review:
        filteredSlang = pattern.sub(lambda x: kamus_slangword[x.group()],kata) # Replace slangword berdasarkan pola review yg telah ditentukan
        content.append(filteredSlang.lower())
    review = content
    return review

def filter_text(text):
    content = []
    text_filter = casefolding(text)
    text_filter = filtering(text_filter)
    text_filter = replaceThreeOrMore(text_filter)
    text_filter = tokenize(text_filter)
    text_filter = convertToSlangword(text_filter)
    text_filter = content.append(" ".join(text_filter))
    text_filter_2 = content
    return text_filter_2

@swag_from('docs/text_processing.yml', methods=['POST'])
@app.route('/text-processing', methods=['POST'])
def text_processing():
    text = request.form.get('data_text')
    text = filter_text(text)
    json_response = {
        'status_code': 200,
        'description': "Teks yang sudah di proses",
        'data': text
    }

    response_data = jsonify(json_response)
    return response_data

@swag_from('docs/upload.yml', methods=['POST'])
@app.route('/text-processing_upload', methods=['POST'])
def text_processing_upload():
    if request.method == 'POST':
        file = request.files['file']
        df = pd.read_csv(io.StringIO(file.read().decode('utf-8')))
        datasets = [df]
        for teks in datasets:
            text_awal = teks['Tweet']
            teks = teks['Tweet'].apply(casefolding)
            teks = teks.apply(filtering)
            teks = teks.apply(replaceThreeOrMore)
            teks = teks.apply(tokenize)
            teks = teks.apply(convertToSlangword)
            teks = teks.apply(" ".join)

        review_dict = {'Tweet Awal': text_awal,'Tweet Bersih': teks}
        df = pd.DataFrame(review_dict, columns = ['Tweet Awal','Tweet Bersih'])
        df.to_csv('src/data-bersih.csv', sep= ',' , encoding='utf-8')
        json_response = {
            'status_code': 200,
            'description': "Data CSV berhasil dicleaning",
            'url_download': "http://127.0.0.1:5000/download_csv"
        }
    response_data = jsonify(json_response)
    return response_data

@app.route('/download_csv')
def download_csv():

	path = "./src/data-bersih.csv"
	return send_file(path, as_attachment=True)

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


import os
import math

import numpy as np

import warp as wp
import warp.sim
import warp.sim.render

wp.init()

# params
sim_width = 8
sim_height = 8

sim_fps = 60.0
sim_substeps = 64
sim_duration = 5.0
sim_frames = int(sim_duration*sim_fps)
sim_dt = (1.0/sim_fps)/sim_substeps
sim_time = 0.0
sim_iterations = 1
sim_relaxation = 1.0

device = wp.get_preferred_device()

builder = wp.sim.ModelBuilder()

builder.add_soft_grid(
    pos=(0.0, 0.0, 0.0),
    rot=wp.quat_identity(),
    vel=(0.0, 0.0, 0.0),
    dim_x=20,
    dim_y=10,
    dim_z=10,
    cell_x=0.1,
    cell_y=0.1,
    cell_z=0.1,
    density=100.0,
    k_mu=50000.0,
    k_lambda=20000.0,
    k_damp=0.0)

builder.add_body(origin=wp.transform((0.5, 2.5, 0.5), wp.quat_identity()))
builder.add_shape_sphere(body=0, radius=0.75, density=100.0)

model = builder.finalize(device=device)
model.ground = True
model.soft_contact_distance = 0.01
model.soft_contact_ke = 1.e+3
model.soft_contact_kd = 0.0
model.soft_contact_kf = 1.e+3

integrator = wp.sim.SemiImplicitIntegrator()

state_0 = model.state()
state_1 = model.state()

model.collide(state_0)

renderer = wp.sim.render.SimRenderer(model, os.path.join(os.path.dirname(__file__), "outputs/example_sim_rigid_fem.usd"))

for i in range(sim_frames):

    with wp.ScopedTimer("render"):

        renderer.begin_frame(sim_time)
        renderer.render(state_0)
        renderer.end_frame()

    with wp.ScopedTimer("simulate"):

        for s in range(sim_substeps):

            wp.sim.collide(model, state_0)

            state_0.clear_forces()
            state_1.clear_forces()

            integrator.simulate(model, state_0, state_1, sim_dt)
            sim_time += sim_dt

            # swap states
            (state_0, state_1) = (state_1, state_0)

renderer.save()


"""
Can we finally use our screen_rect to centre some text??

Just balancing and shit after that. I think there should be a bit more than a
snowball's space between the obstacles - part of the game's challenge can be
holding them there...?
"""

#imports and inits
import pygame
import random
import math
import os

# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREY1 = (230, 230, 230)
GREY2 = (220, 220, 220)
GREY3 = (210, 210, 210)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
ORANGE1 = (255, 210, 0)
ORANGE2 = (255, 180, 0)
ORANGE3 = (255, 130, 0)

PLASMA_COLORS = (YELLOW, ORANGE1, ORANGE2, ORANGE3)
SNOWBALL_COLORS = (WHITE, GREY1, GREY2, GREY3)

#define the classes
class Game(object):
    """ Represents an instance of the game."""

    def __init__(self):
        """Create all attributes and initialise the game"""
        self.score = 0
        self.antiscore = 0
        self.your_final_score = 0
        self.old_high_score = -999
        self.spawn_ticker = 0
        self.dec_ticker = 0
        self.SPAWN_TICKER_LIMIT = 500
        self.font = pygame.font.SysFont("Arial", 20, False, False)
        self.game_state = "menu"
        self.scored = False
        self.countdown_ticks = 0
        self.obstacles_spawned = False
        self.mouse_pos = pygame.mouse.get_pos()
        #create the sprite lists
        self.snowball_list = pygame.sprite.Group()
        self.obstacle_list = pygame.sprite.Group()
        self.plasma_list = pygame.sprite.Group()
        self.decball_list = pygame.sprite.Group()
        self.all_sprites_list = pygame.sprite.Group()
        #create player
        self.player = Player()
        self.player.rect.centerx = 350
        self.player.rect.centery = 450
        self.player.beam = False
        self.all_sprites_list.add(self.player)

    def process_events(self):
        """Event handling. Return True to close window/quit."""
        if self.game_state == "menu":
            # --- Main event handling loop
            for event in pygame.event.get():
                if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                    return True
                elif event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
                    for x in self.decball_list:
                        self.decball_list.remove(x)
                        self.all_sprites_list.remove(x)
                    self.game_state = "playing"
                    return False

        elif self.game_state == "playing":
            # --- Main event handling loop
            for event in pygame.event.get():
                if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                    return True
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    self.player.beam = True
                    return False
                elif event.type == pygame.MOUSEBUTTONUP:
                    self.player.beam = False
                    return False

        elif self.game_state == "over":
            for event in pygame.event.get():
                if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                    return True
                elif event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
                    self.__init__()

    def game_logic(self):
        """Main game logic - updates positions and checks for collides"""
        if self.game_state == "menu":
            self.countdown_ticks = pygame.time.get_ticks()
            #decball spawning
            self.dec_ticker += 1
            if self.dec_ticker > 59:
                self.dec_ticker = 0
            if (self.dec_ticker % 3) == 0:
                create_decball()
            #update sprites
            self.all_sprites_list.update()
            #remove shitty decballs
            for x in self.decball_list:
                if x.rect.top > 500:
                    self.decball_list.remove(x)
                    self.all_sprites_list.remove(x)

        elif self.game_state == "playing":
            #spawn obstacles
            while not self.obstacles_spawned:
                spawn_all_obstacles()
                self.obstacles_spawned = True
            #handle spawning
            self.spawn_ticker += 1
            if self.spawn_ticker == 20 or self.spawn_ticker == 270:
                create_snowballs()
            if self.spawn_ticker == self.SPAWN_TICKER_LIMIT:
                self.spawn_ticker = 0
            if self.player.beam == True:
                create_plasma()
            #update mouse_pos
            self.mouse_pos = pygame.mouse.get_pos()
            #update sprites + check collides
            self.all_sprites_list.update()
            self.snowballs_melted_list = pygame.sprite.groupcollide(self.obstacle_list, self.snowball_list, False, True)
            self.snowballs_hit_list = pygame.sprite.spritecollide(self.player, self.snowball_list, True)
            #remove shitty objects
            for x in self.snowball_list:
                if x.rect.y > 500:
                    self.snowball_list.remove(x)
                    self.all_sprites_list.remove(x)
                    self.antiscore += 1

            for x in self.plasma_list:
                if self.player.beam == False or x.ticker < 1:
                    self.plasma_list.remove(x)
                    self.all_sprites_list.remove(x)
            #update score for items in hit list
            for x in self.snowballs_hit_list:
                self.score += 1
            for x in self.snowballs_melted_list:
                self.antiscore += 1
            #countdown stuff
            self.seconds = (pygame.time.get_ticks() - self.countdown_ticks) / 1000
            self.minus = 0 - self.seconds
            self.countdown_from_this = 60 + self.minus #tweak this one for game length
            #game over if countdown over
            if self.countdown_from_this < 0:
                self.game_state = "over"

        elif self.game_state == "over":
            #decballs
            self.dec_ticker += 1
            if self.dec_ticker > 59:
                self.dec_ticker = 0

            if self.dec_ticker == 0 or self.dec_ticker == 29:
                create_decball()
            #update sprites
            self.all_sprites_list.update()
            #remove shitty decballs
            for x in self.decball_list:
                if x.rect.top > 500:
                    self.decball_list.remove(x)
                    self.all_sprites_list.remove(x)
            #scoring shit
            game.your_final_score = game.score - game.antiscore
            high_scores()

    def display_frame(self, screen):
        """Do all the display stuff"""
        if self.game_state == "menu":
            #clear the screen
            screen.fill(BLACK)
            #draw the decballs
            self.decball_list.draw(screen)

            font = pygame.font.SysFont("Arial", 40, False, False)
            title_headline_text1 = "Snowball's"
            title_headline_display1 = font.render(title_headline_text1, False, WHITE)
            screen.blit(title_headline_display1, [184, 150])

            title_headline_text2 = "Chance"
            title_headline_display2 = font.render(title_headline_text2, False, RED)
            screen.blit(title_headline_display2, [375, 150])

            font = pygame.font.SysFont("Arial", 20, False, False)
            title_sub_text = "Press return to play"
            title_sub_display = font.render(title_sub_text, False, WHITE)
            screen.blit(title_sub_display, [263, 200])

        elif self.game_state == "playing":
            #screen clearing/flashing code
            if self.snowballs_melted_list:
                screen.fill(RED)
            elif self.snowballs_hit_list:
                screen.fill(WHITE)
            else:
                screen.fill(BLACK)

            #draw all sprites
            self.all_sprites_list.draw(screen)

            #text stuff
            font = pygame.font.SysFont("Arial", 20, False, False)
            score_text = str(self.score)
            score_display = font.render(score_text, True, WHITE)
            screen.blit(score_display, [0, 0])

            antiscore_text = str(self.antiscore)
            antiscore_display = font.render(antiscore_text, True, RED)
            screen.blit(antiscore_display, [650, 0])

            timer_text = (str(math.ceil(self.countdown_from_this)))
            timer_display = font.render(timer_text, True, WHITE)
            screen.blit(timer_display, [300, 0])

        elif self.game_state == "over":
            screen.fill(BLACK)

            #decballs
            self.decball_list.draw(screen)
            #text stuff
            game_over_header_x = 175
            game_over_header_y = 50

            game_over_text_x = 200

            font = pygame.font.SysFont("Arial", 60, False, False)
            title_headline_text1 = "Game"
            title_headline_display1 = font.render(title_headline_text1, False, WHITE)
            screen.blit(title_headline_display1, [game_over_header_x, game_over_header_y])

            title_headline_text2 = "Over"
            title_headline_display2 = font.render(title_headline_text2, False, RED)
            screen.blit(title_headline_display2, [game_over_header_x + 175, game_over_header_y])

            font = pygame.font.SysFont("Arial", 20, False, False)
            if self.score > 1:
                title_sub_text1 = "You saved " + str(self.score) + " snowballs."
            else:
                title_sub_text1 = "You saved no snowballs... you monster."
            title_sub_display1 = font.render(title_sub_text1, False, WHITE)
            screen.blit(title_sub_display1, [game_over_text_x, 200])

            title_sub_text2 = "Meanwhile, you lost " + str(self.antiscore) + "..."
            title_sub_display2 = font.render(title_sub_text2, False, WHITE)
            screen.blit(title_sub_display2, [game_over_text_x + 25, 250])

            title_sub_text3 = "...so your score is " + str(self.your_final_score) + "."
            title_sub_display3 = font.render(title_sub_text3, False, WHITE)
            screen.blit(title_sub_display3, [game_over_text_x + 50, 300])

            if self.your_final_score > int(self.old_high_score):
                title_sub_text4 = "A new high score!"
            else:
                title_sub_text4 = "High score: " + str(self.old_high_score)
            title_sub_display4 = font.render(title_sub_text4, False, RED)
            screen.blit(title_sub_display4, [game_over_text_x + 50, 350])

            title_sub_text5 = "Press return to play again or escape to quit."
            title_sub_display5 = font.render(title_sub_text5, False, WHITE)
            screen.blit(title_sub_display5, [game_over_text_x - 50, 450])

        #Update display
        pygame.display.flip()

class Snowball(pygame.sprite.Sprite):
    def __init__(self):
        """ initialises a Snowball object """
        #initialise parent class constructor
        super().__init__()
        #create the surface and give it a black background
        self.image = pygame.Surface([20, 20])
        self.image.fill(BLACK)
        self.image.set_colorkey(BLACK)
        #other attributes
        self.rect = self.image.get_rect()
        self.yvelocity = 3
        self.xvelocity = 2
        self.right = random.randrange(2)
        #draw the circle
        pygame.draw.circle(self.image, SNOWBALL_COLORS[random.randrange(len(SNOWBALL_COLORS))], (10, 10), 10, 0)

    def update(self):
        global game
        """ Called each frame """
        #downwards motion
        if game.player.beam == False:
            self.rect.centery += 2
            if self.right:
                if not random.randrange(2):
                    self.rect.centerx += self.xvelocity
                if not random.randrange(32):
                    self.right = False
            else:
                if not random.randrange(2):
                    self.rect.centerx -= self.xvelocity
                if not random.randrange(64):
                    self.right = True
        #if the player is beaming
        else:
            #x axis motion
            if self.rect.centerx < game.player.rect.centerx:
                self.rect.centerx += self.xvelocity + random.randrange(-3,4)
            if self.rect.centerx > game.player.rect.centerx:
                self.rect.centerx -= self.xvelocity - random.randrange(-3,4)

class Decball(pygame.sprite.Sprite):
    def __init__(self):
        """ initialises a Snowball object """
        #initialise parent class constructor
        super().__init__()
        #create the surface and give it a black background
        self.image = pygame.Surface([20, 20])
        self.image.fill(BLACK)
        self.image.set_colorkey(BLACK)
        #other attributes
        self.rect = self.image.get_rect()
        self.yvelocity = 2
        self.xvelocity = 1
        self.right = random.randrange(2)
        #draw the circle
        pygame.draw.circle(self.image, SNOWBALL_COLORS[random.randrange(len(SNOWBALL_COLORS))], (10, 10), 10, 0)

    def update(self):
        #downwards
        self.rect.centery += 1
        if self.right:
            if not random.randrange(2):
                self.rect.centerx += 1
            if not random.randrange(32):
                self.right = False
        else:
            if not random.randrange(2):
                self.rect.centerx -= 1
            if not random.randrange(64):
                self.right = True

class Plasma(pygame.sprite.Sprite):
    def __init__(self):
        """initialises a beam plasma ball"""
        super().__init__()
        self.image = pygame.Surface([10,10])
        self.image.fill(BLACK)
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.ticker = 15
        pygame.draw.circle(self.image, PLASMA_COLORS[random.randrange(len(PLASMA_COLORS))], (5, 5), 5, 0)

    def update(self):
        self.ticker -= 1

class Obstacle(pygame.sprite.Sprite):
    def __init__(self):
        """initialise obstacle objects"""
        super().__init__()
        self.image = pygame.Surface([40, 40])
        self.image.fill(BLUE)
        self.right = True
        self.rect = self.image.get_rect()
        pygame.draw.rect(self.image, BLUE, self.rect, 0)

    def update(self):
        """called each frame"""
        if self.right:
            self.rect.x += 2
            if self.rect.right >= 700:
                self.right = False
        else:
            self.rect.x -= 2
            if self.rect.left <= 0:
                self.right = True

class Player(pygame.sprite.Sprite):
    def __init__(self):
        """initialises the player object"""
        super().__init__()
        self.image = pygame.Surface([20, 20])
        self.image.fill(BLACK)
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        #draw the player
        pygame.draw.rect(self.image, RED, self.rect, 0)

    def update(self):
        """called per frame"""
        self.rect.centerx = game.mouse_pos[0]

#define functions
def high_scores():
    global game
    if not game.scored:
        try:
            game.hi_scores = open("high_scores.txt", "r")
            game.old_high_score = int(game.hi_scores.read())
            game.hi_scores.close()
        except IOError:
            print("No HS file! Will create one on write.")
        except ValueError:
            print("Can't read HS value! Resorting to default -999")

        if int(game.old_high_score) < game.your_final_score:
            game.hi_scores = open("high_scores.txt", "w")
            game.hi_scores.write(str(game.score - game.antiscore))
            game.hi_scores.close()
        game.scored = True

def create_snowballs():
    """ spawns a volley of snowballs at the top of the screen"""
    global game
    for i in range(25):
        #create one
        snowball = Snowball()
        #set its x-y coords
        snowball.rect.x = random.randrange(700)
        snowball.rect.y = 0
        snowball.right = True
        #add it to the lists
        game.snowball_list.add(snowball)
        game.all_sprites_list.add(snowball)

def create_decball():
    """ creates a single decball"""
    global game
    decball = Decball()
    decball.rect.x = random.randrange(700)
    decball.rect.bottom = 0
    #lists
    game.decball_list.add(decball)
    game.all_sprites_list.add(decball)

def create_plasma():
    """spawns a brace of searing plasma near the player"""
    global game
    for i in range(5):
        plasma = Plasma()
        plasma.rect.x = game.player.rect.x + random.randrange(-20, 21)
        plasma.rect.y = game.player.rect.y - (20 + random.randrange(10))
        game.plasma_list.add(plasma)
        game.all_sprites_list.add(plasma)

def create_obstacle(x, y, right):
    """spawns an obstacle. (xpos, ypos, True/False)
    The list stuff is a cludge because we can't call game.methods() on init"""
    obstacle = Obstacle()
    obstacle.rect.centerx = x
    obstacle.rect.centery = y
    obstacle.right = right
    game.obstacle_list.add(obstacle)
    game.all_sprites_list.add(obstacle)

def spawn_all_obstacles():
    create_obstacle(100, 100, False)
    create_obstacle(200, 175, True)
    create_obstacle(300, 250, False)
    create_obstacle(400, 325, True)

#main loop----------------------------------------------------------------------
def main():
    #make game global cause we are going to be referring to it from inside
    #other functions... a lot
    global game, screen_rect

    #Init stuff not handled by game class
    pygame.init()

    size = (700, 500)
    screen = pygame.display.set_mode(size)
    screen_rect = screen.get_rect()
    pygame.display.set_caption("Snowball's Chance")

    done = False

    clock = pygame.time.Clock()

    #create an instance of the Game class (remember, it's global)
    game = Game()

    #Main game loop
    while not done:
        #Process events (remember - the funtion returns True at quit time)
        done = game.process_events()
        #Run game logic
        game.game_logic()
        #Update display
        game.display_frame(screen)
        #Debug console shit can go below if required

        #pause for next frame
        clock.tick(60)
    pygame.quit()

# Call the main function, start up the game
if __name__ == "__main__":
    main()