import PyQt5
from PyQt5 import QtCore
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import operator
import json
from tkinter import *
import time
import os.path
import tkinter.ttk as ttk
from tkinter import messagebox
from tkinter.filedialog import *
from tkinter import scrolledtext
import tkinter.font as tkFont
from tkcalendar import *
import tkinter as tk
import datetime
from datetime import timedelta
from PIL import Image, ImageTk
import getpass as gp
from multiprocessing import Process, Queue
import threading
import pprint
import pandas as pd
import openpyxl
from openpyxl.styles import Font,Alignment,PatternFill,Color, alignment
import shutil
from openpyxl.styles.borders import Border, Side
import webbrowser
import winshell
import schedule
import pandas

today_file_path='data/today_result.json'
history_file_path='data/today_history.json'
setting_file_path='data/setting.json'
icon_path='checkbox/logo.ico'
excel_path='data_excel.xlsx'
history_excel_path='history_excel.xlsx'
images_path=['places/notebook.png','places/print.png','places/dvd.png']

FILE_CLOSE = True

def ctrlEvent(event):#crtl+c제외 키 블락
    if(12==event.state and event.keysym=='c' ):
        return
    else:
        return "break"

def date_range(start, end):
    start = datetime.datetime.strptime(start, "%Y-%m-%d")
    end = datetime.datetime.strptime(end, "%Y-%m-%d")
    dates = [date.strftime("%Y-%m-%d") for date in pd.date_range(start, periods=(end-start).days+1)]
    return dates

def today_date_str():
    return datetime.datetime.today().strftime("%Y-%m-%d")

def now_time_str():
    return today_date_str()+datetime.datetime.now().strftime(" %I:%M:%S %p")

def imageModifier(FILE_PATH,x,y):#아미지 사이즈 재설정 함수
    img1=Image.open(FILE_PATH)
    img1=img1.resize((x,y),Image.ANTIALIAS)
    resized_img1=ImageTk.PhotoImage(img1)
    return resized_img1

class Json_Data():
    def __init__(
        self,FilePath=today_file_path,
        HistoryPath=history_file_path,
        SettingPath=setting_file_path,
        iconpath=icon_path,
        whereList=["노트북",'프린트','관내열람'],
        genderList=['남성','여성'],
        imagelist=images_path,
        savetime='17:50',
        savedir=winshell.desktop()):#생성자

        if os.path.isfile(iconpath):pass#아이콘 체크
        else:iconpath=''

        for image in imagelist:#이미지 리스트 체크
            if os.path.isfile(image):pass
            else:imagelist.remove(image)

        self.SettingPath=SettingPath
        self.settings={}

        self.load_settings()#세팅 파일 로드
        self.check_setting(FilePath,HistoryPath,whereList,genderList,imagelist,savetime,savedir,iconpath)

        self.__Today_Data__=[]
        self.data={}
        self.history={}

        if self.check_save():
            with open(self.FilePath,"r") as f:
                self.data = json.load(f)
            self.check_date()
            if self.check_his():
                with open(self.HistoryPath,"r") as h:
                    self.history=json.load(h)
                    self.add_history_member(type='init')
            else:
                self.history['init']=[]
                self.history['push']=[]
                self.history['show']=[]
                self.history['built']=[]
                self.history['fail']=[]
                self.add_history_member(type='built')
                self.add_history_member(type='init')
        else:
            if self.check_his():
                with open(self.HistoryPath,"r") as h:
                    self.history=json.load(h)
                    self.add_history_member(type='built')
                    self.add_history_member(type='init')
            else:
                self.history['init']=[]
                self.history['push']=[]
                self.history['show']=[]
                self.history['built']=[]
                self.history['fail']=[]
                self.add_history_member(type='built')
                self.add_history_member(type='init')
            self.data['cumulative']=0#전체 누적 이용자 수
            self.data['typecode']="TR"#데이터 타입
            for where in self.__WhereName__:
                self.data[where]=[]
                k={
                    "date":today_date_str(),
                    "where":where
                }
                for gender in self.__Gender__:
                    k[gender]=0
                self.data[where].append(k)
            self.check_date()
            self.save_data()

    def save_data(self):#데이터 저장
        with open(self.FilePath,'w') as fk:
            json.dump(self.data, fk,indent=4)

    def load_settings(self):
        if os.path.isfile(self.SettingPath):
            with open(self.SettingPath,'r') as stpr:
                self.settings=json.load(stpr)

    def check_setting(self,FilePath,HistoryPath,whereList,genderList,imagelist,savetime,savedir,iconpath):
        '''
        세팅 파일에서 읽어온 데이터 체크
        ->만약 내용이 없다면 1번(새로 만들고 저장 후 자기함수호출)
        ->내용이 불완전하다 2번(세팅 읽어온거 다 지우고 자기함수호출)
        ->내용이 맞다면 3번(세이브 파일 요소로 등록 후 함수 나옴)
        '''
        if self.settings=={}:
            self.settings['FilePath']=[]
            self.settings['FilePath'].append({
                'path':FilePath,
                'type':'Data'
            })
            self.settings['FilePath'].append({
                'path':HistoryPath,
                'type':'History'
            })
            self.settings['NameList']=[]
            self.settings['NameList'].append({
                'list':whereList,
                'type':'Place'
            })
            self.settings['NameList'].append({
                'list':genderList,
                'type':'Gender'
            })
            self.settings['ImagePath']=imagelist
            self.settings['DailySave']={
                'time':savetime,
                'dir':os.path.abspath(savedir)
            }
            self.settings['IconPath']=iconpath
            self.save_settings()
            self.check_setting(FilePath,HistoryPath,whereList,genderList,imagelist,savetime,savedir,iconpath)
        else:
            if sorted(list(self.settings.keys()))!=sorted(['FilePath','NameList','ImagePath','DailySave','IconPath']):
                self.settings={}
                self.check_setting(FilePath,HistoryPath,whereList,genderList,imagelist,savetime,savedir,iconpath)
            else:
                self.settings_to_self()

    def settings_to_self(self):#세팅 dict로부터 요소들 읽어오기
        for d in self.settings['FilePath']:
            if d['type']=='Data':self.FilePath=d['path']
            elif d['type']=='History':self.HistoryPath=d['path']
        for f in self.settings['NameList']:
            if f['type']=='Place': self.__WhereName__=f['list']
            elif f['type']=='Gender':self.__Gender__=f['list']
        self.imagelist=self.settings['ImagePath']
        self.savetime=self.settings['DailySave']['time']
        self.savedir=self.settings['DailySave']['dir']
        self.icon_path=self.settings['IconPath']

    def change_settings(self,**kwargs):#요소를 바꾸고 세팅 dict에 넣은 후 저장, 바뀐 것이 있가면 True 리턴
        ischanged=False
        for k,v in kwargs.items():
            print (k)
            print(v)
            print('===========================')
            k=k.lower()
            if k=='savedir' and os.path.isdir(v):
                print('change savedir')
                self.savedir=v
                self.settings['DailySave']['dir']=self.savedir
                self.save_settings()
                ischanged=True
            if k=='iconpath' and os.path.isfile(v):
                print('change icon path')
                self.icon_path=v
                self.settings['IconPath']=self.icon_path
                self.save_settings()
                ischanged=True
            if k=='savetime' and v is str:
                try:
                    time.strftime(v,'%H:%M')
                    print('change savetime')
                    self.savetime=v
                    self.settings['DailySave']['time']=self.savetime
                    self.save_settings()
                    ischanged=True
                except ValueError:
                    pass
            if k=='imagelist' and type(v)==list:
                for vd in v:#이미지 리스트 체크
                    if os.path.isfile(vd):pass
                    else:v.remove(vd)
                print('change imagelist')
                self.imagelist=v
                self.settings['ImagePath']=self.imagelist
                self.save_settings()
                ischanged=True
            if k=='wherelist' and type(v)==list:
                for vd in v:
                    if type(vd) is not str:
                        v.remove(vd)
                print('change places name')
                self.__WhereName__=v
                for f in self.settings['NameList']:
                    if f['type']=='Place': f['list']=self.__WhereName__
                self.save_settings()
                ischanged=True
            if k=='genderlist' and type(v)==list:
                for vd in v:
                    if type(vd) is not str:
                        v.remove(vd)
                print('change Gender name')
                self.__Gender__=v
                for f in self.settings['NameList']:
                    if f['type']=='Gender': f['list']=self.__Gender__
                self.save_settings()
                ischanged=True
            if k=='filepath':
                print('Change FilePath')
                self.FilePath=v
                for d in self.settings['FilePath']:
                    if d['type']=='Data':d['path']=self.FilePath
                self.save_settings()
                ischanged=True
            if k=='historypath':
                print('Change HistoryPath')
                self.HistoryPath=v
                for d in self.settings['FilePath']:
                    if d['type']=='History':d['path']=self.HistoryPath
                self.save_settings()
                ischanged=True
        return ischanged

    def show_settings(self,*args):
        tmp={}
        for arg in args:
            k=None
            if arg.lower()=='filepath':k=self.FilePath
            elif arg.lower()=='historypath':k=self.HistoryPath
            elif arg.lower()=='wherelist':k=self.__WhereName__
            elif arg.lower()=='genderlist':k=self.__Gender__
            elif arg.lower()=='imagelist':k=self.imagelist
            elif arg.lower()=='savetime':k=self.savetime
            elif arg.lower()=='savedir':k=self.savedir
            elif arg.lower()=='iconpath':k=self.icon_path
            if k!=None:tmp[arg]=k
        return tmp
    def save_settings(self):
        with open(self.SettingPath,'w') as kosk:
            json.dump(self.settings,kosk, indent=4)

    def save_history(self):#내역 저장
        with open(self.HistoryPath,'w') as hk:
            json.dump(self.history,hk,indent=4)

    def add_history_member(self,type='push',count=1,gender="",place="",showdates=(today_date_str(),today_date_str())):
        tmp={}
        if type =='built'or type=='init':
            tmp['user']=gp.getuser()
            tmp['time']=now_time_str()
            tmp['type']=type
            tmp['isSucess']=TRUE
        elif type=='push' and gender in self.__Gender__ and place in self.__WhereName__:
            tmp['user']=gp.getuser()
            tmp['time']=now_time_str()
            tmp['type']=type
            tmp['isSucess']=TRUE
            tmp['gender']=gender
            tmp['place']=place
            tmp['count']=count
        elif type=='show' and len(date_range(showdates[0],showdates[1]))>0:
            tmp['user']=gp.getuser()
            tmp['time']=now_time_str()
            tmp['type']=type
            tmp['isSucess']=TRUE
            tmp['dates']=date_range(showdates[0],showdates[1])
        else:
            tmp['user']=gp.getuser()
            tmp['time']=now_time_str()
            tmp['type']=type
            tmp['isSucess']=FALSE
            tmp['count']=count
            if gender!="":tmp['gender']=gender
            if place!="":tmp['place']=place
            self.history['fail'].append(tmp)
            self.save_history()
            return FALSE
        self.history[tmp['type']].append(tmp)
        self.save_history()
        return TRUE

    def check_date(self,date_w=today_date_str()):#오늘 날짜 멤버 체크 및 생성
        today=date_w
        print('check_date')
        print(today)
        self.__Today_Data__=[]
        for where in self.__WhereName__:
            for item in self.data[where]:
                if today==item['date']:
                    self.__Today_Data__.append(item)
                    break
        print('sada')
        print(self.__Today_Data__)
        if len(self.__Today_Data__)<len(self.__WhereName__):
            hasMember=[]
            for item in self.__Today_Data__:
                hasMember.append(item['where'])
            tmp=list(set(self.__WhereName__)-set(hasMember))
            print('fdasfasd')
            print(tmp)
            for place in tmp:
                kal={
                    "date":today,
                    "where":place
                }
                for gender in self.__Gender__:
                    kal[gender]=0
                self.data[place].append(kal)
            self.check_date(date_w=today)
        elif len(self.__WhereName__)==len(self.__Today_Data__):
            self.save_data()
            return
        else: self.check_date(date_w=today)

    def show_data(self,start=today_date_str(),end=today_date_str(),mode=FALSE):#특정 기간의 데이터 검색
        end_date=datetime.datetime.strptime(end, '%Y-%m-%d')
        start_date=datetime.datetime.strptime(start, '%Y-%m-%d')
        result=[]
        delta=end_date - start_date
        if delta.days==0:
            for place in self.__WhereName__:
                for data in self.data[place]:
                    if datetime.datetime.strptime(data['date'],'%Y-%m-%d')==start_date:
                        result.append(data)
                        break
        elif delta.days>=1:
            for time in [start_date+timedelta(days=i) for i in range(delta.days+1)]:
                for place in self.__WhereName__:
                    for data in self.data[place]:
                        if datetime.datetime.strptime(data['date'],'%Y-%m-%d')==time:
                            result.append(data)
                            break
        if mode:self.add_history_member(type='show',showdates=(start,end))
        return result

    def push_data(self,date=today_date_str(),gender="",where="",count=1):#날짜/성별/장소 를 지정 count만큼 추가
        sucess=FALSE
        print('hey')
        if gender not in self.__Gender__:pass#Invalid Gender
        elif where not in self.__WhereName__:pass#Invalid Place
        elif [data for data in self.show_data(date,date) if data['where']==where]==[]:
            print(self.show_data(date,date))#No Member0
            print(where)
        else:
            target=[data for data in self.show_data(date,date) if data['where']==where][0]
            print('kola')
            print(target)
            for member in self.data[where]:
                if member==target:
                    member[gender]+=count
                    if member[gender]<0:
                        member[gender]=0
                    self.data['cumulative']+=count
                    if self.data['cumulative']<=0:
                        self.data['cumulative']=0
                    sucess=TRUE
                    break
        self.save_data()
        self.add_history_member(type='push',gender=gender,place=where,count=count)
        return sucess

    def modify_history_excel(self,excel_path=history_excel_path):
        """
        excel_path : if mode is TRUE excel file will save at excel_path. Defalt :'history_excel.xlsx'
        """
        columns_h={}
        for key in list(self.history.keys()):
            try:
                columns_h[key]=list(self.history[key][0].keys())
            except IndexError:
                columns_h[key]=[]

        wb=openpyxl.Workbook()
        for key in list(self.history.keys()):
            ws=wb.create_sheet(key)
            if len(columns_h[key])!=0:
                for cl in range(len(columns_h[key])):
                    ws.cell(row=1,column=cl+2).value=columns_h[key][cl]
                    ws.cell(row=1,column=cl+2).alignment=Alignment(horizontal='center',vertical='center')
                    ws.cell(row=1,column=cl+2).fill=PatternFill(patternType='solid',fgColor=Color('FFC000'))
                for index in range(len(self.history[key])):
                    ws.cell(row=index+2,column=1).value=index+1
                    ws.cell(row=index+2,column=1).alignment=Alignment(horizontal='center',vertical='center')
                    ws.cell(row=index+2,column=1).fill=PatternFill(patternType='solid',fgColor=Color('008000'))
                    ws.cell(row=index+2,column=1).font=Font(bold=TRUE,color=Color('ffffff'))
                    for cl in range(len(columns_h[key])):
                        if type(self.history[key][index][columns_h[key][cl]])!=list:ws.cell(row=index+2,column=cl+2).value=self.history[key][index][columns_h[key][cl]]
                        else:ws.cell(row=index+2,column=cl+2).value=str(self.history[key][index][columns_h[key][cl]])
                        ws.cell(row=index+2,column=cl+2).alignment=Alignment(horizontal='center',vertical='center')
                self.adjust_cell_width(ws)
            else:
                pass
        wb.remove(wb['Sheet'])
        try:
            wb.save(excel_path)
            os.startfile(excel_path)
        except PermissionError:
            messagebox.showerror("PermissionError","파일을 닫아주세요.")

    def adjust_cell_width(self, ws,value=1.2,cl=['A'],ri=[1]):
        """
        Adjust cell width/make (.1)&(A.) thick
        ws : worksheet handle from openpyxl
        cl : options to make other columns thick default : ['a']
        ri : options to make other rows thick default : [1]
        """
        thick_border=Border(left=Side(style='thick'),right=Side(style='thick'),top=Side(style='thick'),bottom=Side(style='thick'))
        for col in ws.columns:
            max_length =0
            column_col=col[0].column_letter
            for cell in col:
                cell.alignment=Alignment(horizontal='center',vertical='center')
                try:
                    if cell.column_letter in cl or cell.row in ri:cell.border=thick_border
                    if cell.value==0:cell.value='-'
                    if len(str(cell.value)) > max_length:
                        max_length = len(str(cell.value))
                except:
                    print('kr')
                    pass
            adjusted_width=(max_length+2)*value
            print(column_col)
            print(int(adjusted_width))
            ws.column_dimensions[str(column_col)].width=int(adjusted_width)

    def give_savedir(self):#만약 프로그램을 다른 컴퓨터에서 실행한다면 데스크톱 유저 디렉토리도 바뀌므로 그에 대비해서 만든 함수
        tmp=''
        if os.path.isdir(self.savedir):
            pass
        elif self.savedir.split('\\')[-1]=='Desktop':
            tmp=winshell.desktop()
        else:
            tmp='data'
        if tmp!='':self.change_settings(savedir=tmp)
        return self.savedir

    def modify_data_excelike(self,selected_dates=[],mode=TRUE,excel_path=excel_path):
        """
        mode : make Excel file default : True
        selected_dates : list of dates that required for showing info DeFault : show_everything
        excel_path : if mode is TRUE excel file will save at excel_path. Defalt :'data_excel.xlsx'
        """
        datesd=[]
        for place in self.__WhereName__:
            for data in self.data[place]:
                if data['date'] not in datesd:datesd.append(data['date'])
        dates=[]
        if selected_dates!=[]:
            for date in datesd:
                if date in selected_dates:
                    dates.append(date)
        else:dates=datesd
        DATE=sorted(dates)
        dates=DATE
        result={}
        columns_d=["Date"]
        columns_name=[]
        for where in self.__WhereName__:
            for gender in self.__Gender__:
                columns_name.append(where+" "+gender)
        columns_d+=columns_name
        columns_d+=['총합']
        for date in range(len(dates)):
            sd=self.show_data(start=dates[date],end=dates[date],mode=TRUE)
            tmp=[dates[date]]
            for place in self.__WhereName__:
                for gender in self.__Gender__:
                    tmp.append(0)
            tmp.append(0)
            for member in sd:
                for i in range(len(self.__WhereName__)):
                    if member['where']==self.__WhereName__[i]:
                        for j in range(len(self.__Gender__)):
                            tmp[i*2+j+1]+=member[self.__Gender__[j]]
                            tmp[-1]+=tmp[i*2+j+1]
            result[str(date+1)]=tmp
        pprint.pprint(result)
        if mode:
            df=pd.DataFrame.from_dict(result,orient="index",columns=columns_d)
            try:
                df.to_excel(excel_path)
                wb=openpyxl.load_workbook(excel_path,data_only=True)
                ws=wb['Sheet1']
                sum_row=[]
                for c in ws.columns:
                    column_ind=c[0].column_letter
                    c[0].alignment=Alignment(horizontal='center',vertical='center')
                    c[0].fill=PatternFill(patternType='solid',fgColor=Color('FFC000'))
                    if column_ind !='A' and column_ind !='B':
                        tmp_add=0
                        for cell in c:
                            cell.alignment=Alignment(horizontal='center',vertical='center')
                            if cell.row!=1:
                                tmp_add+=int(cell.value)
                        sum_row.append(tmp_add)
                    elif column_ind=='A':
                        F=Font(bold=TRUE,color=Color('ffffff'))
                        for cell in c:
                            cell.alignment=Alignment(horizontal='center',vertical='center')
                            cell.fill=PatternFill(patternType='solid',fgColor=Color('008000'))
                            cell.font=F
                    else:
                        F=Font(bold=TRUE,color=Color('ffffff'))
                        for cell in c:
                            cell.alignment=Alignment(horizontal='center',vertical='center')
                            cell.fill=PatternFill(patternType='solid',fgColor=Color('008000'))
                            cell.font=F
                ws.append(["총합"," "]+sum_row)
                kolase=[]
                for kas in range(len(self.__Gender__)):
                    j=0
                    for suro in range(len(sum_row)):
                        if suro%len(self.__Gender__)==kas:
                            j+=sum_row[suro]
                    kolase.append(j)
                kolase[0]-=sum_row[-1]
                kartli=[]
                for genko in range(len(self.__Gender__)):
                    kartli.append(self.__Gender__[genko]+ " 총합 :")
                    kartli.append(kolase[genko])
                place_total=[]
                GT=len(self.__Gender__)
                for plag in range(len(self.__WhereName__)):
                    loki=0
                    for geni in range(GT):
                        loki+=sum_row[plag*GT+geni]
                    place_total.append(self.__WhereName__[plag]+" 총합 :")
                    place_total.append(loki)
                ws.append(["",""]+kartli)
                ws.append(["",""]+place_total)
                self.adjust_cell_width(ws,value=2.4,cl=['A','B'])
                ws.column_dimensions['A'].width=5
                wb.save(excel_path)
                os.startfile(excel_path)
            except PermissionError:
                messagebox.showerror("PermissionError","파일을 닫아주세요.")
        return result

    def columns_name(self):
        columns_name=[]
        for where in self.__WhereName__:
            for gender in self.__Gender__:
                columns_name.append(where+" "+gender)
        return columns_name

    def button_event(self,event,where="",gender="",mode=TRUE):
        if where not in self.__WhereName__ or gender not in self.__Gender__:pass
        else:
            if mode==TRUE:self.push_data(gender=gender,where=where)
            else:self.push_data(gender=gender,where=where,count=-1)

    def check_save(self,path=""):
        isValid=FALSE
        if path=="":path=self.FilePath
        if os.path.isfile(path):
            check_tmp={}
            with open(path,'r') as check:
                check_tmp=json.load(check)
            if sorted(list(check_tmp.keys()))==sorted(self.__WhereName__+['cumulative','typecode']) and sorted(list(check_tmp[self.__WhereName__[0]][0].keys()))==sorted(list(self.__Gender__+['date','where'])):
                isValid=TRUE
                print("세이브 파일 무결성 확인")
        else:
            pass
        return isValid

    def check_his(self,path=""):
        isValid=FALSE
        if path=="":path=self.HistoryPath
        if os.path.isfile(path):
            check_tmp={}
            with open(path,'r') as check:
                check_tmp=json.load(check)
            if sorted(list(check_tmp.keys()))==sorted(['init','built','show','push','fail']):
                isValid=TRUE
                print("기록 파일 무결성 확인")
        else:
            pass
        return isValid

    def quit(self,mode=TRUE):
        global FILE_CLOSE
        FILE_CLOSE=mode
        print("자동저장 후 종료")
        self.save_data()
        self.save_history()
        self.save_settings()
        print('저장 완료')
        del self

class MyDelegate(QItemDelegate):
    def __init__(self,parent):
        super().__init__(parent)

    def paint(self,painter=QPainter,option=QStyleOptionViewItem,index=QModelIndex):
        super().paint(painter,option,index)
        painter.setPen(Qt.red)
        painter.drawRect( option.rect )
class MyApp(QWidget):
    def __init__(self,save_file=None,master=None):
        super().__init__()
        self.savefile=save_file
        self.master=master
        self.InitUi()
        self.SetUi()

    def InitUi(self):
        self.set_menu()
        self.set_statusbar()
        self.set_widgets()

    def set_menu(self):
        pass

    def set_statusbar(self):
        pass

    def set_widgets(self):
        self.table=QTableWidget(self)
        self.table.resize(1000,250)
        self.table.move(0,0)
        self.setTableWidgetData()

    def setTableWidgetData(self):
        dta=self.savefile.modify_data_excelike(mode=False)
        df=pandas.DataFrame.from_dict(dta,orient='index',columns=['Date(날짜)']+self.savefile.columns_name()+['Total(총합)'])
        self.table.setColumnCount(len(df.columns))
        self.table.setRowCount(len(df.index))
        self.table.setHorizontalHeaderLabels(df.columns.tolist())
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        for i in range(len(df.index)):
            for j in range(len(df.columns)):
                oak=QTableWidgetItem(str(df.iloc[i, j]))
                oak.setTextAlignment(QtCore.Qt.AlignCenter)
                self.table.setItem(i,j,oak)
        self.table.setAutoScroll(True)
        self.table.resizeColumnsToContents()
        self.table.resizeRowsToContents()
        self.table.setAutoFillBackground(True)
        self.table.setStyleSheet('QTableView {border: 4px solid ;} QTableView::column{border: 4px solid ;}')
        self.table.repaint()
    def SetUi(self):
        self.setWindowTitle(today_date_str()+'일 기록')
        self.resize(1000,600)
        self.center()
        self.setWindowIcon(QIcon(self.savefile.icon_path))
        self.show()

    def center(self):#make window move to center
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def closeEvent(self,event):
        event.ignore()
        print('Quit all')
        self.savefile.quit()
        event.accept()

if __name__ == "__main__":
    app=QApplication(sys.argv)
    print(app)
    jd=Json_Data()
    Mw=MyApp(save_file=jd,master=app)
    sys.exit(app.exec_())


import random,re
from termcolor import colored

def luck(L='',p='',w='',mesg=''):
    luck_st=colored(f"\n******GOOD LUCK******\n","red")
    places=['Albany','Mt Wellington','Mt Eden','Ponsonby','Auckland-CBD','Handerson','New-lynn','Tapu','NewMarket']

    if w=="lotto":
        print(luck_st)
        for i in range(int(L)):
            a=" ".join(sorted(str(i).zfill(2) for i in random.sample(range(1,41),6)))
            if p=="yes":
                print(colored(f"{a} \t   {str(random.randint(1,10)).zfill(2)}","cyan"))
            else:
                print(colored(f"{a}","blue"))
        print(luck_st)
        print(colored(f"{mesg} \n Your Ticket has been sold at {places[random.randint(0,len(places)-1)]}","red",'on_white'))

    else:
        print(luck_st)
        for i in range(int(L)):
                a=" ".join(str(i).zfill(2) for i in random.sample(range(1,41),4))
                print(colored(a,"blue"))
        print(luck_st)
        print(colored(f"{mesg} \n Your Ticket has been sold at {places[random.randint(0,len(places)-1)]}","red",'on_white'))

def balance(name_user):

    def check_balance(balance_user,balance_user_not_accept=None):
        if 199<balance_user:
            print(colored(f'\nPlease {name_user}. Make sure to not excced the limit $200\n{"Also we dont accept amounts like"+balance_user_not_accept+"c" if balance_user_not_accept else ""}' ,"red","on_white"))
            return balance(name_user)

        elif balance_user<6:
            print(colored(f'\nPlease {name_user}. The top up must be higher than $5\n{"Also we do not accept amounts like"+balance_user_not_accept+"c" if balance_user_not_accept else ""}' ,"red","on_white"))
            return balance(name_user)

        elif balance_user_not_accept:
            print(colored(f'\nGood Luck {name_user}.But we will only accept {balance_user}$ we do not accept amounts like {balance_user_not_accept+"c" if balance_user_not_accept else ""}' ,"red","on_white"))
            print(colored(f"Each line of JackPot cost $2 and 1$ for Strike or Lotto ","red",'on_white'))
            return x(name_user,balance_user)

    balance_user=input(colored('how much would you like to top up your account \n','red')).strip()

    if balance_user=='':
        print(f'\nplease dont leave it blank {name_user}\n ')
        return balance(name_user)

    elif re.findall(r"^[\d]+$",balance_user):
        balance_user=int(balance_user)
        check_balance(balance_user)

    elif balance_user.find('.') !=-1 and balance_user.count('.')==1:
        balance_user_not_accept=balance_user[balance_user.index('.'):]
        balance_user=int(balance_user[:balance_user.index('.')])
        check_balance(balance_user,balance_user_not_accept)

    else:
        print('\nplease onlt type number')
        return balance(name_user)

    print(colored(f"Good Luck {name_user.upper()} - your balance is {balance_user}$",'red','on_white'))
    print(colored(f"Each line of JackPot cost $2 and 1$ for Strike or Lotto ","red",'on_white'))
    return x(name_user,balance_user)

def name_user():
    name_user=input(colored('what is your name \n','red')).strip()
    while name_user=='' or re.findall(r"[\d\W]",name_user):
        if name_user=='':
            print(colored("Please don't leave it blank",'red','on_white'))
        else:
            print(colored("Please type only letters!",'red','on_white'))
        name_user=input(colored('what is your name \n','red',"on_white"))
    return balance(name_user)

def strike(balance):
    which="stike"
    lines= balance
    power=None
    mesg=colored(f"you will #{lines}LINES of STRIKES \n",'red')
    return luck(lines,power,which,mesg)

def lotto(balance):
    which="lotto"
    power=input(colored(f"are you keen for a jakpot ? yes or no \n",'red',"on_white")).lower()
    if power =='yes' or power=='y':
        if balance %2==0:
            lines=int(balance/2)
            mesg=f"you have #{lines} LINES of jackpot draw!"
            return luck(lines,power,which,mesg)
        else:
            balance-=1
            lines=int(balance/2)
            mesg=f'''you have #{lines} LINES of jackpot draw!
            please note that your balance now is 1$'''
            return luck(lines,power,which,mesg)
    else:
        power='no'
        lines= int(balance)
        mesg=f"you have #{lines} LINES of {which} draw!"
        return luck(lines,power,which,mesg)

def x(name,balance):

    which=input(colored('\nDo you want lotto or strike ?\n','red',"on_white").capitalize()).lower()

    while which=='' :
            print(colored(f'please {name.upper()} Either type lotto or strike. thank you :)',"red","on_white"))
            which=input(colored('\n do you want lotto or strike ?\n','red','on_white').capitalize()).lower()

    if which != 'lotto' and which!='strike':
        like_strike=re.search(r"[strike]{,10}",which).group()
        like_lotto=re.search(r"[lto]{,10}",which).group()
        answers=['y','yes','ys']

        if like_strike  or like_lotto :
            ask=input(colored(f"Do you mean {'strike' if like_strike else 'lotto' } ? Yes or No ?\n",'red','on_white')).lower()
            while ask=="":
                    print(f'Dear {name.upper()} please make sure to type Yes or No...')
                    ask=input(colored(f"Do you mean {'strike' if like_strike else 'lotto' } ? Yes or No ?\n",'red',"on_white")).lower()
            else:
                if ask not in answers:
                    print(colored(f'I think you change your mind{name.upper()} ....let us strat from begin!',"red","on_white"))
                    return x(name,balance)
                else:
                    if like_strike:
                        return strike(balance)
                    else:
                        return lotto(balance)
        else:
            print(colored(f'I can not understand that {name.upper()} ....let us strat from begin!',"red","on_white"))
            return x(name,balance)

    else:
        if which=="lotto":
            return lotto(balance)

        else:
            return strike(balance)

name_user()


from tempfile import TemporaryDirectory
from typing import List

import torch

from robot_demo.utils.image import visualize_joint_prediction
from robot_demo.utils.movie import combine_gifs, save_movie_gif

from .utils import plot_spatial_softmax, setup

@torch.inference_mode()
def open_loop(model_name: str, batch_indices: List[int]) -> None:
    report_dir, model, datamodule = setup(model_name, "open_loop")

    model.init_hidden(batch_size=datamodule.actions.shape[0])
    output = model(
        actions=datamodule.actions,
        observations=datamodule.observations,
        goals=datamodule.goals,
    )
    for batch_idx in batch_indices:
        visualize_joint_prediction(
            target_data=datamodule.actions[batch_idx],
            pred_data=output["action_prediction"][batch_idx],
            save_path=f"{report_dir}/action_{batch_idx}.png",
        )
        with TemporaryDirectory() as tmp_dir:
            paths = [f"{tmp_dir}/obs.gif", f"{tmp_dir}/pred.gif"]
            save_movie_gif(
                movie=datamodule.observations[batch_idx],
                label="observation",
                output_path=paths[0],
            )
            save_movie_gif(
                movie=output["observation_prediction"][batch_idx],
                label="prediction",
                output_path=paths[1],
            )
            output_path = f"{report_dir}/obs_pred_{batch_idx}.gif"
            combine_gifs(*paths, rows=2, output_path=output_path)

@torch.inference_mode()
def feature_points(model_name: str, batch_indices: List[int]) -> None:
    report_dir, model, datamodule = setup(model_name, "open_loop")
    with TemporaryDirectory() as tmp_dir:
        paths = []
        for batch_index in batch_indices:
            observation = plot_spatial_softmax(
                observation=datamodule.observations[batch_index],
                encoder=model.spatial_encoder._conv,
            )
            path = f"{tmp_dir}/feature_points_{batch_index}.gif"
            paths.append(path)
            save_movie_gif(
                movie=observation,
                label=str(batch_index),
                output_path=path,
            )
        output_path = f"{report_dir}/feature_points.gif"
        combine_gifs(*paths, rows=2, output_path=output_path)


'''
API kurs mata uang
'''

import requests
kode = input('ketik bank: ')
data = requests.get(f'https://kurs.web.id/api/v1/{kode}')
data1 = requests.get('https://blockchain.info/ticker')
error_code = data.json()['error']

if error_code == 'true':
    print('bank tidak ada')
else:
    print('1.USD>IDR\n2.IDR>USD\n3.USD>Bitcoin\n4.Bitcoin>USD\n5.IDR>Bitcoin\n6.Bitcoin>IDR')
    quest = int(input('masukan 1/2/3/4/5/6: '))
    kurs_jual = float(data.json()['jual'])
    kurs_beli = float(data.json()['beli'])
    value = data1.json()['USD']['buy']
    if quest == 1:
        nominal = float(input('masukan nominal USD: '))
        convert_result = (nominal * kurs_jual)
        print(f'{nominal} USD = Rp {round(convert_result,2)}')
        print(f'{kode.upper()}: kurs jual = {kurs_jual} dan kurs beli = {kurs_beli}')
    elif quest == 2:
        nominal = float(input('masukan nominal Rp: '))
        convert_result = (nominal / kurs_beli)
        print(f'{nominal} Rp = USD {round(convert_result,2)}')
        print(f'{kode.upper()}: kurs jual = {kurs_jual} dan kurs beli = {kurs_beli}')
    elif quest == 3:
        nominal = float(input('masukan nominal USD: '))
        convert_result = (nominal / value)
        print(f'{nominal} USD = Bitcoin {convert_result}')
    elif quest == 4:
        nominal = float(input('masukan nominal Bitcoin: '))
        convert_result = (nominal * value)
        print(f'{nominal} Bitcoin = USD {convert_result}')
    elif quest == 5:
        nominal = float(input('masukan nominal IDR: '))
        idr_to_usd = (nominal/kurs_beli)
        convert_result = (idr_to_usd/value)
        print(f'{nominal} IDR = Bitcoin {convert_result}')
    elif quest == 6:
        nominal = float(input('masukan nominal Bitcoin: '))
        bit_to_usd = (nominal*kurs_jual)
        convert_result = (bit_to_usd*value)
        print(f'{nominal} Bitcoin = IDR {convert_result}')
    else:
        print('tidak ada menu pilihan')


import tensorflow as tf
import numpy as np
import cv2 as cv

class DataGenerator(tf.keras.utils.Sequence):
    def __init__(self, ids, mask, image_dir='./', batch_size=2, img_h=256, img_w=256, shuffle=True):

        self.ids = ids
        self.mask = mask
        self.image_dir = image_dir
        self.batch_size = batch_size
        self.img_h = img_h
        self.img_w = img_w
        self.shuffle = shuffle
        self.on_epoch_end()

    def __len__(self):
        return int(np.floor(len(self.ids)) / self.batch_size)

    def __getitem__(self, index):
        indexes = self.indexes[index * self.batch_size: (index + 1) * self.batch_size]
        list_ids = [self.ids[i] for i in indexes]
        list_mask = [self.mask[i] for i in indexes]
        X, y = self.__data_generation(list_ids, list_mask)

        return X, y

    def on_epoch_end(self):
        self.indexes = np.arange(len(self.ids))

        if self.shuffle:
            np.random.shuffle(self.indexes)

    def __data_generation(self, list_ids, list_mask):
        X = np.empty((self.batch_size, self.img_h, self.img_w, 3))
        y = np.empty((self.batch_size, self.img_h, self.img_w, 1))

        for i in range(len(list_ids)):
            img_path = str(list_ids[i])

            mask_path = str(list_mask[i])

            img = cv.cvtColor(cv.imread(img_path), cv.COLOR_BGR2RGB)
            mask = cv.cvtColor(cv.imread(mask_path), cv.COLOR_BGR2GRAY)

            img = cv.resize(img, (self.img_h, self.img_w))
            img = np.array(img, dtype=np.float64)

            mask = cv.resize(mask, (self.img_h, self.img_w))
            mask = np.array(mask, dtype=np.float64)

            img -= img.mean()
            img /= img.std()

            mask -= mask.mean()
            mask /= mask.std()

            X[i,] = img
            y[i,] = np.expand_dims(mask, axis=2)

        y = (y > 0).astype(int)

        return X, y


from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_SplashSCreen(object):
    def __init__(self,window):
        super(Ui_SplashSCreen, self).__init__()
        self.setupUi(window)

    def setupUi(self, SplashSCreen):
        SplashSCreen.setObjectName("SplashSCreen")
        SplashSCreen.resize(680, 400)
        self.centralwidget = QtWidgets.QWidget(SplashSCreen)
        self.centralwidget.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.centralwidget.setObjectName("centralwidget")
        self.dropShadowFrame = QtWidgets.QFrame(self.centralwidget)
        self.dropShadowFrame.setGeometry(QtCore.QRect(0, 0, 681, 401))
        self.dropShadowFrame.setStyleSheet("QFrame{\n"
"color: rgb(10, 66, 127);\n"
"background-color:rgb(162, 155, 255);\n"
"border-radius:20px;\n"
"}")
        self.dropShadowFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.dropShadowFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.dropShadowFrame.setObjectName("dropShadowFrame")
        self.main_label = QtWidgets.QLabel(self.dropShadowFrame)
        self.main_label.setGeometry(QtCore.QRect(16, 70, 651, 91))
        font = QtGui.QFont()
        font.setFamily("Yu Gothic UI Semibold")
        font.setPointSize(40)
        self.main_label.setFont(font)
        self.main_label.setStyleSheet("background-color: rgb(216, 255, 221);")
        self.main_label.setAlignment(QtCore.Qt.AlignCenter)
        self.main_label.setObjectName("main_label")
        self.progressBar = QtWidgets.QProgressBar(self.dropShadowFrame)
        self.progressBar.setGeometry(QtCore.QRect(100, 260, 501, 31))
        font = QtGui.QFont()
        font.setFamily("Yu Gothic UI Semilight")
        font.setPointSize(13)
        self.progressBar.setFont(font)
        self.progressBar.setStyleSheet("QProgressBar{\n"
"    background-color: rgb(173, 167, 255);\n"
"    \n"
"    color: rgb(0, 0, 127);\n"
"border-radius:20px;\n"
"text-align:centre;\n"
"\n"
"}\n"
"QProgressBar::chunk{\n"
"border-radius:20px;\n"
"    background-color: rgb(67, 170, 150);\n"
"}")
        self.progressBar.setProperty("value", 24)
        self.progressBar.setAlignment(QtCore.Qt.AlignCenter)
        self.progressBar.setTextVisible(True)
        self.progressBar.setTextDirection(QtWidgets.QProgressBar.BottomToTop)
        self.progressBar.setObjectName("progressBar")
        self.loading_label = QtWidgets.QLabel(self.dropShadowFrame)
        self.loading_label.setGeometry(QtCore.QRect(6, 290, 671, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(10)
        font.setItalic(True)
        font.setStrikeOut(False)
        self.loading_label.setFont(font)
        self.loading_label.setAlignment(QtCore.Qt.AlignCenter)
        self.loading_label.setWordWrap(True)
        self.loading_label.setObjectName("loading_label")
        self.createdby_label = QtWidgets.QLabel(self.dropShadowFrame)
        self.createdby_label.setGeometry(QtCore.QRect(20, 350, 651, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(10)
        font.setItalic(False)
        font.setStrikeOut(False)
        self.createdby_label.setFont(font)
        self.createdby_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.createdby_label.setWordWrap(True)
        self.createdby_label.setObjectName("createdby_label")
        SplashSCreen.setCentralWidget(self.centralwidget)

        self.retranslateUi(SplashSCreen)
        QtCore.QMetaObject.connectSlotsByName(SplashSCreen)

    def retranslateUi(self, SplashSCreen):
        _translate = QtCore.QCoreApplication.translate
        SplashSCreen.setWindowTitle(_translate("SplashSCreen", "MainWindow"))
        self.main_label.setText(_translate("SplashSCreen", "Practice Py-QT"))
        self.loading_label.setText(_translate("SplashSCreen", "
Loading
"))
        self.createdby_label.setText(_translate("SplashSCreen", "
Created by: Mushfiq
"))


import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

img = cv.imread('C:/Users/HASEE/Desktop/Pycharm_Project/images/landscape_2.jpeg', 1)
img_B = img.copy()
img_G = img.copy()
img_R = img.copy()

# set channel of R to 0
img_R[81:110, 108:147, 0] = 0
ax1 = plt.subplot(221)
ax1.set_title('R')
plt.axis('off')
plt.imshow(img_R)

# set channel of G to 0
img_G[81:110, 108:147, 1] = 0
ax2 = plt.subplot(222)
ax2.set_title('G')
plt.axis('off')
plt.imshow(img_G)

# set channel of B to 0
img_B[81:110, 108:147, 2] = 0
ax3 = plt.subplot(223)
ax3.set_title('B')
plt.axis('off')
plt.imshow(img_B)

# display the raw image
ax4 = plt.subplot(224)
ax4.set_title('raw image')
plt.axis('off')
plt.imshow(img)
plt.show()


""" An example ICAP service that modifies response content.

Try visiting:

    $ export http_proxy=http://localhost:3128
    $ curl http://www.example.net/

And look for '
Modifed Example Domain
'

"""

import logging
from icapservice import ICAPService, OK

class Modify(ICAPService):

    abs_path = '/respmod'

    def RESPMOD(self, icap_request):
        http_response, chunks = icap_request.modify_http_response()
        return OK(http_response=http_response, chunks=self.modify_chunks(chunks))

    def modify_chunks(self, chunks):
        before  = 'Example Domain'
        after = before.replace('Example', 'Modified Example')
        for chunk in chunks:
            if before in chunk:
                chunk = chunk.replace(before, after)
            yield chunk

def main():
    logging.basicConfig(level=logging.INFO)
    Modify().icap_handler_class().server().serve_forever()

if __name__ == '__main__':
    main()


import dimod
import numpy as np

from src.linear_regression import build_precision_matrix, build_precision_two_complement_fixed_point, build_Q
from src.utils import load_dict, save_dict

def get_precision(num_bits: int, num_weights: int, point_position: float) -> None:
    save_dict(
        to_save={
            'precision': build_precision_matrix(
                num_weights=num_weights,
                precision=build_precision_two_complement_fixed_point(
                    num_bits=num_bits,
                    point_position=point_position
                )
            ).tolist()
        },
        output_file='precision_matrix.json'
    )

def get_problem_matrix(precision_matrix, preprocessed_dataset) -> None:
    precision = load_dict(precision_matrix)['precision']
    dataset = load_dict(preprocessed_dataset)
    precision = np.asarray(precision)
    x = np.asarray(dataset['x'])
    y = np.asarray(dataset['y'])

    save_dict(
        to_save={
            'q': build_Q(
                precision_matrix=precision,
                feature_matrix=x,
                target_matrix=y
            ).tolist()
        },
        output_file='q.json'
    )

def anneal(q, precision_matrix) -> None:
    q = np.asarray(
        load_dict(q)['q']
    )

    precision = load_dict(precision_matrix)['precision']
    precision = np.asarray(precision)

    array_bqm = dimod.AdjArrayBQM(q, 'BINARY')

    sample_set = dimod.SimulatedAnnealingSampler().sample(array_bqm)

    w_binary = np.asarray(list(sample_set.first.sample.values()))

    w_approx = precision.dot(w_binary)

    save_dict(
        {
            'solution': w_approx.tolist()
        },
        'solution.json'
    )


from PIL import Image
import PIL.ImageOps
from torchvision import transforms

tran = transforms.ToTensor()

images = ['1.jpeg', '2.jpeg', '3.jpeg', '4.jpeg',
          '5.jpeg', '6.jpeg', '7.jpeg', '8.jpeg', '9.jpeg']

# Para transformar la imagen a una escala de un solo color
rgb_weights = [0.2989, 0.5870, 0.1140]

# pred = np.argmax(model.predict(test))
# print('Predicted {}'.format(pred))

fig, axs = plt.subplots(nrows=3, ncols=3, figsize=(12, 4))
preds = []
for i, ax in enumerate(axs.flatten()):

  # Abrimos la imagen
  image1 = Image.open(images[i]).resize((28, 28), Image.ANTIALIAS)
  image1 = PIL.ImageOps.invert(image1)
  image_np = np.array(image1)
  image_np = np.dot(image_np[..., :3], rgb_weights)

  # Lo ponemos en formato para que lo entienda la red
  test = np.array([image_np]*128)
  test = tf.expand_dims(test, 3)
  plt.sca(ax)

  preds.append(model.predict(test)[0])
  plt.imshow(test[0].reshape(28, 28))
  plt.title('Predicted: {}'.format(np.argmax(preds[i])))

plt.suptitle('Predicciones')
plt.show()


import typing
from dataclasses import dataclass

from Cryptodome.Cipher import AES
from Cryptodome.Util import Counter

from bkcrypto import constants, types

from .. import configs, options
from . import base

@dataclass
class AESSymmetricRuntimeConfig(configs.BaseSM4SymmetricConfig, base.BaseSymmetricRuntimeConfig):

    mode_class: types.AESModeClass = None

    def __post_init__(self):
        super().__post_init__()

        if self.key_size not in AES.key_size:
            raise ValueError(f"Optional key sizes are {AES.key_size}, but got {self.key_size}")

        try:
            self.mode_class = {
                constants.SymmetricMode.CTR: AES.MODE_CTR,
                constants.SymmetricMode.CBC: AES.MODE_CBC,
                constants.SymmetricMode.GCM: AES.MODE_GCM,
                constants.SymmetricMode.CFB: AES.MODE_CFB,
            }[self.mode]

        except KeyError:
            raise ValueError(f"Unsupported mode: {self.mode}")

class AESSymmetricCipher(base.BaseSymmetricCipher):

    CIPHER_TYPE: str = constants.SymmetricCipherType.AES.value

    CONFIG_DATA_CLASS: typing.Type[AESSymmetricRuntimeConfig] = AESSymmetricRuntimeConfig

    OPTIONS_DATA_CLASS: typing.Type[options.AESSymmetricOptions] = options.AESSymmetricOptions

    config: AESSymmetricRuntimeConfig = None

    def get_block_size(self) -> int:
        return self.config.key_size

    def init_ctx(self, encryption_metadata: base.EncryptionMetadata):
        mode_init_args: typing.List[bytes] = []
        mode_init_kwargs: typing.Dict[str : typing.Any] = {}

        if self.config.enable_iv:
            if self.config.mode == constants.SymmetricMode.CTR:
                # Size of the counter block must match block size
                mode_init_kwargs["counter"] = Counter.new(
                    self.get_block_size() * 8, initial_value=int.from_bytes(encryption_metadata.iv, byteorder="big")
                )
            else:
                mode_init_args.append(encryption_metadata.iv)

        cipher_ctx = AES.new(self.config.key, self.config.mode_class, *mode_init_args, **mode_init_kwargs)
        if self.config.enable_aad:
            cipher_ctx.update(encryption_metadata.aad)

        return cipher_ctx

    def _encrypt(self, plaintext_bytes: bytes, encryption_metadata: base.EncryptionMetadata) -> bytes:

        cipher_ctx = self.init_ctx(encryption_metadata)

        if self.config.mode == constants.SymmetricMode.GCM:
            ciphertext_bytes, tag = cipher_ctx.encrypt_and_digest(plaintext_bytes)
            encryption_metadata.tag = tag
            return ciphertext_bytes
        else:
            return cipher_ctx.encrypt(plaintext_bytes)

    def _decrypt(self, ciphertext_bytes: bytes, encryption_metadata: base.EncryptionMetadata) -> bytes:

        cipher_ctx = self.init_ctx(encryption_metadata)

        if self.config.mode == constants.SymmetricMode.GCM:
            plaintext_bytes: bytes = cipher_ctx.decrypt_and_verify(ciphertext_bytes, encryption_metadata.tag)
            return plaintext_bytes
        else:
            return cipher_ctx.decrypt(ciphertext_bytes)


#!/usr/bin/env python3
import sys

assert sys.version_info >= (3,7), "This script requires at least Python 3.7"

print('Greetings!')
color = input("What is my favorite color? ")
print(color)

#Before running
''' This program is different from the last in two ways. First off
it actually stores my guess into a varible (color), but
then it also prints out what I guessed back out. I think the
color = input() will actually store what I type in unlike the last one
were it didn't have a variable to store it in.'''

#After running
'''The program did what I thought it was going to do, no suprises'''


# bullet.py
# 这个模块用来维护子弹类

import pygame

from math import *

from utility import globe
from render import cache
from object import item

global plpoint
played_se = False

class EnemyBullet(object):
    def __init__(self, bltype, orbit):
        self.bltype = bltype
        self.orbit = orbit
        self.ungrazed = True

class BulletType(object):
    def __init__(self, img, area):
        self.image = img
        self.area = area
        self.rect = img.get_rect()

def bl_inter_collide(embullet):
    global plpoint
    blpoint = embullet.orbit.point
    area = embullet.bltype.area

    # 类型自适应
    if type(area) == float or type(area) == int:
        if ((blpoint[0] - plpoint[0]) ** 2 + (blpoint[1] - plpoint[1]) ** 2) < area ** 2:
            return True
    else:
        theta = embullet.orbit.theta
        if type(area) == pygame.Rect:
            rctuple = (area.left, area.top, area.width, area.height)
        else:
            rctuple = area
        disx = plpoint[0] - blpoint[0]
        disy = plpoint[1] - blpoint[1]
        if abs(cos(theta / 180.0 * pi) * disx + sin(theta / 180.0 * pi) * disy) < rctuple[3] / 2 and abs(
                sin(theta / 180.0 * pi) * disx - cos(theta / 180.0 * pi) * disy) < rctuple[2] / 2:
            return True
    return False

def bl_inter_real_graze(embullet: EnemyBullet):
    # 疯狂擦弹的时候撞可能无 biu 音效, 所以控制每帧只播一次擦弹音效
    global played_se
    global plpoint
    globe.scgame.graze += 1
    globe.scgame.score += 200
    embullet.ungrazed = False
    if globe.scgame.player.status != globe.cstatus["hit"] and not played_se:
        globe.destiny.msManager.play_SE("graze")
        played_se = True
    # 显示擦弹特效
    if globe.scgame.player.status != globe.cstatus["hit"]:
        globe.scgame.anManager.grazeFX(plpoint[0], plpoint[1])

def bl_inter_check_graze(embullet: EnemyBullet):
    # 检测擦弹, 暂定 15 像素可以擦弹
    grazedis = 15
    global plpoint
    blpoint = embullet.orbit.point
    area = embullet.bltype.area

    # 根据子弹类型 (圆形/矩形) 进行对应检测
    if type(area) == float or type(area) == int:
        dis2 = (blpoint[0] - plpoint[0]) ** 2 + (blpoint[1] - plpoint[1]) ** 2
        if dis2 < (area + grazedis) ** 2:
            if embullet.ungrazed:
                bl_inter_real_graze(embullet)
        elif dis2 >= (area + (grazedis << 2)) ** 2:
            embullet.ungrazed = True
        return

    theta = embullet.orbit.theta
    if type(area) == pygame.Rect:
        rctuple = (area.left, area.top, area.width, area.height)
    else:
        rctuple = area

    disx = plpoint[0] - blpoint[0]
    disy = plpoint[1] - blpoint[1]
    left_right = cos(theta / 180.0 * pi) * disx + sin(theta / 180.0 * pi) * disy
    top_bottom = sin(theta / 180.0 * pi) * disx - cos(theta / 180.0 * pi) * disy
    if abs(left_right) < rctuple[3] / 2 + grazedis and abs(top_bottom) < rctuple[2] / 2 + grazedis:
        if embullet.ungrazed:
            bl_inter_real_graze(embullet)
    elif abs(left_right) >= rctuple[3] / 2 + (grazedis << 2) and abs(top_bottom) >= rctuple[2] / 2 + (grazedis << 2):
        embullet.ungrazed = True

def bl_inter_outscr(embullet):
    # 子弹出界
    blpoint = embullet.orbit.point
    if not globe.playrc.inflate(50, 50).collidepoint(blpoint):
        return True

class BulletManager(object):

    def __init__(self):
        self.time = 0

        self.plimg = []

        # 自机弹幕
        self.plimg.append(cache.cache_set_alpha(cache.cache_rotate(globe.destiny.rsManager.anime["ziji"][5], 90), 128))
        self.plimg.append(cache.cache_set_alpha(cache.cache_rotate(globe.destiny.rsManager.anime["ziji"][6], 90), 128))
        self.plimg.append(cache.cache_set_alpha(cache.cache_flip(self.plimg[1]), 128))

        self.plbullet = []  # (rect,id)
        self.plrc = self.plimg[0].get_rect()
        self.plspeed = 32

        self.enbullet = set()

        global plpoint
        plpoint = globe.scgame.player.point

    def create_plbl(self, point, bltype):
        tp = self.plrc.copy()
        tp.midbottom = point
        tp.top += self.plspeed
        self.plbullet.append((tp, bltype))

    def create_enbl(self, bltype, orbit):
        self.enbullet.add(EnemyBullet(bltype, orbit))

    def update(self):
        global played_se
        global plpoint
        enbl_tmp = []
        played_se = False
        for i in self.plbullet:
            i[0].top -= self.plspeed
            if i[0].bottom < globe.playrc.top:
                self.plbullet.remove(i)

        if globe.scgame.player.status == globe.cstatus["sc"]:
            for i in self.enbullet:
                i.orbit.update(i.bltype)
                if bl_inter_outscr(i):
                    enbl_tmp.append(i)
                bl_inter_check_graze(i)
        else:
            for i in self.enbullet:
                if bl_inter_collide(i):
                    enbl_tmp.append(i)
                    globe.scgame.player.hit()
                else:
                    i.orbit.update(i.bltype)
                    if bl_inter_outscr(i):
                        enbl_tmp.append(i)
                bl_inter_check_graze(i)

        for i in enbl_tmp:
            self.enbullet.remove(i)

        self.time += 1

    def draw(self, screen):
        for i in self.plbullet:
            screen.blit(self.plimg[i[1]], i[0])

        for i in self.enbullet:
            if i.orbit.theta != 0:
                tpimg = cache.cache_rotate(i.bltype.image, i.orbit.theta)
                tprc = tpimg.get_rect()
            else:
                tpimg = i.bltype.image
                tprc = tpimg.get_rect()
            tprc.center = i.orbit.point
            screen.blit(tpimg, tprc)

    def clear_enbl(self):
        for i in self.enbullet:
            globe.scgame.itManager.create(item.CleanBlItem, i.orbit.point)
        # 造成全局伤害
        for i in globe.scgame.enManager.enemy:
            if i.health * 0.2 <= 2000:
                i.health -= 2000
            else:
                i.health *= 0.8
        self.enbullet.clear()


import pandas as pd
import streamlit as st
import bcrypt
import os
import glob

st.set_page_config(
    page_title="PDF Annotator",
    page_icon="ðŸ“„",
)

if "project_loaded" not in st.session_state:
        st.session_state.project_loaded = False

#Loading project part
st.title("Label a project")
projects_info = pd.read_csv("./data/projects_info.csv")
st.write("Load project")
col1, col2, col3 = st.columns(3)
with col1:
    project_name = st.selectbox("Project name",projects_info["name"].unique(),index=None,label_visibility="collapsed")
with col2:
    username = st.text_input("Your username",label_visibility="collapsed",placeholder="Your username")
    if username and not username.isalpha():
        username = None
        st.error("Username not valid, please only use alpha character")
with col3:
    load_project_button = st.button("Load")

if load_project_button or st.session_state.project_loaded:
    if not project_name:
        st.error("Select a project")
    elif not username:
        st.error("Input an username")
    else:
        st.session_state.project_loaded = True
        project_papers_info = pd.read_csv(f'./data/{project_name.replace(" ","")}/papers_info.csv').dropna(subset='folds')
        folds = project_papers_info["folds"].unique()
        folds.sort()
        fold = st.selectbox("Fold",folds)
        with st.expander("More information"):
            add_info = projects_info[projects_info["name"] == project_name]["Additional information"].values[0]
            add_info = add_info.replace('""','"')
            add_info = add_info.replace(r'\n',"\n")
            st.write(add_info)

            if os.path.exists(f'./data/{project_name.replace(" ","")}/guide.pdf'):
                with open(f'./data/{project_name.replace(" ","")}/guide.pdf','rb') as guide_file:
                    st.download_button(label='Download Annotation Guide',
                                       data=guide_file,
                                       file_name=f'Guide_{project_name.replace(" ","")}.pdf',
                                       mime='application/octet-stream')
            else:
                st.write("No annotation guide available")

        #Try to load previous annotations
        if not os.path.exists(f'./data/{project_name.replace(" ","")}/annotations/{username}.csv'):
            st.info("New user for this project")
            with open(f'./data/{project_name.replace(" ","")}/annotations/{username}.csv',"w+") as annotation_file:
                annotation_file.write("doc_id,doc_name,label1,label2,value,comments")
        old_annotations = pd.read_csv(f'./data/{project_name.replace(" ","")}/annotations/{username}.csv')

        #Render PDF part
        papers = project_papers_info[project_papers_info["folds"] == fold]
        base_path = f'./data/{project_name.replace(" ","")}/pdfs/'
        index = st.number_input("Document id",min_value=0,max_value=len(papers)-1,value=st.session_state.get(f"{project_name}{username}{fold}",0),step=1,disabled=True)

        doc_id = papers.iloc[index]["index"]
        pdf_path = f"{base_path}file_{str(doc_id)}"
        with open(pdf_path) as pdf_file:
            base64_pdf = pdf_file.read()
            pdf_display = F'<iframe src="data:application/pdf;base64,{base64_pdf}#navpanes=0&scrollbar=0" width=100% height=700 type="application/pdf"></iframe>'
        pdf_display = st.markdown(pdf_display, unsafe_allow_html=True)

        if (old_annotations["doc_id"].isin([doc_id])).any():
            st.info("You've annotated this paper")
            labels1 = old_annotations[old_annotations["doc_id"] == doc_id]["label1"].unique()
        else:
            labels1= projects_info[projects_info["name"] == project_name]["labels1"].values[0].split(",")
        labels2 = projects_info[projects_info["name"] == project_name]["labels2"].values[0]
        if not pd.isna(labels2):
            labels2 = labels2.split(",")

            columns = ["label1"]
            columns.extend(labels2)
            lst_row = []
            for label in labels1:
                row = [label]
                for c in labels2:
                    if (old_annotations["doc_id"].isin([doc_id])).any():
                        old_value = old_annotations[old_annotations["doc_id"].isin([doc_id])]\
                            [(old_annotations["label1"].isin([label])) & (old_annotations["label2"].isin([c]))]["value"].values[0]
                        row.append(old_value)
                    else:
                        row.append(False)
                lst_row.append(row)

            annotations = pd.DataFrame(lst_row,columns=columns)
            annotations = annotations.sort_values(by=["label1"])
            annotations = annotations.set_index("label1")

            column_config={
                "label1": st.column_config.TextColumn("label1", default="")
            }
            for c in labels2:
                column_config[c]=st.column_config.CheckboxColumn(c,default=False)

            annotations = st.data_editor(annotations,num_rows="dynamic",column_config=column_config,use_container_width=True,hide_index=False)

            if (old_annotations["doc_id"].isin([doc_id])).any():
                text_save = "Update"
            else:
                text_save = "Save"

            col4,col5,col6 = st.columns(3)
            with col4:
                if index == 0:
                    disabled_previous = True
                else:
                    disabled_previous = False
                previous_button = st.button("Previous",disabled= disabled_previous)

            with col5:
                save_button = st.button(text_save)

            with col6:
                if index == len(papers)-1:
                    disabled_next = True
                else:
                    disabled_next = False
                next_button = st.button("Next",disabled= disabled_next)

            if save_button:
                #Remove old annotation:
                old_annotations = old_annotations[~old_annotations["doc_id"].isin([doc_id])]
                with open(f'./data/{project_name.replace(" ","")}/annotations/{username}.csv',"w") as annotation_user_file:
                    annotation_user_file.write("doc_id,doc_name,label1,label2,value")
                    doc_title = papers.iloc[index]["filename"]
                    for row in annotations.iterrows():
                        row_values = row[1]
                        for label2 in labels2:
                            line = f'\n{doc_id},{doc_title},{row[0]},{label2},{row_values[label2]}'
                            annotation_user_file.write(line)
                    annotation_user_file.write("\n")
                old_annotations[~old_annotations["doc_id"].isin([doc_id])].to_csv(f'./data/{project_name.replace(" ","")}/annotations/{username}.csv',mode="a",index=False,header=False)
                st.success("Annotation saved!")
                st.rerun()

            if next_button:
                st.session_state[f"{project_name}{username}{fold}"] = index + 1
                index = index + 1
                st.rerun()

            if previous_button:
                st.session_state[f"{project_name}{username}{fold}"] = index - 1
                index = index + 1
                st.rerun()

        else:
            columns = ["label1","selected"]
            lst_row = []
            if (old_annotations["doc_id"].isin([doc_id])).any():
                for label in labels1:
                    old_value = old_annotations[old_annotations["doc_id"].isin([doc_id])][(old_annotations["label1"].isin([label]))]["selected"].values[0]
                    row = [label,old_value]
                    lst_row.append(row)
            else:
                for label in labels1:
                    row = [label,False]
                    lst_row.append(row)

            annotations = pd.DataFrame(lst_row,columns=columns)
            annotations = annotations.sort_values(by=["label1"])
            annotations = annotations.set_index("label1")

            column_config={
                "label1": st.column_config.TextColumn("Label", default=""),
                "selected": st.column_config.CheckboxColumn("Selected",default=False),
            }
            annotations = st.data_editor(annotations,num_rows="dynamic",column_config=column_config,use_container_width=True,hide_index=True)
            if (old_annotations["doc_id"].isin([doc_id])).any():
                text_save = "Update"
            else:
                text_save = "Save"

            col4,col5,col6 = st.columns(3)
            with col4:
                if index == 0:
                    disabled_previous = True
                else:
                    disabled_previous = False
                previous_button = st.button("Previous",disabled= disabled_previous)

            with col5:
                save_button = st.button(text_save)

            with col6:
                if index == len(papers)-1:
                    disabled_next = True
                else:
                    disabled_next = False
                next_button = st.button("Next",disabled= disabled_next)

            if save_button:
                #Remove old annotation:
                old_annotations = old_annotations[~old_annotations["doc_id"].isin([doc_id])]
                with open(f'./data/{project_name.replace(" ","")}/annotations/{username}.csv',"w") as annotation_user_file:
                    annotation_user_file.write("doc_id,doc_name,label1,selected")
                    doc_title = papers.iloc[index]["filename"]
                    for row in annotations.iterrows():
                        row_values = row[1]
                        line = f'\n{doc_id},{doc_title},{row[0]},{row_values["selected"]}'
                        annotation_user_file.write(line)
                    annotation_user_file.write("\n")
                old_annotations[~old_annotations["doc_id"].isin([doc_id])].to_csv(f'./data/{project_name.replace(" ","")}/annotations/{username}.csv',mode="a",index=False,header=False)
                st.success("Annotation saved")
                st.rerun()

            if next_button:
                st.session_state[f"{project_name}{username}{fold}"] = index + 1
                index = index + 1
                st.rerun()

            if previous_button:
                st.session_state[f"{project_name}{username}{fold}"] = index - 1
                index = index + 1
                st.rerun()


"""
https://leetcode-cn.com/problems/smallest-rotation-with-highest-score/

给定一个数组 A，我们可以将它按一个非负整数 K 进行轮调，这样可以使数组变为 A[K], A[K+1], A{K+2], ... A[A.length - 1], A[0], A[1], ..., A[K-1] 的形式。此后，任何值小于或等于其索引的项都可以记作一分。

例如，如果数组为 [2, 4, 1, 3, 0]，我们按 K = 2 进行轮调后，它将变成 [1, 3, 0, 2, 4]。这将记作 3 分，因为 1 > 0 [no points], 3 > 1 [no points], 0 <= 2 [one point], 2 <= 3 [one point], 4 <= 4 [one point]。

在所有可能的轮调中，返回我们所能得到的最高分数对应的轮调索引 K。如果有多个答案，返回满足条件的最小的索引 K。

示例 1：
    输入：[2, 3, 1, 4, 0]
    输出：3
    解释：
        下面列出了每个 K 的得分：
        K = 0,  A = [2,3,1,4,0],    score 2
        K = 1,  A = [3,1,4,0,2],    score 3
        K = 2,  A = [1,4,0,2,3],    score 3
        K = 3,  A = [4,0,2,3,1],    score 4
        K = 4,  A = [0,2,3,1,4],    score 3
        所以我们应当选择 K = 3，得分最高。

示例 2：
    输入：[1, 3, 0, 2, 4]
    输出：0
    解释：
        A 无论怎么变化总是有 3 分。
        所以我们将选择最小的 K，即 0。

提示：
    A 的长度最大为 20000。
    A[i] 的取值范围是 [0, A.length]。

"""
from typing import List

""" 方法一：差分数组 """
class Solution:
    def bestRotation(self, nums: List[int]) -> int:
        n = len(nums)
        diffs = [0] * n
        for i, num in enumerate(nums):  # [1,2,3,5]
            low = (i + 1) % n
            high = (i - num + n + 1) % n
            diffs[low] += 1
            diffs[high] -= 1
            if low >= high:
                diffs[0] += 1
        print('diffs: ', diffs)
        score, maxScore, idx = 0, 0, 0
        for i, diff in enumerate(diffs):
            score += diff
            if score > maxScore:
                maxScore, idx = score, i
        return idx

class Solution:
    def bestRotation(self, nums: List[int]) -> int:
        n = len(nums)
        step = [0] * n
        for i, a in enumerate(nums):
            if a <= 0 or a >= n:    # 不满足条件的跳过
                continue
            left = i - (a - 1)
            right = i - (n - 1)
            print(i, a, left, right)
            step[left % n] -= 1
            step[right % n] += 1
        print(step)
        val, max_val, max_index = 0, - n - 1, -1
        for i in range(n):
            s = step[i]
            val += s
            if val > max_val:
                max_val = val
                max_index = i
        return max_index

if __name__ == "__main__":
    nums = [1,2,3,5]
    sol = Solution()
    result = sol.bestRotation(nums)
    print(result)

algorithms/01_数组 & 列表/差分数组/0798_得分最高的最小轮调.py

0798_得分最高的最小轮调.py


from math import ceil, floor

if __name__ == "__main__":
    n = int(input())
    a = list(map(int, input().split()))
    s = sum(a)
    avg = s / n
    res = 0
    if avg % 1 == 0:
        avg = int(avg)
        for val in a:
            res += abs(avg - val)
    else:
        m = s % n
        new = [ceil(s/n) for _ in range(m)] + [floor(s/n) for _ in range(n-m)]
        a.sort()
        new.sort()
        for i in range(n):
            res += abs(a[i] - new[i])
    res = res // 2
    print(res)


import sys, os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import time
from File_class import File_class

class ComputerTimePrint(QWidget):

    def __init__(self):
        super().__init__()
        self.dir_path = os.getcwd()
        self.now = time.localtime()
        self.init_the_file_class()
        self.init_the_list()
        self.start_time_comboBox_index = 0

        self.initUI()
        self.init_INFO()

    def init_the_file_class(self):
        self.Computer_name = File_class('Computer_name')
        self.Computer_start_time = File_class('Computer_start_time')
        self.Computer_end_time = File_class('Computer_end_time')
        self.Weekly_schedule = File_class('Weekly_schedule')
        self.Weekly_end_time = File_class('Weekly_end_time')
        self.Weekly_start_time = File_class('Weekly_start_time')

    def init_the_list(self):
        self.week = ('월', '화', '수', '목', '금', '토', '일')
        self.list_of_Computer_name = self.Computer_name.call_the_list()
        self.list_of_Computer_startTime =  self.Computer_start_time.call_the_list()
        self.list_of_Computer_endTime = self.Computer_end_time.call_the_list()
        self.list_of_schedule = self.Weekly_schedule.call_the_list()
        self.list_of_Weekly_endTime = self.Weekly_end_time.call_the_list()
        self.list_of_Weekly_startTime = self.Weekly_start_time.call_the_list()
        self.list_of_endTimeEdit = []
        self.list_of_startTimeEdit = []
        self.list_of_week = ["월요일", "화요일", "수요일", "목요일", "금요일", "토요일", "일요일"]
        self.list_of_week_checkBox = []

    def initUI(self):

        #요일 스케줄
        self.week_group = QGroupBox('전시장 운영 요일 설정')
        self.hbox = QHBoxLayout()
        self.vbox = QVBoxLayout()
        self.checkBox_group = QButtonGroup()
        self.checkBox_group.setExclusive(False)
        for i, v in enumerate(self.list_of_week):
            self.list_of_week_checkBox.insert(i, QCheckBox(f'{v}', self))
            self.hbox.addWidget(self.list_of_week_checkBox[i])
            self.checkBox_group.addButton(self.list_of_week_checkBox[i], i)
        self.vbox.addLayout(self.hbox)
        self.checkBox_save_btn = QPushButton('스케줄 저장',self)
        self.vbox.addWidget(self.checkBox_save_btn)
        self.week_group.setLayout(self.vbox)

        # 현재 스케줄
        self.computer_schedule_group = QGroupBox('컴퓨터 시작&종료 시간 설정')

        self.computer_schedule_text_label_name = QLabel('이름')
        self.computer_schedule_text_label_startTime = QLabel('시작시간')
        self.computer_schedule_text_label_endTime = QLabel('종료시간')
        self.computer_schedule_textEdit_name = QPlainTextEdit()
        self.computer_schedule_textEdit_startTime = QPlainTextEdit()
        self.computer_schedule_textEdit_endTime = QPlainTextEdit()

        self.computer_schedule_txt_grid = QGridLayout()
        self.computer_schedule_txt_grid.addWidget(self.computer_schedule_text_label_name, 0, 0)
        self.computer_schedule_txt_grid.addWidget(self.computer_schedule_text_label_startTime, 0, 1)
        self.computer_schedule_txt_grid.addWidget(self.computer_schedule_text_label_endTime, 0, 2)
        self.computer_schedule_txt_grid.addWidget(self.computer_schedule_textEdit_name, 1, 0)
        self.computer_schedule_txt_grid.addWidget(self.computer_schedule_textEdit_startTime, 1, 1)
        self.computer_schedule_txt_grid.addWidget(self.computer_schedule_textEdit_endTime, 1, 2)

        self.computer_schedule_combo = QComboBox()
        self.computer_schedule_combo.addItem('컴퓨터 목록')

        for i in self.list_of_Computer_name:
            self.computer_schedule_combo.addItem(i)

        self.computer_starttime_lineEdit = QLineEdit()
        self.computer_endtime_lineEdit = QLineEdit()

        self.computer_schedule_titleLabel = QLabel('────────────────컴퓨터 스케줄 변경────────────────')
        self.computer_schedule_titleLabel.setAlignment(Qt.AlignHCenter)
        self.computer_starttime_lineEdit.setPlaceholderText('시작 시간')
        self.computer_endtime_lineEdit.setPlaceholderText('종료 시간')
        self.computer_starttime_save_btn = QPushButton('저장', self)
        self.computer_starttime_save_btn.setEnabled(False)
        self.computer_schedule_txt_grid.addWidget(self.computer_schedule_titleLabel,2,0,3,3)
        self.computer_schedule_txt_grid.addWidget(self.computer_schedule_combo, 5,0)
        self.computer_schedule_txt_grid.addWidget(self.computer_starttime_lineEdit,5,1)
        self.computer_schedule_txt_grid.addWidget(self.computer_endtime_lineEdit,5,2)
        self.computer_schedule_txt_grid.addWidget(self.computer_starttime_save_btn,6,0,7,3)

        self.computer_schedule_group.setLayout(self.computer_schedule_txt_grid)

        # 전시장 시작시간 박스
        self.start_time_group = QGroupBox('전시장 시작 시간 설정 (Projector 일괄시작)')
        self.start_time_Grid = QGridLayout()

        for i, v in enumerate(self.week):
            tp = QLabel(v)
            self.start_time_Grid.addWidget(tp, 0, i)
            tp.setAlignment(Qt.AlignCenter)

        for i in range(0, 7):
            self.list_of_startTimeEdit.insert(i, QTimeEdit(self))
            self.start_time_Grid.addWidget(self.list_of_startTimeEdit[i], 1, i)
            self.list_of_startTimeEdit[i].setDisplayFormat('hh:mm')
            temp_startTime = self.list_of_Weekly_startTime[i].split(':')
            self.list_of_startTimeEdit[i].setTime(QTime(int(temp_startTime[0]), (int(temp_startTime[1]))))  # 리스트에 저장된 현재 설정을 세팅

        self.start_time_save_btn = QPushButton('저장', self)
        self.start_time_vLayout = QVBoxLayout()
        self.start_time_vLayout.addLayout(self.start_time_Grid)
        self.start_time_vLayout.addWidget(self.start_time_save_btn)
        self.start_time_group.setLayout(self.start_time_vLayout)

        # 전시장 마감시간 박스
        self.end_time_group = QGroupBox('전시장 마감 시간 설정 (PC & Projector 일괄종료)')
        self.end_time_Grid = QGridLayout()

        for i, v in enumerate(self.week):
            tp = QLabel(v)
            self.end_time_Grid.addWidget(tp, 0, i)
            tp.setAlignment(Qt.AlignCenter)

        for i in range(0, 7):
            self.list_of_endTimeEdit.insert(i, QTimeEdit(self))
            self.end_time_Grid.addWidget(self.list_of_endTimeEdit[i], 1, i)
            self.list_of_endTimeEdit[i].setDisplayFormat('hh:mm')
            temp_endTime = self.list_of_Weekly_endTime[i].split(':')
            self.list_of_endTimeEdit[i].setTime(QTime(int(temp_endTime[0]), (int(temp_endTime[1])))) #리스트에 저장된 현재 설정을 세팅

        self.end_time_save_btn = QPushButton('저장', self)
        self.vLayout = QVBoxLayout()
        self.vLayout.addLayout(self.end_time_Grid)
        self.vLayout.addWidget(self.end_time_save_btn)
        self.end_time_group.setLayout(self.vLayout)

        # activated.connect
        self.computer_schedule_combo.activated.connect(self.combo_changed)
        self.computer_starttime_save_btn.clicked.connect(self.computer_start_time_save_btn_clicked)
        self.end_time_save_btn.clicked.connect(self.end_time_save_btn_clicked)
        self.start_time_save_btn.clicked.connect(self.start_time_save_btn_clicked)
        self.checkBox_group.buttonClicked.connect(self.radioBtn_Clicked)
        self.checkBox_save_btn.clicked.connect(self.radioBtn_saveBtn_Clicked)

        #전체 구조
        self.layout = QGridLayout()
        self.layout.addWidget(self.week_group,0, 0)
        self.layout.addWidget(self.computer_schedule_group, 1, 0)
        self.layout.addWidget(self.start_time_group, 2, 0)
        self.layout.addWidget(self.end_time_group, 3, 0)
        self.setLayout(self.layout)

    def init_INFO(self):
        self.computer_schedule_textEdit_name.setPlainText(self.Computer_name.read_the_list())
        self.computer_schedule_textEdit_startTime.setPlainText(self.Computer_start_time.read_the_list())
        self.computer_schedule_textEdit_endTime.setPlainText(self.Computer_end_time.read_the_list())
        for i, v in enumerate(self.list_of_schedule):
            if int(v) == 2:
                self.list_of_week_checkBox[i].setCheckState(2) #2가 갈매기표임

    def combo_changed(self, index):
        if not index == 0:
            self.computer_starttime_save_btn.setEnabled(True)
            self.computer_starttime_lineEdit.setInputMask('99:99:99; ')
            self.computer_endtime_lineEdit.setInputMask('99:99:99; ')
            self.start_time_comboBox_index = index

    def computer_start_time_save_btn_clicked(self):
        start_time = str(self.computer_starttime_lineEdit.text()) #착각하면 안된다. 여기서 나오는 반환값은 String이 아니라 QString이다... #temp = int(name[0])  #Qstring을 int로 바꾼다. #7/19 여기 수정해야됨. 10이 1로되는현상. #7/25 수정함 전역변수를 사용해서
        end_time = str(self.computer_endtime_lineEdit.text())
        index = self.start_time_comboBox_index - 1
        start_time.replace(" ", "")
        end_time.replace(" ", "")
        self.Computer_start_time.save_the_list(index, start_time)
        self.Computer_end_time.save_the_list(index, end_time)
        self.init_INFO()

    def end_time_save_btn_clicked(self):
        tempList = []
        for i in range(0,7):
            tempList.append(self.list_of_endTimeEdit[i].text())
        with open(f'{self.dir_path}\\txt\\Weekly_end_time.txt', 'w', encoding='UTF8') as fp:
            for i in tempList:
                data = str(i)
                fp.write(data + '\n')

    def start_time_save_btn_clicked(self):
        tempList = []
        for i in range(0, 7):
            tempList.append(self.list_of_startTimeEdit[i].text())
        with open(f'{self.dir_path}\\txt\\Weekly_start_time.txt', 'w', encoding='UTF8') as fp:
            for i in tempList:
                data = str(i)
                fp.write(data + '\n')

    def radioBtn_Clicked(self):
        tempList = []
        for cb in self.list_of_week_checkBox:
            tempList.append(cb.checkState())
        self.list_of_schedule = tempList

    def radioBtn_saveBtn_Clicked(self):
        with open(f'{self.dir_path}\\txt\\Weekly_schedule.txt', 'w', encoding='UTF8') as fp:
            for i in self.list_of_schedule:
                data = str(i) #str을 붙여줘야한다. 왜냐하면 저 스케쥴 리스트에 든 0은 null로 간주하기 때문이다.
                fp.write(data + '\n')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ComputerTimePrint()
    sys.exit(app.exec_())


from art import logo

alphabet = [
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
    'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
]

def caesar(start_text, shift_amount, cipher_direction):
    end_text = ""
    if cipher_direction == "decode":
        shift_amount *= -1
    for char in start_text:
        if char in alphabet:
            position = alphabet.index(char)
            new_position = (position + shift_amount)%26
            end_text += alphabet[new_position]
        else:
            end_text += char
    print(f"Here's the {cipher_direction}d result: {end_text}")

# # # # # # # # # # # # # # # # # # # # # # # # #
print(f"\u001b[33m{logo}\u001b[0m")

restart = True
while restart == True:
    direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n")
    text = input("Type your message:\n").lower()
    shift = int(input("Type the shift number:\n"))
    if shift%26 == 0:
      print("-Number must not be multiple of 26 or you're going to get the same message.\n")
    caesar(start_text=text, shift_amount=shift, cipher_direction=direction)
    answer = input("Do you want to restart the program? (y/n) \n")
    if answer == "n":
      restart = False
      print("GoodBye :)")


import torch
import numpy as np
import random
import argparse
import os
import sys
import time
from datetime import datetime
import yaml
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torch.utils.data.sampler import SubsetRandomSampler
from torch.optim.lr_scheduler import StepLR, MultiStepLR
from tqdm import tqdm

from project_code.models.deepLab.deeplab import DeepLab
from project_code.loss import get_loss_function
from project_code.metrics.metrics import Metrics
from project_code.saver.saver import ModelSaver, ImgSaver, ArraySaver
from project_code.utils.utils import pretty_print, save_string
from project_code.optimizer import get_optimizer
from project_code.dataloader.get_loaders import LoaderGetter
from project_code.dataloader.utils import decode_seg_map_sequence
from homography.EM import EM

class Trainer():
    def __init__(self, options):
        random_seed = options['training']['random_seed']
        np.random.seed(random_seed)
        random.seed(random_seed)
        torch.manual_seed(random_seed)

        self.options =  options
        self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

        self.logdir = os.path.join('runs', 'normal')#datetime.now().strftime('%Y-%m-%d_%H:%M'))
        self.writer = SummaryWriter(self.logdir)
        options_string = pretty_print(options)
        print(options_string)
        save_string(options_string, self.logdir)

        self.model = DeepLab(options).to(self.device)
        #print(model)

        self.model = torch.nn.DataParallel(self.model, device_ids=range(torch.cuda.device_count()))
        self.model_saver = ModelSaver(options)
        self.model, self.epoch, self.best_acc, self.scheduler, self.optimizer = self.model_saver.load_model(self.model)
        self.optimizer = get_optimizer(options, self.model.parameters()) if self.optimizer is None else self.optimizer
        self.scheduler = StepLR(self.optimizer, step_size=1,
                        gamma=options['training']['scheduler']['gamma']) if self.scheduler is None else self.scheduler
        self.criterion = get_loss_function()
        self.evaluator = Metrics(options['data']['num_classes'])

        #print("Total number of parameters:", sum(p.numel() for p in self.model.parameters())/1e6, "M")

        self.validation_folder = 'MVI_4627.MP4'
        self.loader_getter = LoaderGetter(options, specific_folders={'val': self.validation_folder})
        self.img_saver = ImgSaver()
        self.step = int(self.epoch*self.loader_getter.get_size('train')/options['training']['batch_size'])

    def validate(self):
        self.model.eval()
        self.evaluator.reset()
        evaluator2 = Metrics(options['data']['num_classes'])
        evaluator_vp = Metrics(options['data']['num_classes'])
        evaluator_vp.reset()
        post = EM(options['data']['root'], self.validation_folder)
        array_saver = ArraySaver()
        val_loader = self.loader_getter('val')
        loss = []
        #out_list = []
        #av_length = 5
        accuracy, accuracy_post, accuracy_vp = [], [], []
        names = []
        with torch.no_grad():
            for b,batch in tqdm(enumerate(val_loader)):
                evaluator2.reset()
                self.evaluator.reset()
                evaluator_vp.reset()

                name = batch['name'][0]

                # if name not in ['687.png', '205.png', '867.png', '1008.png', '777.png']:
                #     continue

                image = batch['image'].to(self.device)
                gt = batch['ground_truth'].to(self.device)

                skip_model = True

                if skip_model:
                    with open(os.path.join('data/results', 'segmentation_probs', self.validation_folder, name + '.npy'), 'rb') as f:
                        pred = np.load(f)
                else:
                    out = self.model(image)
                    loss.append(self.criterion(out, gt).item())

                    pred = out.data.cpu().numpy()
                    array_saver(pred, batch['name'][0] + '.npy', folder=os.path.join('segmentation_probs', self.validation_folder))

                gt = gt.cpu().numpy()
                pred0 = np.argmax(pred, axis=1)
                self.evaluator.add_batch(gt, pred0)
                pred0 = decode_seg_map_sequence(pred0)
                # decoded_gt = decode_seg_map_sequence(gt)
                self.img_saver(pred0[0], batch['name'][0], folder=os.path.join('segmentation_raw', self.validation_folder))

                start_time = time.time()
                skip_post = False

                if skip_post:
                    with open(os.path.join('data/results', 'polygons', self.validation_folder, name), 'rb') as f:
                        polygons = np.load(f)
                        face_labels = np.load(f)
                else:
                    polygons,face_labels = post.EM(pred[0])
                    array_saver(polygons, batch['name'][0] + '.npy', folder=os.path.join('polygons', self.validation_folder), array1=face_labels)
                pred_post = post.get_segmentation_output(polygons, face_labels)
                pred_post = np.expand_dims(pred_post, axis=0)
                evaluator2.add_batch(gt, pred_post)
                #evaluator2.add_time(time.time() - start_time)

                #or i,o in enumerate(out):
                pred_post = decode_seg_map_sequence(pred_post)
                self.img_saver(pred_post[0], batch['name'][0], folder=os.path.join('segmentation_post', self.validation_folder))

                t2 = time.time()

                print('post time', t2 - start_time)

                skip_vp = False

                if skip_vp:
                    with open(os.path.join('data/results', 'polygons_vp', self.validation_folder, name), 'rb') as f:
                        new_polygons = np.load(f)
                        face_labels = np.load(f)
                else:
                    new_polygons = post.opt_vp(polygons, face_labels, pred[0])
                pred_post = post.get_segmentation_output(new_polygons, face_labels)
                pred_post = np.expand_dims(pred_post, axis=0)
                evaluator_vp.add_batch(gt, pred_post)
                evaluator_vp.add_time(time.time() - start_time)

                #or i,o in enumerate(out):
                pred_post = decode_seg_map_sequence(pred_post)

                #for i,p in enumerate(pred1):
                #     #nb = b*options['training']['batch_size'] + i
                self.img_saver(pred_post[0], batch['name'][0], folder=os.path.join('segmentation_vp', self.validation_folder))
                array_saver(new_polygons, batch['name'][0] + '.npy', folder=os.path.join('polygons_vp', self.validation_folder), array1=face_labels)

                print('vp time', t2 - time.time())

                accuracy.append(self.evaluator.Pixel_Accuracy())
                accuracy_post.append(evaluator2.Pixel_Accuracy())
                accuracy_vp.append(evaluator_vp.Pixel_Accuracy())
                #self.best_acc = max(accuracy, self.best_acc)
                # print_string = 'VALIDATION: Step {} Loss {:.2f} Accuracy {:.2f}%'.format(self.step,
                #                 sum(loss)/len(loss), accuracy*100)
                #print(print_string)
                #avg_time = evaluator_vp.get_average_time()
                print("Name {} First Accuracy {:.2f} Post Accuracy {:.2f} VP Accuracy {:.2f}".format(name ,accuracy[-1]*100, accuracy_post[-1]*100, accuracy_vp[-1]*100))
                names.append(name)
                if b % 10 == 0:
                    print("Overall scores: First Accuracy {:.4f} Post Accuracy {:.4f} VP Accuracy {:.4f}".format(sum(accuracy)/len(accuracy)*100,
                                                                                sum(accuracy_post)/len(accuracy_post)*100, sum(accuracy_vp)/len(accuracy_vp)*100))
        #save_string(print_string, self.logdir)

        print("Overall scores: First Accuracy {:.4f} Post Accuracy {:.4f} VP Accuracy {:.4f}".format(sum(accuracy)/len(accuracy)*100,
                                                                                sum(accuracy_post)/len(accuracy_post)*100, sum(accuracy_vp)/len(accuracy_vp)*100))
        self.evaluator.reset()

        acc_performance = [vp - post for post,vp in zip(accuracy_post, accuracy_vp)]
        names = [n for a,n in sorted(zip(acc_performance, names))]
        acc_performance = sorted(acc_performance)
        for name,p in zip(names, acc_performance):
            print(name, p)

    def train(self):
        while True:
            print()
            print("Start epoch {}".format(self.epoch))

            train_loader = self.loader_getter('train')
            self.evaluator.reset()

            for b,batch in enumerate(train_loader):
                if len(batch['image']) != self.options["training"]["batch_size"]:#is this even necessary?
                    break
                start_time = time.time()

                image = batch['image'].to(self.device)
                gt = batch['ground_truth'].to(self.device)

                self.model.train()

                # Predict with model
                out = self.model(image)
                loss = self.criterion(out, gt)

                # Do backprop
                self.optimizer.zero_grad()
                loss.backward()
                self.optimizer.step()

                # Add batch to evaluator
                pred = out.data.cpu().numpy()
                gt = gt.cpu().numpy()
                pred = np.argmax(pred, axis=1)
                self.evaluator.add_batch(gt, pred)
                self.evaluator.add_time(time.time() - start_time)

                # pred = decode_seg_map_sequence(pred)
                # for i,p in enumerate(pred):
                #     nb = b*options['training']['batch_size'] + i
                #     self.img_saver(p.permute(2,1,0), batch['name'][i] + '.png', folder='train')

                self.step += 1
                if self.step % self.options['training']['print_interval'] == 0:
                    accuracy = self.evaluator.Pixel_Accuracy()
                    avg_time = self.evaluator.get_average_time()/self.options['training']['batch_size']
                    print_string = 'Step {} Time per image {:.2f} Loss {:.2f} Accuracy {:.2f}%'.format(self.step,
                         avg_time, loss, accuracy*100)
                    print(print_string)
                    save_string(print_string,self.logdir)

                #if self.step % self.options['training']['val_interval'] == 0:
                #     self.model_saver.save_model(self.model, self.epoch)

            self.scheduler.step()

            self.model_saver.save_model(self.model, self.epoch, self.best_acc, self.scheduler, self.optimizer)
            #self.validate()

            self.epoch += 1
            if self.epoch == self.options['training']['total_epochs']:
                print('Last epoch reached')
                break

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="config")
    parser.add_argument(
        "--config",
        nargs="?",
        type=str,
        default="yo",
        help="Configuration file to use",
    )

    args = parser.parse_args()
    args.config = os.path.join("configs", args.config + ".yml")

    with open(args.config) as fp:
        options = yaml.load(fp)

    if options["gpu_id"] is not None:
        os.environ["CUDA_VISIBLE_DEVICES"] = str(options["gpu_id"])

    trainer = Trainer(options)
    trainer.validate()


#!flask/bin/python
import logging
import sys
import json

from flask import Flask
from flask_restplus import Api
from webargs.flaskparser import parser, abort
from flask_cors import CORS

from common.util import parse_config
from common.util import ConfigException

from v1.api.retrieve import RetrieveAPI as RetrieveAPIv1
from adapters.G2Adapter import G2Adapter

ENDPOINTS = {
    "gd2": 'gd2.mlb.com/components/'
}

def setup_adapters(config):
    adapters = dict()
    logging.debug(config['main']['mlb_endpoint'])
    adapters['gamefeed_adapter'] = G2Adapter(ENDPOINTS[config['main']['mlb_endpoint']])

    return adapters

def run_server(config):
    app = Flask(__name__)
    api = Api(app)
    if config['main']['enable_cors']:
        logging.info("Enabling CORS for all routes")
        CORS(app)

    adapters = setup_adapters(config)

    api.add_resource(RetrieveAPIv1, '/v1/retrieve', '/retrieve', endpoint='v1_retrieve',
                     resource_class_kwargs={'gamefeed_adapter': adapters['gamefeed_adapter']})
    app.run(host='0.0.0.0', port=config['main']['port'], debug=config['main']['debug'])

@parser.error_handler
def handle_request_parsing_error(err, req, schema):
    try:
        json.loads(req.data)
    except ValueError:
        abort(422, error="The request parameters or data violated the schema", schema=str(err))
    abort(422, errors=err.messages)

def main():
    logging.basicConfig(level=logging.DEBUG)

    if len(sys.argv) != 2:
        raise ConfigException("You must specify a config file as a command-line argument")

    config_file = sys.argv[1]
    config = parse_config(config_file)

    run_server(config)

if __name__ == "__main__":
    main()


import cv2
import numpy as np
from pypylon import pylon

def search_get_device():
    tl_factory = pylon.TlFactory.GetInstance()
    camera_list = []
    for dev_info in tl_factory.EnumerateDevices():

        if dev_info.GetDeviceClass() == 'BaslerGigE':
            camera = pylon.InstantCamera(tl_factory.CreateDevice(dev_info))
            camera_list.append(camera)
    if len(camera_list) > 0:

        return camera_list
    else:
        raise EnvironmentError("no GigE device found")

def grab_img_realtime(camera):
    converter = pylon.ImageFormatConverter()
    # converting to opencv bgr format
    converter.OutputPixelFormat = pylon.PixelType_BGR8packed
    converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned
    camera.Open()
    camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
    while camera.IsGrabbing():
        grabResult = camera.RetrieveResult(1000, pylon.TimeoutHandling_ThrowException)
        if grabResult.GrabSucceeded():
            # Access the image data
            image = converter.Convert(grabResult)
            img = image.GetArray()
            # cv2.namedWindow('title', cv2.WINDOW_NORMAL)
            # cv2.imshow('title', img)
            # k = cv2.waitKey(1)
            # if k == 27:
            #     break
        grabResult.Release()