from flask import render_template, request
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder import ModelView, BaseView, expose
from app import appbuilder, db
#from .helpers import upload_ewd, upload_correspondence,create_file_list
from flask_appbuilder.models.sqla.filters import FilterStartsWith, FilterEqualFunction, FilterEqual, FilterNotContains

from datetime import timedelta
"""
    DRASS Comments View Section
"""
from flask_appbuilder.baseviews import BaseView, expose
from flask_appbuilder import ModelView, action, MasterDetailView, MultipleView
from flask_appbuilder.models.sqla.interface import SQLAInterface
#from flask import render_template, request
#from app.models import Document, Revision, Commentsheet, Comment, Dedoc, Moc,Discipline, Unit, SplitOfWorks, Actionrequired, Issuetype
from app.models import (Disciplinedras, Mocmodel, Dedocmodel, Unitmodel,
                        Splitofworks, Drasdocument, Drasrevision, Drasissuetype,
                        Drasactionrequired, Drascommentsheet, Drascomment,
                        Tagdiscipline, Drasvendor, Drasmr)

#from app import appbuilder, db
from app.comments.helpers import check_labels, get_data_from_cs
from flask import session, redirect, url_for, abort
from app.comments.customWidgets import commentListWidget, RevisionListCard
from flask_appbuilder.widgets import ListBlock
from app.comments.helpers import update_data_from_cs, update_vendor_data_from_cs, update_all_YF, piero_items
#from app.comments.ListeXLSX.helpers import add_moc, add_unit
#import app.comments.ListeXLSX.helpers
from flask_babel import lazy_gettext
from app.init_helpers import init_dras

#from app.init_helpers import fakeItem3

'''
from app.comments.views import (DocumentView, RevisionView, CommentSheetView,
                                CommentView, DrasUploadView, DEDOperatingCenterView,
                                MainOperatingCenterView, DEDOperatingCenterView, UnitView,
                                SowView, IssueTypeView, ActionRequiredView)
'''

"""
    Early Works View Section
"""

class MidorDrasDashboardView(BaseView):
    default_view = 'dash_dras'
    @expose('/dash_dras', methods=['POST', 'GET'])
    def dash_dras(self):
        return self.render_template('dash_dras.html')

class MidorDras2DashboardView(BaseView):
    default_view = 'dash_dras'
    @expose('/dash_dras', methods=['POST', 'GET'])
    def dash_dras(self):
        return self.render_template('dash_dras2.html')

class MidorDras3DashboardView(BaseView):
    default_view = 'dash_dras'
    @expose('/dash_dras', methods=['POST', 'GET'])
    def dash_dras(self):
        return self.render_template('dash_dras3.html')

class MidorDras4DashboardView(BaseView):
    default_view = 'dash_dras'
    @expose('/dash_dras', methods=['POST', 'GET'])
    def dash_dras(self):
        return self.render_template('dash_dras4.html')

class MidorDras5DashboardView(BaseView):
    default_view = 'dash_dras'
    @expose('/dash_dras', methods=['POST', 'GET'])
    def dash_dras(self):
        return self.render_template('dash_dras5.html')

class UnitView(ModelView):
    datamodel = SQLAInterface(Unitmodel)
    #related_views = [CommentSheetView, RevisionView, CommentView]
    #show_template = 'appbuilder/general/model/show_cascade.html'

    list_columns = ['name','code','moc', 'dedoc']
    label_columns = {
        'moc':'Main OC',
        'dedoc':'DED OC',
        'name': 'Title',
        'code': 'Unit'
    }

class DEDOperatingCenterView(ModelView):
    datamodel = SQLAInterface(Dedocmodel)
    #related_views = [CommentSheetView, RevisionView, CommentView]
    #show_template = 'appbuilder/general/model/show_cascade.html'

    list_columns = ['name','moc']
    label_columns = {
        'moc':'MOC',
        'name': 'Name'
    }

class MainOperatingCenterView(ModelView):
    datamodel = SQLAInterface(Mocmodel)
    #related_views = [DEDOperatingCenterView]
    show_template = 'appbuilder/general/model/show_cascade.html'

    list_columns = ['name','created_on','created_by']

class DisciplineView(ModelView):
    datamodel = SQLAInterface(Disciplinedras)
    #related_views = [CommentSheetView, RevisionView, CommentView]
    #show_template = 'appbuilder/general/model/show_cascade.html'

    list_columns = ['name','created_on','created_by']

class SowView(ModelView):
    datamodel = SQLAInterface(Splitofworks)
    #related_views = [CommentSheetView, RevisionView, CommentView]
    #show_template = 'appbuilder/general/model/show_cascade.html'

    list_columns = ['unitmodel.code','unitmodel.name','disciplinedras.name','oc.moc','oc']
    show_columns = ['unitmodel.code','unitmodel.name','disciplinedras.name','oc.moc','oc']
    edit_columns = ['oc']
    #add_columns = ['unitmodel.code','unitmodel.name','disciplinedras.name','oc.moc','oc']

    label_columns = {
        'unitmodel.name':'Unit Title',
        'unitmodel.code':'Unit',
        'disciplinedras.name': 'Discipline',
        'oc': 'DED OC',
        'oc.moc': 'MAIN OC'
    }

    @action("muldelete", "Delete", "Delete all Really?", "fa-rocket")
    def muldelete(self, items):
        if isinstance(items, list):
            self.datamodel.delete_all(items)
            self.update_redirect()
        else:
            self.datamodel.delete(items)
        return redirect(self.get_redirect())

class IssueTypeView(ModelView):
    datamodel = SQLAInterface(Drasissuetype)
    list_columns = ['name']

class ActionRequiredView(ModelView):
    datamodel = SQLAInterface(Drasactionrequired)
    list_columns = ['name']

class CommentSheet2View(ModelView):
    datamodel = SQLAInterface(Drascommentsheet)
    list_title = 'List Current DRAS'
    search_columns = [
                        'documentReferenceDoc',
                        'contractorTransmittalMr',
                        'contractorTransmittalVendor',
                        'contractorTransmittalReference',
                        'documentReferenceBy'
                        ]
    list_columns = ['document_link','drasrevision','stage_icon','contractorTransmittalMr', 'download']
    label_columns = {
        'documentReferenceDoc':     'Document',
        'documentReferenceRev':     'Revision',
        'documentReferenceDesc':    'Description',
        'documentReferenceBy':      'Discipline',

        'ownerTransmittalReference':'ID',
        'ownerTransmittalDate':     'Date',
        'response_status':          'Status',

        'contractorTransmittalReference':   'Transmittal',
        'contractorTransmittalDate':        'Date',
        'contractorTransmittalMr':          'MR',
        'contractorTransmittalVendor':      'Vendor',
        'stage_icon':'Stage',

        'issuetype':                'Issue Type',
        'actionrequired':           'Action Required',
        'notificationItem':         'Notification Item',
        'actualDate':               'Actual Date',
        'expectedDate':             'Expected Date',
        'plannedDate':              'Planned Date',
        'drasdocument':             'Document',
        'drasrevision':             'Revision',
        'drasvendor':               'Vendor',
        'drasmr':                   'Material Requisition'
    }
    base_filters = [['current', FilterEqual,1]]
    edit_exclude_columns = ['created_by', 'changed_by']
    show_exclude_columns = ['created_by', 'changed_by']

class CommentView(ModelView):
    datamodel = SQLAInterface(Drascomment)
    list_columns = ['tag','ownerCommentComment','contractorReplyStatus','contractorReplyComment','ownerCounterReplyComment','finalComment', 'commentStatus', 'pos']
    show_title = 'Show Comment'
    list_title = 'List Comments'
    add_title = 'Add Comment'
    edit_title = 'Edit Comment'
    search_columns = ['commentStatus']
    list_widget = commentListWidget
    label_columns = {
        'ownerCommentBy': 'by',
        'ownerCommentDate': 'Date',
        'ownerCommentComment': 'Owner:',

        'contractorReplyDate': 'Date',
        'contractorReplyStatus': 'Status',
        'contractorReplyComment': 'Contractor:',

        'ownerCounterReplyDate': 'Date',
        'ownerCounterReplyComment' : 'Owner:',

        'finalAgreementDate': 'Agreement Date',
        'finalAgreemntCommentDate':'Comment Date',
        'finalAgreementComment': 'Agreement:',
        'commentStatus': 'Status'

    }

    show_fieldsets = [
        (lazy_gettext('DRAS Comment'),

         {'fields': ['pos', 'tag', 'info']}),

        (lazy_gettext('Owner Comment'),

         {'fields': ['ownerCommentBy',
                    'ownerCommentDate',
                    'ownerCommentComment'], 'expanded': True}),

        (lazy_gettext('Contractor Reply'),

         {'fields': ['contractorReplyDate',
                    'contractorReplyStatus',
                    'contractorReplyComment'],
                    'expanded': False}),

        (lazy_gettext('Owner Counter Reply'),

         {'fields': ['ownerCounterReplyDate',
                    'ownerCounterReplyComment',],
                    'expanded': False}),

        (lazy_gettext('Final Agreement'),

         {'fields': ['finalAgreementDate',
                    'finalAgreemntCommentDate',
                    'finalAgreementComment',
                    'commentStatus'], 'expanded': False}),

    ]

    @action("muldelete", "Delete", "Delete all Really?", "fa-rocket")
    def muldelete(self, items):
        if isinstance(items, list):
            self.datamodel.delete_all(items)
            self.update_redirect()
        else:
            self.datamodel.delete(items)
        return redirect(self.get_redirect())

class CommentSheetView(ModelView):
    datamodel = SQLAInterface(Drascommentsheet)
    related_views = [CommentView]
    add_title = 'View DRAS'
    edit_title = 'Edit DRAS'
    edit_exclude_columns = ['cs_file']
    list_title = 'List DRAS History'
    show_title = 'Show DRAS'
    add_columns = ['cs_file', 'current']
    order_columns = ['actualDate']
    base_order = ('actualDate','asc')
    search_columns = [
                        'documentReferenceDoc',
                        'contractorTransmittalMr',
                        'contractorTransmittalVendor',
                        'contractorTransmittalReference',
                        'stage',
                        'note'
                        ]

    list_columns = ['drasdocument','drasrevision','stage_icon','actualDate','expectedDate','notificationItem', 'is_current', 'download']
    label_columns = {
        'open_comments': 'Open',
        'documentReferenceDoc':     'Document',
        'documentReferenceRev':     'Revision',
        'documentReferenceDesc':    'Description',
        'documentReferenceBy':      'Discipline',

        'ownerTransmittalReference':'ID',
        'ownerTransmittalDate':     'Date',
        'response_status':          'Status',

        'contractorTransmittalReference':   'Transmittal',
        'contractorTransmittalDate':        'Date',
        'contractorTransmittalMr':          'MR',
        'contractorTransmittalVendor':      'Vendor',
        'stage_icon':'Stage',

        'issuetype':                'Issue Type',
        'actionrequired':           'Action Required',
        'notificationItem':         'Notification Item',
        'actualDate':               'Actual Date',
        'expectedDate':             'Expected Date',
        'plannedDate':              'Planned Date',
        'drasdocument':             'Document',
        'drasrevision':             'Revision',
        'drasvendor':               'Vendor',
        'drasmr':                   'Material Requisition'
    }

    show_fieldsets = [
        (lazy_gettext('DRAS Info'),

         {'fields': ['drasdocument', 'drasrevision', 'stage_icon']}),

        (lazy_gettext('Document Reference'),

         {'fields': [
                    'documentReferenceDesc',
                    'documentReferenceBy',
                    'drasvendor','drasmr',
                    'contractorTransmittalReference',
                    ], 'expanded': True}),

        (lazy_gettext('DRAS Notification'),

         {'fields': ['notificationItem',
                    'issuetype',
                    'actualDate',
                    'expectedDate','actionrequired',
                    'response_status'], 'expanded': True}),

        (lazy_gettext('DRAS Internal Info'),

         {'fields': ['note'],
                    'expanded': False}),
    ]

    edit_fieldsets = [

        (lazy_gettext('DRAS Notification'),

         {'fields': ['notificationItem',
                    'actualDate',
                    'issuetype',
                    'actionrequired'], 'expanded': True}),

        (lazy_gettext('DRAS Internal Info'),

         {'fields': ['note'],
                    'expanded': False}),
    ]
    add_fieldsets = [
        (lazy_gettext('DRAS File'),
         {'fields': ['cs_file','current']}),

        (lazy_gettext('DRAS Notification'),
         {'fields': ['issuetype',
                    'actionrequired',
                    'notificationItem',
                    'actualDate',
                    'expectedDate',
                    'plannedDate'], 'expanded': True}),

        (lazy_gettext('DRAS Material Requisition'),

         {'fields': ['drasvendor','drasmr',], 'expanded': True}),

        (lazy_gettext('DRAS Internal Info'),
         {'fields': ['note'],
                    'expanded': False}),

    ]
    #related_views = [CommentView]
    #show_template = 'appbuilder/general/model/show_cascade.html'

    @action("muldelete", "Delete", "Delete all Really?", "fa-rocket")
    def muldelete(self, items):
        if isinstance(items, list):
            self.datamodel.delete_all(items)
            self.update_redirect()
        else:
            self.datamodel.delete(items)
        return redirect(self.get_redirect())

    @action("updatecomments", "Update Comments", "Upload all comments?", "fa-rocket", multiple=False)
    def setcurrent(self, items):
        item = items

        update_vendor_data_from_cs(item)
        #print(session)

        #return redirect(self.get_redirect())
        return redirect(url_for('DrasdocumentView.show', pk=item.drasdocument_id))

    def pre_add(self, item):

        # Check File Requirements
        check_labels(item)
        doc = get_data_from_cs(item)

        #session['last_document'] = doc
        #print('PRE ADD FUNCTION ************ ',session['last_document'] )

        if doc == False:
            return abort(400, 'Pre Add Function Error.')

    def pre_update(self, item):
        indoor = ['Y','Y2']
        outdoor = ['S','Y1','Y3']

        if item.stage in indoor:
            item.expectedDate = item.actualDate + timedelta(days=7)
        if item.stage in outdoor:
            item.expectedDate = item.actualDate + timedelta(days=14)

        # Find or Create Document
        # Find or Create Revision
    '''
    def post_add_redirect(self):
        """Override this function to control the redirect after add endpoint is called."""
        if session['last_document']:
            doc = str(session['last_document'])
            print('POST EDIT FUNCTION ************ ',session['last_document'] )

            return redirect(url_for('DrasdocumentView.show', pk=doc))
    '''

class RevisionView(ModelView):
    datamodel = SQLAInterface(Drasrevision)
    list_columns = ['drasdocument','stage_class','name', 'current_cs']
    show_columns = ['drasdocument','stage_class','name', 'current_cs']
    label_columns = {
        'drasdocument':'Document',
        'stage_class':'Stage',
        'name': 'Name',
        'current_cs': 'Status'
    }

    show_title = 'Show Revision'
    list_title = 'List Revision'
    add_title = 'Add Revision'
    edit_title = 'Edit Revision'
    related_views = [CommentSheetView]
    #default_view = 'show'
    list_widget = RevisionListCard
    show_template = 'appbuilder/general/model/show_cascade.html'

    @action("muldelete", "Delete", "Delete all Really?", "fa-rocket")
    def muldelete(self, items):
        if isinstance(items, list):
            self.datamodel.delete_all(items)
            self.update_redirect()
        else:
            self.datamodel.delete(items)
        return redirect(self.get_redirect())

class DrasdocumentView(ModelView):
    datamodel = SQLAInterface(Drasdocument)
    related_views = [CommentSheetView, RevisionView, CommentView]
    show_template = 'appbuilder/general/model/show_cascade.html'
    search_columns = ['name']
    list_columns = ['name','moc', 'open_comm' ]
    show_columns = ['title_name','description', 'moc','current_mr','current_mr_description','current_rev','current_stage']
    show_title = 'Show Document'
    list_title = 'List Document'
    add_title = 'Add Document'
    edit_title = 'Edit Document'

    label_columns = {

        'moc':'Main Operating Center',
        'name': 'Document Code',
        'dedoc':'DED Operating Center',
        'title_name': 'Document',
        'current_rev': 'Current Rev',
        'current_stage': 'Stage',
        'description' : 'Title',
        'current_mr': 'Material Requisition',
        'current_mr_description': 'MR Description'

    }
from app.comments.helpers import get_vendor_data_from_cs
class DrasUploadView(ModelView):
    datamodel = SQLAInterface(Drascommentsheet)
    add_title = 'DRAS Upload'
    default_view = 'add'
    base_permissions = ['can_add']
    label_columns = {
        'documentReferenceDoc': 'Document',
        'documentReferenceRev': 'Revision',
        'documentReferenceDesc': 'Description',
        'documentReferenceBy': 'By',

        'ownerTransmittalReference': 'ID',
        'ownerTransmittalDate':'Date',
        'response_status': 'Status',

        'contractorTransmittalReference': 'ID',
        'contractorTransmittalDate': 'Date',
        'contractorTransmittalMr': 'MR',
        'contractorTransmittalVendor':'Vendor',
        'stage_icon':'Stage',

        'issuetype':'Issue Type',
        'actionrequired':'Action Required',
        'notificationItem':'Notification Item',
        'actualDate': 'Actual Date',
        'expectedDate': 'Expected Date',
        'plannedDate': 'Planned Date',
        'cs_file': 'File',
        'drasvendor': 'Vendor',
        'drasmr': 'MR'
    }

    add_fieldsets = [
        (lazy_gettext('DRAS File'),
         {'fields': ['cs_file','current']}),

        (lazy_gettext('DRAS Notification'),
         {'fields': [
                    #'drasvendor',
                    #'drasmr',
                    'issuetype',
                    'actionrequired',
                    'notificationItem',
                    'actualDate',
                    #'expectedDate'
                    ], 'expanded': True}),

        (lazy_gettext('DRAS Internal Info'),
         {'fields': ['note'],
                    'expanded': True}),

    ]
    #related_views = [CommentView]
    #show_template = 'appbuilder/general/model/show_cascade.html'

    def pre_add(self, item):

        # Check File Requirements
        #check_labels(item)
        doc = get_vendor_data_from_cs(item)

        session['last_document'] = doc
        print('PRE ADD FUNCTION ************ ',session['last_document'] )

        if doc == False:
            return abort(400, 'Pre Add Function Error.')

    #def pre_update(self, item):

        #session['last_document'] = item.drasdocument_id

        # Find or Create Document
        # Find or Create Revision

    def post_add_redirect(self):
        # Override this function to control the redirect after add endpoint is called.
        try:
            if session['last_document']:
                doc_id = session['last_document']
                #print('POST EDIT FUNCTION ************ ',session['last_document'] )

                return redirect(url_for('DrasdocumentView.show', pk=doc_id))
        except:
            print('Something still does not work for session')
            return redirect(self.get_redirect())

class TagdisciplineView(ModelView):
    datamodel = SQLAInterface(Tagdiscipline)
    list_columns = ['name','start','finish']

class DrasMrView(ModelView):
    datamodel = SQLAInterface(Drasmr)
    list_columns = ['name','description','drasvendor']
    add_columns = ['name','description','drasvendor']
    edit_columns = ['name','description','drasvendor']
    show_columns = ['name','description','drasvendor']

class DrasVendorView(ModelView):
    datamodel = SQLAInterface(Drasvendor)
    related_views = [DrasMrView]
    show_template = 'appbuilder/general/model/show_cascade.html'
    list_columns = ['name']
    add_columns = ['name','description']
    edit_columns = ['name','description']
    show_columns = ['name','description']

#appbuilder.add_view(RevisionView,'Revision',icon="fa-folder-open-o", category="DRAS", category_icon='fa-envelope')

"""
    Application wide 404 error handler
"""
@appbuilder.app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html', base_template=appbuilder.base_template, appbuilder=appbuilder), 404

#appbuilder.add_view(MidorewdDashboardView, "Early Works Documentation", icon="fa-folder-open-o", category="Dashboard", category_icon='fa-envelope')
appbuilder.add_view(MidorDrasDashboardView, "Comments", icon="fa-folder-open-o", category="Dashboard", category_icon='fa-envelope')
appbuilder.add_view(MidorDras2DashboardView, "DRAS", icon="fa-folder-open-o", category="Dashboard", category_icon='fa-envelope')
appbuilder.add_view(MidorDras3DashboardView, "Export", icon="fa-folder-open-o", category="Dashboard", category_icon='fa-envelope')
appbuilder.add_view(MidorDras4DashboardView, "Comments Check", icon="fa-folder-open-o", category="Dashboard", category_icon='fa-envelope')
appbuilder.add_view(MidorDras5DashboardView, "DRAS Current All Revision", icon="fa-folder-open-o", category="Dashboard", category_icon='fa-envelope')

appbuilder.add_view(MainOperatingCenterView, 'Main Operating Centers',icon="fa-folder-open-o", category="DRAS Components")

appbuilder.add_view(DEDOperatingCenterView, 'DED Operating Centers', icon="fa-folder-open-o", category="DRAS Components")

appbuilder.add_view(UnitView, 'Unit',icon="fa-folder-open-o", category="DRAS Components")

appbuilder.add_view(DisciplineView, 'Discipline',icon="fa-folder-open-o", category="DRAS Components")
appbuilder.add_view(TagdisciplineView, 'Tags',icon="fa-folder-open-o", category="DRAS Components")

appbuilder.add_view(SowView, 'Split of Works',icon="fa-folder-open-o", category="DRAS Components")

appbuilder.add_view(DrasVendorView, 'Vendors',icon="fa-folder-open-o", category="DRAS Components")
appbuilder.add_view(DrasMrView, 'MR',icon="fa-folder-open-o", category="DRAS Components")

appbuilder.add_view(DrasdocumentView, 'Document', icon="fa-folder-open-o",category="DRAS DCC", category_icon='fa-envelope')

appbuilder.add_view(RevisionView, 'Revision',
                    icon="fa-folder-open-o", category="DRAS DCC")

appbuilder.add_view(CommentSheetView, 'Dras List',
                    icon="fa-folder-open-o", category="DRAS DCC")

appbuilder.add_view(CommentSheet2View, 'Search Dras List',
                    icon="fa-folder-open-o", category="DRAS DCC")

appbuilder.add_view(CommentView, 'Comment',
                    icon="fa-folder-open-o", category="DRAS DCC")

appbuilder.add_separator(category="DRAS DCC")

appbuilder.add_view(DrasUploadView, 'Dras Upload',
                    icon="fa-folder-open-o", category="DRAS DCC")

appbuilder.add_view(IssueTypeView, 'Issue Type',
                    icon="fa-folder-open-o", category="DRAS Components")

appbuilder.add_view(ActionRequiredView, 'Action Required',
                    icon="fa-folder-open-o", category="DRAS Components")

appbuilder.add_separator(category="DRAS Components")

appbuilder.add_separator(category="DRAS Components")

#db.create_all()

#add_moc()

db.create_all()
#piero_items()
#update_all_YF()
#upload_ewd()
#create_file_list()
#upload_correspondence()
#fakeItem3(1)
#init_dras()
from app.comments.helpers import cs_sanification, piero_pos_check_items
#piero_pos_check_items()
#cs_sanification()


import cv2 as cv

# reading images
img = cv.imread('../Images/cat2.jpg')

# cv.imshow() Display images in a new separate window
cv.imshow('cat', img)
cv.waitKey(0)

# Reading videos
# VideoCapture() method takes either integer values 0, 1, 2, etc. as a parameter or path to a video file
# use integer value to use our webcam or camera source
capture = cv.VideoCapture('../Videos/SampleVideo1.mp4')

# use while loop and read video frame by frame
while True:
    # capture.read() rads above video in capture frame by frame
    # isTrue represent boolean value if the video frame was read successfully or not
    isTrue, frame = capture.read()

    cv.imshow('SampleVideo1', frame)

    # if keyboard letter d is pressed, exit out of loop
    if cv.waitKey(20) & 0xFF == ord('d'):
        break

capture.release()
cv.destroyAllWindows()


import pygame

pygame.init() # 초기화(반드시 필요)

# 화면 크기 설정
screen_width = 480 # 가로 크기
screen_height = 640 # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("Nado Game") # 게임이름

# 배경 이미지 불러오기
background = pygame.image.load("C:/data_analysis/pygame_basic/background.png")

# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("C:/data_analysis/pygame_basic/character.png")
character_size = character.get_rect().size # 이미지의 크기를 구해옴, rect : 사각형
character_width = character_size[0] # 캐릭터의 가로 크기
character_height = character_size[1] # 캐릭터의 세로 크기
character_x_pos = (screen_width - character_width)/ 2 # 화면 가로의 절반에 위치
character_y_pos = screen_height - character_height # 화면 세로 가장 아래에 위치

# 이벤트 루프
running = True # 게임이 진행중인가?
while running:
    for event in pygame.event.get(): # 프로그램이 중단되지 않도록 계속 대기하는것, 사용자가 키보드나 마우스로 동작하는지 체크
        if event.type == pygame.QUIT: # 맨 위 오른쪽의 x버튼 누르면 창 닫기
            running = False # 게임이 진행중이 아님

    screen.blit(background, (0,0)) # 배경 그리기

    screen.blit(character, (character_x_pos, character_y_pos)) # 캐릭터 그리기

    pygame.display.update() # 게임화면 다시 그리기!!! 계속 호출해야함

# pygame 종료
pygame.quit()


from django import forms
from app.models import Customer

class AddCustomerForm(forms.ModelForm):
    class Meta:
        model = Customer
        fields = ('customer_name','customer_mob_no','customer_address')

        widgets = {
            'customer_name':forms.TextInput(attrs={'class':'form-control'}),
            'customer_mob_no':forms.NumberInput(attrs={'class':'form-control', 'type': 'number'}),
            'customer_address':forms.Textarea(attrs={'class':'form-control'}),
        }

    def clean_quantity(self):
        customer_mob_no = self.cleaned_data['customer_mob_no']
        if customer_mob_no < 0:
            raise forms.ValidationError("Mobile number cannot be negative.")
        return customer_mob_no


import casadi as ca
import casadi.tools

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt

"""
State of nonholonomic vehicle:
x = [
    x_pos,
    y_pos,
    psi,
    body_velocity
]

inputs = [
    v
    omega
]

"""
def stateFunc(x, u):

    psi = x[2]
    velocity = u[0]
    ang_velocity = u[1]

    dx_pos = velocity*ca.cos(psi)
    dy_pos = velocity*ca.sin(psi)
    dpsi = ang_velocity

    return [dx_pos, dy_pos, dpsi]

################################################################
# Global Variables
################################################################

################################################################
# States, Inputs, Equations
################################################################
"""States """
states = ['x_pos',
          'y_pos',
          'psi']

x = ca.tools.struct_symMX(
    states
)

"""Inputs"""
inputs = ['velocity',
          'angular_velocity']

u = ca.tools.struct_symMX(
    inputs
)

"""Equation setup"""
dx = ca.tools.struct_MX(x) #make sure this is a matrix

dx_pos = u["velocity"] * ca.cos(x["psi"])
dy_pos = u["velocity"] * ca.sin(x["psi"])
dpsi = u['angular_velocity']

dx["x_pos"] = dx_pos
dx["y_pos"] = dy_pos
dx["psi"] = dpsi #+ x["psi"]

# Ode Right Hand Side ax+bu = x_dot
rhs = dx
f = ca.Function('f',
                [x,u],
                [rhs],
                ['x', 'u'],
                ['dx']
)

################################################################
# Optimization setup
################################################################

opti = ca.Opti()

#optimization grid points
N = 20
dt_val = 0.1

# define decision variables
X = opti.variable(x.size, N+1) # decision variables of states x grid_points + 1
x_pos = X[0,:]
y_pos = X[1,:]
psi = X[2,:]

U = opti.variable(u.size, N) # decision variables of inputs x grid_points + 1
velocity = U[0,:]
angular_velocity = U[1,:]
T = opti.variable() # final time

#Initial State parameter
x0 = opti.parameter(x.size) # number of states

"""
Add dynamic constraints, g utilizing Runge Kutta, can use collocation methods
"""

################################################################
# Initial Integration
################################################################

#doing this through matrix operations
dt = ca.MX.sym("dt")
k1 = f(x, u)
k2 = f(x + dt / 2.0 * k1, u)
k3 = f(x + dt / 2.0 * k2, u)
k4 = f(x + dt * k3, u)
xf = x + dt / 6.0 * (k1 + 2 * k2 + 2 * k3 + k4)

# Single step time propagation
F_RK4 = ca.Function("F_RK4",
                    [x, u, dt], [xf],
                    ['x[k]', 'u[k]', "dt"],
                    ['x[k+1]'])

#dt_val = T/N
for k in range(N):
    opti.subject_to(
        X[:,k+1] == F_RK4(X[:,k], U[:,k], dt_val)
        )

#hermite simpson qudrature
# dt = ca.MX.sym("dt")
# z_low = X[:,:-1] #all states to just before the last time grid point
# z_upp = X[:,1:] #all states but skip the first grid point

# u_low = U[:,:-1]
# u_upp = U[:,1:]

# f_low = stateFunc(z_low,u_low)
# f_upp = stateFunc(z_upp, u_upp)

# ## compute dynamics at intermediate point, centroid
# z_bar = 0.5*(z_low + z_upp) + (dt/8)*(f_low-f_upp);
# u_bar = u_low + (u_low + u_upp)/2 #trapezoid
# f_bar = stateFunc(z_bar, u_bar)

# ## compute the defects
# defects = z_upp - z_low - (dt/6)*(f_low + 4*f_bar + f_upp);

# Control constraints defined as path constraints
MAX_VELOCITY = 45 #m/s
MIN_VELOCITY = 15 #m/s
MAX_ANG_VELOCITY = np.deg2rad(60) #rad/s

opti.subject_to(opti.bounded(MIN_VELOCITY, velocity, MAX_VELOCITY))
opti.subject_to(opti.bounded(-MAX_ANG_VELOCITY, angular_velocity, MAX_ANG_VELOCITY))

goal_x = 25
goal_y = 25
goal_psi = np.deg2rad(45)

# Initial and terminal constraints
opti.subject_to(X[:,0] == x0)
# opti.subject_to(T>=0) #time must be grater than 0

opti.subject_to(X[:,-1] == [goal_x,goal_y,goal_psi])

#cost function
e_x = (goal_x - x_pos)
e_y = (goal_y - y_pos)
e_psi = (goal_psi - psi)

weights = [1, 1, 10]

# cost_value = (weights[0]*ca.sumsqr(e_x)) + (weights[1]*ca.sumsqr(e_y)) + \
#     (weights[-1]* ca.sumsqr(e_psi)) + ca.sumsqr(U)

cost_value = (weights[0]*ca.sumsqr(e_x)) + (weights[1]*ca.sumsqr(e_y)) + \
    (weights[-1]* ca.sumsqr(e_psi))

#opti.minimize(cost_value)
opti.minimize(cost_value)

#solve problem
opti.solver('ipopt')#, {'ipopt': {'print_level': 0}})
#set initial guesses
opti.set_value(x0, [0, 0, 0])
sol = opti.solve()

x_traj = sol.value(X).T[:-1]
u_traj = sol.value(U).T

sol_traj = pd.DataFrame(np.hstack((x_traj, u_traj)),
                        columns=['x', 'y', 'psi', 'velocity', 'angular_velocity'])

#%%
################################################################
# Visualize Results
################################################################
plt.close('all')
t_simulate = np.arange(0, N*dt_val, dt_val)
# t_simulate = np.arange(0,sol.value(T), sol.value(dt_val))

fig, ax = plt.subplots(figsize=(8, 8))

ax.plot(goal_x, goal_y, 'x', markersize=20)
ax.plot(sol_traj["x"], sol_traj["y"])
#ax.add_patch(c)

ax.set_xlim([-1, goal_x+10])
ax.set_ylim([-1, goal_y+10])
ax.grid()

fig2, ax2 = plt.subplots(figsize=(8,8))

ax2.plot(t_simulate, np.rad2deg(u_traj[:,1]), label='angular_velocity')
ax2.plot(t_simulate, np.rad2deg(sol_traj['psi']), label='psi')

ax2.legend(loc="upper left")

ax2.grid()

fig3, ax3 = plt.subplots(figsize=(8,8))
ax3.plot(t_simulate, u_traj[:,0], label='velocity')

ax2.grid()


import textmining, logging
from scipy import spatial

def term_document_matrix(texts):
    term_doc_matrix = textmining.TermDocumentMatrix(tokenizer=textmining.simple_tokenize_remove_stopwords)
    for t in texts:
        term_doc_matrix.add_doc(t)
    return term_doc_matrix

def common_and_unique_word_freqs(texts):
    word_count_d1 = len(texts[0].split())
    word_count_d2 = len(texts[1].split())
    tdm = term_document_matrix(texts)
    # get the most common used words, sorted by freq
    common_rows = tdm.rows(cutoff=2)
    common_terms = next(common_rows)
    common_d1_freqs = next(common_rows)
    common_d2_freqs = next(common_rows)
    total_uses = [t1 + t2 for t1,t2 in zip(common_d1_freqs,common_d2_freqs)]
    common_word_freqs = zip(total_uses,common_terms)
    common_word_freqs.sort(reverse=True)
    # get word counts of common terms in each document
    common_counts = [zip(common_d1_freqs, common_terms), zip(common_d2_freqs, common_terms)]
    common_counts[0].sort(reverse=True)
    common_counts[1].sort(reverse=True)
    # get all the rows for unique-to-doc calculations
    all_rows = tdm.rows(cutoff=0)
    all_terms = next(all_rows)
    all_d1_freqs = next(all_rows)
    all_d2_freqs = next(all_rows)
    # get the doc1 words
    d1 = [ (f1,t) for t,f1 in zip(all_terms,all_d1_freqs) if f1>0]
    d1.sort(reverse=True)
    # get the doc2 words
    d2 = [ (f2,t) for t,f2 in zip(all_terms,all_d2_freqs) if f2>0]
    d2.sort(reverse=True)
    # get the unique doc1 words
    unique_to_d1 = [ (f1,t) for t,f1,f2 in zip(all_terms,all_d1_freqs,all_d2_freqs) if f2 is 0]
    unique_to_d1.sort(reverse=True)
    # get the unique doc2 words
    unique_to_d2 = [ (f2,t) for t,f1,f2 in zip(all_terms,all_d1_freqs,all_d2_freqs) if f1 is 0]
    unique_to_d2.sort(reverse=True)
    # compute cosine similarity too
    cosine_similarity = ( 1 - spatial.distance.cosine(all_d1_freqs,all_d2_freqs) )

    # stitch it together to return the data
    return {'common': common_word_freqs, 'common_counts': common_counts, 'doc1': d1, 'doc2':d2,
            'doc1unique': unique_to_d1, 'doc2unique': unique_to_d2,
            'doc1total': word_count_d1, 'doc2total': word_count_d2,
            'cosine_similarity': cosine_similarity}


# 给你一个二叉树的根节点 root ，按 任意顺序 ，返回所有从根节点到叶子节点的路径。
# 叶子节点指没有子节点的结点

# Definition for a binary tree node.
import collections
from typing import Optional, List

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        path_list = []

        node_que = collections.deque([root])
        parent_que = collections.deque([str(root.val)])

        while node_que:
            node = node_que.popleft()
            cur_path = parent_que.popleft()

            if not node.left and not node.right:
                path_list.append(cur_path)

            if node.left:
                lcur_path = cur_path + '->' + str(node.left.val)
                node_que.append(node.left)
                parent_que.append(lcur_path)

            if node.right:
                rcur_path = cur_path + '->' + str(node.right.val)
                node_que.append(node.right)
                parent_que.append(rcur_path)

        return path_list

    def dfs_binaryTreePaths(self, root):
        def dfs(root, path):
            if root:
                path += str(root.val)
                if not root.left and not root.right:
                    paths.append(path)
                else:
                    path += '->'
                    dfs(root.left, path)
                    dfs(root.right, path)

        paths = []
        dfs(root, '')
        return paths

node1 = TreeNode(1)
node2 = TreeNode(2)
node3 = TreeNode(3)
node5 = TreeNode(5)

node1.left = node2
node1.right = node3
node2.right = node5

a = Solution().binaryTreePaths(node1)
print(a)


"""Utility functions for the openedx app"""
from dataclasses import dataclass
from typing import NamedTuple, TypeVar, List, Generic
from urllib.parse import urljoin

from django.conf import settings

def edx_url(path):
    """Returns the full url to the provided path"""
    return urljoin(settings.OPENEDX_API_BASE_URL, path)

def edx_redirect_url(path):
    """Returns the full url to the provided path using the edX hostname specified for redirects"""
    return urljoin(settings.OPENEDX_BASE_REDIRECT_URL, path)

T = TypeVar("T")

@dataclass
class SyncResult(Generic[T]):
    """Represents the results of a sync with edX"""

    created: List[T]
    reactivated: List[T]
    deactivated: List[T]

    def __init__(
        self,
        created: List[T] = None,
        reactivated: List[T] = None,
        deactivated: List[T] = None,
    ):
        self.created = created or []
        self.reactivated = reactivated or []
        self.deactivated = deactivated or []

    @property
    def no_changes(self):
        """Returns True if this sync object does not indicate any changes"""
        return all(
            [
                len(self.created) == 0,
                len(self.reactivated) == 0,
                len(self.deactivated) == 0,
            ]
        )


import numpy as np
from tqdm import tqdm
import test_functions as test

class Particle:
    global_best_value = None
    global_best_position = None

    def __init__(self, obj_func, bounds, c_i, c_s, c_c):
        self.obj_function = obj_func
        self.c_i = c_i
        self.c_c = c_c
        self.c_s = c_s

        self.lower_bounds = np.array([bound[0] for bound in bounds])
        self.upper_bounds = np.array([bound[1] for bound in bounds])

        self.position = np.random.uniform(self.lower_bounds, self.upper_bounds, len(bounds))
        self.value = self.obj_function(self.position)

        self.personal_best_position = self.position.copy()
        self.personal_best_value = self.value

        self.velocity = np.random.uniform(self.lower_bounds - self.upper_bounds,
                                          self.upper_bounds - self.lower_bounds,
                                          len(bounds))

        if Particle.global_best_value is None or self.value < Particle.global_best_value:
            Particle.global_best_position = self.position.copy()
            Particle.global_best_value = self.value

    def update_velocity(self):
        r_c = np.random.random(self.velocity.shape)
        r_s = np.random.random(self.velocity.shape)

        cognitive_velocity = r_c * self.c_c * (self.personal_best_position - self.position)
        social_velocity    = r_s * self.c_s * (Particle.global_best_position - self.position)
        inertia            = self.c_i * self.velocity

        self.velocity = cognitive_velocity + social_velocity + inertia

    def update_position(self):
        self.position = np.clip(self.position + self.velocity, self.lower_bounds, self.upper_bounds)
        self.value = self.obj_function(self.position)

        if self.value < self.personal_best_value:
            self.personal_best_value = self.value
            self.personal_best_position = self.position.copy()

            if self.value < Particle.global_best_value:
                Particle.global_best_value = self.value
                Particle.global_best_position = self.position.copy()

def PSO(swarm_size, num_iters, c_i, c_c, c_s, obj_func, num_dimensions, lb, ub):
    bounds = [(lb, ub) for _ in range(num_dimensions)]
    swarm = [Particle(obj_func, bounds, c_i, c_s, c_c) for _ in range(swarm_size)]

    for iter in tqdm(range(num_iters)):
        for particle in swarm:
            particle.update_velocity()
            particle.update_position()

    print(f'Global best value: {Particle.global_best_value}')
    print(f'Global best position: {Particle.global_best_position}')

    Particle.global_best_position = None
    Particle.global_best_value = None


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='BlogPost',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('title', models.CharField(max_length=150)),
                ('body', models.TextField()),
                ('timestamp', models.DateTimeField()),
                ('tags', models.CharField(max_length=100)),
                ('views_count', models.TextField()),
                ('comments_count', models.TextField()),
                ('auth', models.TextField(default=b'\xe8\xb0\xb7\xe6\x99\xa8')),
                ('address', models.CharField(default=b'\xe8\xa5\xbf\xe5\xae\x89', max_length=100)),
            ],
        ),
    ]


from django.urls import path
from django.contrib.auth import views as auth_views
from rest_framework.routers import DefaultRouter
from mainsite.views import (
    HomeView,
    ProfileViewSet,
    HashtagView,
    ProductViewSet,
)

router = DefaultRouter()
router.register(r"products", ProductViewSet, basename="products")

urlpatterns = [
    path("", HomeView.as_view(), name="home"),
    # path("profile/", ProfileViewSet.as_view(), name="profile"),
    # path("<hashtag>/", HashtagView.as_view(), name="hashtag"),
]

urlpatterns += router.urls


from django.utils.translation import gettext_lazy as _
from rest_framework import serializers

class LinkOrgSerializer(serializers.Serializer):
    id = serializers.CharField(max_length=36, label='ID', read_only=True)
    name = serializers.CharField(max_length=64, label=_('二级机构名'), allow_blank=False, allow_null=False, required=True)
    remarks = serializers.CharField(label=_('备注'), max_length=255, allow_blank=True, allow_null=True, required=False, default='')
    location = serializers.CharField(label=_('经纬度'), max_length=64, allow_blank=True, allow_null=True, required=False, default='')
    data_center = serializers.SerializerMethodField(label=_('数据中心'), method_name='get_data_center')

    @staticmethod
    def get_data_center(obj):
        data_center = obj.data_center
        if data_center is not None:
            return {'id': data_center.id, 'name': data_center.name, 'name_en': data_center.name_en}
        return None


from PIL import Image, ImageDraw, ImageFilter, ImageEnhance

char_map = " `'\".,:;i!~-+]{|1\\rxucoz6?UCL0O*#W&B@$$"

class Picture:
    def __init__(self, filename, resolution):
        # loading image
        img = Image.open(filename)
        img = img.resize((resolution * round(img.size[0] / img.size[1]), resolution))
        self.image = img
        self.width, self.height = img.size

        # enhance image for cleaner result
        self.image = self.image.filter(ImageFilter.EDGE_ENHANCE)
        self.image = ImageEnhance.Contrast(self.image).enhance(2)

        # required matrices
        self.char_matrix = []
        self.rgb_matrix = []

        # output image
        self.output = Image.new('RGB', (self.width * 10, self.height * 10))

    def generate(self):
        # make 2d array of pixels
        rgb_matrix = list(self.image.getdata())
        self.rgb_matrix = [rgb_matrix[j:j + self.width] for j in range(0, len(rgb_matrix), self.width)]
        # rgb values to intensity values
        intensity_matrix = [[.21 * p[0] + .72 * p[1] + .07 * p[2] for p in pixel_row] for pixel_row in self.rgb_matrix]
        # intensity values to characters
        self.char_matrix = [[char_map[int(i * (len(char_map) - 1) / 255)] for i in i_row] for i_row in intensity_matrix]

    def draw_color(self):
        draw = ImageDraw.Draw(self.output)

        for y in range(self.height):
            for x in range(self.width):
                draw.text((x * 10, y * 10), self.char_matrix[y][x], fill=self.rgb_matrix[y][x])

    def draw_bw(self):
        draw = ImageDraw.Draw(self.output)

        for y in range(self.height):
            for x in range(self.width):
                draw.text((x * 10, y * 10), self.char_matrix[y][x], fill=(255, 255, 255))

    def save_image(self, path):
        self.output.save(path + '.jpg')

    def save_text(self, path):
        string = ""
        for row in self.char_matrix:
            line = [p + p + p for p in row]
            string += ''.join(line) + '\n'

        text_file = open(path + '.txt', "w")
        text_file.write(string)
        text_file.close()


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

'''
original matlab code at https://www.robots.ox.ac.uk/~vgg/research/caltech/phog.html
'''

def anna_phog(Img, bin, angle, L, roi):
    '''
     anna_PHOG Computes Pyramid Histogram of Oriented Gradient over a ROI.

     [BH, BV] = anna_PHOG(Img,BIN,ANGLE,L,ROI) computes phog descriptor over a ROI.

     Given and image Img, phog computes the Pyramid Histogram of Oriented Gradients
     over L pyramid levels and over a Region Of Interest

    IN:
        Img- Images numpy array of size MxN (Color or Gray)
        bin - Number of bins on the histogram
        angle - 180 or 360
       L - number of pyramid levels
       roi - Region Of Interest (ytop,ybottom,xleft,xright)

    OUT:
        p - pyramid histogram of oriented gradients
    '''
    if Img.shape[2] == 3:
        G = cv2.cvtColor(Img, cv2.COLOR_BGR2GRAY)
    else:
        G = Img

    if np.sum(G) > 100:
        # apply automatic Canny edge detection using the computed median
        sigma = 0.33
        v = np.median(G)
        lower = int(max(0, (1.0 - sigma) * v))
        upper = int(min(255, (1.0 + sigma) * v))
        E = cv2.Canny(G,lower,upper) #high and low treshold
        GradientX, GradientY = np.gradient(G)
        GradientYY = np.gradient(GradientY, axis=1)

        Gr = np.sqrt(np.square(GradientX)+np.square(GradientY))
        index = GradientX == 0
        GradientX[index] = 1e-5 #maybe another value

        YX = GradientY*GradientX
        if angle == 180: A = ((np.arctan(YX)+(np.pi/2))*180)/np.pi
        if angle == 360: A = ((np.arctan2(GradientY,GradientX)+np.pi)*180)/np.pi

        bh, bv = anna_BinMatrix(A,E,Gr,angle,bin)

    else:
        bh = np.zeros(Img.shape)
        bv = np.zeros(Img.shape)

    bh_roi = bh[roi[0]:roi[1], roi[2]:roi[3]]
    bv_roi = bv[roi[0]:roi[1], roi[2]:roi[3]]

    p = anna_PhogDescriptor(bh_roi,bv_roi,L,bin)
    return p

def anna_BinMatrix(A,E,G,angle,bin):
    '''
    anna_BINMATRIX Computes a Matrix (bm) with the same size of the image where
    (i,j) position contains the histogram value for the pixel at position (i,j)
    and another matrix (bv) where the position (i,j) contains the gradient
    value for the pixel at position (i,j)

    IN:
    	A - Matrix containing the angle values
    	E - Edge Image
        G - Matrix containing the gradient values
    	angle - 180 or 360
        bin - Number of bins on the histogram

    OUT:
    	bm - matrix with the histogram values
        bv - matrix with the gradient values (only for the pixels belonging to and edge)
    '''
    n, contorns = cv2.connectedComponents(E, connectivity=8)

    X = E.shape[1]
    Y = E.shape[0]
    bm = np.zeros(shape=(Y,X))
    bv = np.zeros(shape=(Y,X))

    nAngle = angle/bin

    for i in range(n):
        posY, posX = np.where(contorns==i)
        for j in range(posY.shape[0]):
            pos_x = posX[j]
            pos_y = posY[j]

            b = np.ceil(A[pos_y,pos_x]/nAngle)
            if b==0: bin=1
            if G[pos_y,pos_x]>0:
                bm[pos_y,pos_x] = b
                bv[pos_y,pos_x] = G[pos_y,pos_x]

    return (bm, bv)

def anna_PhogDescriptor(bh,bv,L,bin):
    '''
     anna_PHOGDESCRIPTOR Computes Pyramid Histogram of Oriented Gradient over a ROI.

    IN:
        bh - matrix of bin histogram values
        bv - matrix of gradient values
       L - number of pyramid levels
       bin - number of bins

    OUT:
        p - pyramid histogram of oriented gradients (phog descriptor)
    '''
    p = np.array([])
    #level 0
    for b in range(bin):
        ind = bh==b
        p = np.append(p, np.sum(bv[ind]))

    #higher levels
    for l in range(1, L+1):
        x = int(np.trunc(bh.shape[1]/(2**l)))
        y = int(np.trunc(bh.shape[0]/(2**l)))
        for xx in range(0, bh.shape[1]-x+1, x):
            for yy in range(0, bh.shape[0]-y+1, y):
                print(l)
                bh_cella = bh[yy:yy+y, xx:xx+x]
                bv_cella = bv[yy:yy+y, xx:xx+x]

                for b in range(bin):
                    ind = bh_cella==b
                    p = np.append(p, np.sum(bv_cella[ind], axis=0))

    if np.sum(p)!=0:
        p = p/np.sum(p)

    return p


from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import psycopg2
from PyQt5.uic import loadUiType
from Connect import ConnectDatabase

# Global Variable
listentry_ui, _ = loadUiType('Ui/ListEntryPartLoop.ui')

class ListEntryApp(QDialog, listentry_ui):
    def __init__(self, parent=None):
        super(ListEntryApp, self).__init__(parent)
        self.setupUi(self)
        self.HandleButtonAction()
        self.ShowDepartment_custom()
        self.ShowStatus_entry()
        self.ClearDropDown()
        self.ListEntry_show()

    # Method for Button action
    def HandleButtonAction(self):
        self.pushButtonListEntrySearch.clicked.connect(self.ListEntry_show)
        self.pushButtonListEntryReset.clicked.connect(self.ListEntry_reset)

    # Method to set empty value in drop-down field
    def ClearDropDown(self):
        self.comboBoxListEntryDepartment.setCurrentText('')
        self.comboBoxListEntryStatus.setCurrentText('')

    # Method to show drop-down data
    def ShowDepartment_custom(self):
        self.db = ConnectDatabase()
        self.cur = self.db.cursor()
        self.cur.execute('SELECT department_name FROM department ORDER BY department_name ASC')
        department_list = self.cur.fetchall()
        for department in department_list:
            self.comboBoxListEntryDepartment.addItem(department[0])
        self.db.close()

    def ShowStatus_entry(self):
        self.db = ConnectDatabase()
        self.cur = self.db.cursor()
        self.cur.execute('SELECT status_name FROM status ORDER BY status_name ASC')
        status_list = self.cur.fetchall()
        for status in status_list:
            self.comboBoxListEntryStatus.addItem(status[0])
        self.db.close()

    # Method to show list of entry
    def ListEntry_show(self):
        field_name = self.lineListEntryPartName.text()
        field_department = self.comboBoxListEntryDepartment.currentText()
        field_status = self.comboBoxListEntryStatus.currentText()
        search_name = '%{}%'.format(field_name)
        search_department = '%{}%'.format(field_department)
        search_status = '%{}%'.format(field_status)
        self.db = ConnectDatabase()
        self.cur = self.db.cursor()
        try:
            self.cur.execute('''SELECT entry.id, entry.entry_date, part.part_name, part.part_department,
            entry.entry_status, entry.entry_qty, entry.entry_employee, entry.entry_desc FROM entry JOIN part ON
            entry.part_id = part.id WHERE part.part_name ILIKE %s AND part.part_department ILIKE %s AND
            entry.entry_status ILIKE %s ORDER BY entry.id ASC''',
                             (search_name, search_department, search_status))
            fetch_data = self.cur.fetchall()
        except Exception as error:
            self.error_popup("Duplicate Error", "Failed to connect database")
        else:
            if fetch_data is None:
                self.tableWidgetListEntry.setRowCount(0)
                self.error_popup("List Entry", "No records found!")
            else:
                self.tableWidgetListEntry.setRowCount(0)
                self.tableWidgetListEntry.insertRow(0)
                for row, form in enumerate(fetch_data):
                    for column, item in enumerate(form):
                        self.tableWidgetListEntry.setItem(row, column, QTableWidgetItem(str(item)))
                        column += 1
                        row_position = self.tableWidgetListEntry.rowCount()
                        self.tableWidgetListEntry.insertRow(row_position)
                        self.tableWidgetListEntry.resizeColumnsToContents()
                        self.tableWidgetListEntry.horizontalHeader().setSectionResizeMode(7, QHeaderView.Stretch)
        self.db.close()

    # Method to reset list of entry
    def ListEntry_reset(self):
        self.ClearDropDown()
        self.lineListEntryPartName.clear()
        self.ListEntry_show()

    # Method to show error popup window
    def error_popup(self, title_popup, msg_popup):
        popup = QMessageBox()
        popup.setFixedSize(500, 500)
        popup.setWindowTitle(title_popup)
        popup.setIcon(QMessageBox.Warning)
        popup.setStyleSheet("font:9pt Poppins;")
        popup.setText(msg_popup)
        popup.exec_()


from datetime import datetime, timedelta

from openerp import api, fields, models
from openerp.tools.translate import _
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as OE_DTFORMAT

class SaleOrder(models.Model):

    _inherit = 'sale.order'

    @api.model
    def _get_date_planned(self, order, line, start_date):

        if line and line.requested_date:
            date_planned = datetime.strptime(line.requested_date, OE_DTFORMAT)
            date_planned -= timedelta(days=order.company_id.security_lead)
            return date_planned.strftime(OE_DTFORMAT)

        return super(SaleOrder, self).\
            _get_date_planned(order, line, start_date)

class SaleOrderLine(models.Model):

    """Add several date fields to Sale Order Lines"""

    _inherit = 'sale.order.line'

    @api.depends('state', 'order_id.picking_ids')
    def _get_shipped_date(self):
        """Read the shipping date from the related pickings"""

        for line in self:
            order = line.order_id
            dates_list = []
            for pick in order.picking_ids:
                for move in pick.move_lines:
                    if move.product_id.id == line.product_id.id \
                       and move.state == 'done':
                        dates_list.append(pick.date)
            if dates_list:
                line.shipped_date = max(dates_list)
            else:
                line.shipped_date = False

    @api.depends('product_id', 'delay')
    def _get_commitment_date(self):
        """Compute the commitment date"""

        for line in self:
            if line.state == 'cancel':
                continue
            dates_list = []
            order_datetime = datetime.strptime(line.order_id.date_order,
                                               OE_DTFORMAT)
            dt = order_datetime + timedelta(days=line.delay or 0.0)
            dates_list.append(dt.strftime(OE_DTFORMAT))
            if dates_list:
                line.commitment_date = min(dates_list)

    @api.onchange('requested_date')
    def onchange_requested_date(self):
        """Warn if the requested dates is sooner than the commitment date"""

        for line in self:
            if (line.requested_date and
                    line.commitment_date and
                    line.requested_date < line.commitment_date):
                return {'warning': {
                    'title': _('Requested date is too soon!'),
                    'message': _("The date requested by the customer is "
                                 "sooner than the commitment date. You may be "
                                 "unable to honor the customer's request.")
                }
                }
        return {}

    # Fields
    #
    commitment_date = fields.Datetime(
        compute=_get_commitment_date, store=True, string='Commitment Date',
        help="Date by which the products are sure to be delivered. This is "
             "a date that you can promise to the customer, based on the "
             "Product Lead Times.")
    requested_date = fields.Datetime(
        'Requested Date', readonly=False, copy=False,
        help="Date by which the customer has requested the items to be "
             "delivered.\n"
             "When this Order gets confirmed, the Delivery Order's "
             "expected date will be computed based on this date and the "
             "Company's Security Delay.\n"
             "Leave this field empty if you want the Delivery Order to be "
             "processed as soon as possible. In that case the expected "
             "date will be computed using the default method: based on "
             "the Product Lead Times and the Company's Security Delay.")
    shipped_date = fields.Date(
        compute=_get_shipped_date, store=False, string='Shipped Date',
        help="Date on which the last shipment was made.")


#! /usr/bin/env python
# encoding: utf-8

import sys
sys.path.append('..')
sys.path.append('mock')

import unittest
from mock import Mock
import simulator.relay

class TestPacket(unittest.TestCase):
    """Class for testing Relay."""

    def test_instantiation(self):
        """Test instantiation."""
        id = "test_id"
        stats = {}
        decoder = Mock(name="decoder_object")
        decoder.block_size = Mock(return_value=100)
        c = simulator.relay.Relay(id, stats, decoder)
        self.assertEqual(c.sender.id, id)
        self.assertEqual(c.receiver.id, id)
        self.assertEqual(c.receiver.decoder, decoder)

if __name__ == '__main__':
    unittest.main()


import logging
from abc import abstractmethod, ABCMeta

class AbstractJob(metaclass=ABCMeta):
    '''AbstractJob provides common functionality for jobs that executes various set of tasks on spark.'''

    def __init__(self, sc, spark, gc, config):
        logging.basicConfig(level=logging.INFO)
        self.logger = logging.getLogger(self.__class__.__name__)
        self.sc = sc
        self.spark = spark
        self.gc = gc
        self.config = config

    @abstractmethod
    def try_execute(self, sc, spark, gc, config):
        pass

    def execute(self):
        self.logger.info("Executing job %s", (self.__class__.__name__,))
        try:
            self.try_execute( self.sc, self.spark, self.gc, self.config)
            self.logger.error("Executing job %s completed", self.__class__.__name__)
        except Exception as exception:
            # unexpected error, should retry
            self.logger.error("Error while executing job %s", self.__class__.__name__, exc_info=exception)


# n = len(nums)
# time: O(n*n)
# space: O(1)

from typing import List

class Solution:
    def sortColors(self, nums: List[int]) -> None:

        n=len(nums)

        for i in range(1,n):
            key=nums[i]
            j=i-1
            while j>=0 and key<nums[j]:
                nums[j+1]=nums[j]
                j-=1

            nums[j+1]=key


# coding: utf-8

# In[2]:

import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.optim as optim

import numpy as np

from PIL import Image
import matplotlib.pyplot as plt

import torchvision.transforms as transforms
import torchvision.models as models

import copy

# In[3]:

use_cuda = torch.cuda.is_available()

dtype = torch.cuda.FloatTensor if use_cuda else torch.FloatTensor

# # Preparing the data

# In[4]:

imsize = 512 if use_cuda else 128

loader_transform = transforms.Compose([
    transforms.Scale(imsize),
    transforms.ToTensor()
])

# # important notes for pytorch training

# the PIL load image with values between 0 and 255. After being transformed to torch floatTensor,
# the values are between 0 and 1.
# neural networks from torch library are trained with 0-1 tensor image. Feeding images with values
# between 0 and 255 makes no sense. While in Cafe the networks are pretrained with 0-255 tensor
# images

# In[5]:

def image_loader(image_name):
    image = Image.open(image_name)
    image = Variable(loader_transform(image))

    image = image.unsqueeze(0)
    # fake the batch dimension to fit the neural network input dimensions
    return image

# In[6]:

style_img = image_loader('picasso.jpg').type(dtype)
content_img = image_loader('dancing.jpg').type(dtype)

print(type(style_img))
assert style_img.size() == content_img.size(), 'we need to import style and content images of the same size'

# # display the images

# In[7]:

unloader_transform = transforms.ToPILImage()

#plt.ion()

def imshow(tensor, title = None):
    image = tensor.clone().cpu()
    image = image.squeeze(0) # an optinal operation image.view(3,imsize,imsize)
    #trnsform the image with values from 0-1 to 0-255 for (3, 128, 128) to (128, 128, 3)
    image = unloader_transform(image)
    #print(image.size)

    #image = image.numpy().transpose(1,2,0)
    #print(image.shape)
    plt.imshow(image)

    if title is not None:
        plt.title(title)
    plt.pause(0.001)

# In[8]:

##plt.figure()
##imshow(style_img.data, title = 'Style Image')
##plt.figure()
##imshow(content_img.data, title = 'Content Iamge')

#plt.show()

# In[9]:

class ContentLoss(nn.Module):

    def __init__(self, target, weight):
        super(ContentLoss, self).__init__()
        #self.target = target.clone() * weight
        # this is a problem in calculating gradient when using clone()
        self.target = target.detach() * weight
        #self.target.requires_grad = False
        self.weight = weight
        self.criterion = nn.MSELoss()

    def forward(self, input):
        self.loss = self.criterion(input * self.weight, self.target)
        self.output = input
        return self.output
    def backward(self, retain_variables = True):
        self.loss.backward(retain_variables = retain_variables)
        return self.loss

# In[10]:

class GramMatrix(nn.Module):
    def forward(self, input):
        a,b,c,d = input.size()

        features = input.view(a*b,c*d)

        G = torch.mm(features, features.t())

        return G.div(a * b * c * d)

# In[11]:

class StyleLoss(nn.Module):

    def __init__(self, target, weight):
        super(StyleLoss, self).__init__()
        self.target = target.detach() * weight
        #self.target = target.detach() * weight
        #self.target.requires_grad = False
        self.weight = weight
        self.gram = GramMatrix()
        self.criterion = nn.MSELoss()

    def forward(self, input):
        self.output = input.clone()
        self.G = self.gram(input)
        self.G.mul_(self.weight)
        self.loss = self.criterion(self.G, self.target)
        return self.output
    def backward(self, retain_variables = True):
        self.loss.backward(retain_variables = retain_variables)
        return self.loss

# In[12]:

cnn = models.vgg19(pretrained = True).features
if use_cuda:
    cnn = cnn.cuda()

print(list(cnn))

# In[13]:

content_layers_default = ['conv_4']
style_layers_default = ['conv_1', 'conv_2', 'conv_3', 'conv_4', 'conv_5']

def build_model(cnn, style_img, content_img,
                style_weight = 1000, content_weight = 1,
               content_layers = content_layers_default,
               style_layers = style_layers_default):
    cnn = copy.deepcopy(cnn)

    content_losses = []
    style_losses = []

    model = nn.Sequential()

    gram = GramMatrix()

    if use_cuda:
        model = model.cuda()
        gram = gram.cuda()

    i = 1
    for layer in list(cnn):
        if isinstance(layer, nn.Conv2d):
            name = 'conv_' + str(i)
            model.add_module(name, layer)

            if name in content_layers:
                target = model(content_img).clone()
                content_loss = ContentLoss(target, content_weight)
                model.add_module('content_loss' + str(i), content_loss)
                content_losses.append(content_loss)

            if name in style_layers:
                target_feature = model(style_img).clone()
                target_feature_gram = gram(target_feature)
                style_loss = StyleLoss(target_feature_gram, style_weight)
                model.add_module('style_loss_' + str(i), style_loss)
                style_losses.append(style_loss)

        if isinstance(layer, nn.ReLU):
            name = 'relu_' + str(i)
            model.add_module(name, layer)

            if name in content_layers:
                target = model(content_img).clone()
                content_loss = ContentLoss(target, content_weight)
                model.add_module('content_loss' + str(i), content_loss)
                content_losses.append(content_loss)

            if name in style_layers:
                target_feature = model(style_img).clone()
                target_feature_gram = gram(target_feature)
                style_loss = StyleLoss(target_feature_gram, style_weight)
                model.add_module('style_loss_' + str(i), style_loss)
                style_losses.append(style_loss)
            i += 1

        if isinstance(layer, nn.MaxPool2d):
            name = 'pool' + str(i)
            model.add_module(name, layer)

    return model, style_losses, content_losses

# In[14]:

input_img = content_img.clone()
# input_img = Varaible(troch.randn(content_img.data.size())).type(dtype)

##plt.figure()
##imshow(input_img.data, title = 'Input Image')
#plt.show()

# In[15]:

def get_input_param_optimizer(input_img):
    input_param = nn.Parameter(input_img.data)
    optimizer = optim.LBFGS([input_param])
    return input_param, optimizer

# In[18]:

def run_transfer(cnn, content_img, style_img, input_img, num_steps = 300,
                style_weight = 1000, content_weight = 1):
    print('building style transfer model...')
    model, style_losses, content_losses = build_model(cnn, style_img,content_img, style_weight,content_weight)
    input_param, optimizer = get_input_param_optimizer(input_img)

    print('Optimizing...')

    global iteration
    iteration = 0
    while iteration <= num_steps:

        def transfer_step():
            global iteration
            input_param.data.clamp_(0, 1)

            model(input_param)

            style_score = 0
            content_score = 0

            for style in style_losses:
                style_score += style.backward()
            for content in content_losses:
                content_score += content.backward()

            iteration += 1
            if iteration % 50 == 0:
                print('run {}:'.format(iteration))
                print('style loss:{:4f} \n content loss:{:4f}'.format(
                style_score.data[0], content_score.data[0]))

            return style_score + content_score

        optimizer.zero_grad()
        optimizer.step(transfer_step)
    input_param.data.clamp_(0, 1)

    return input_param.data

# In[ ]:

output = run_transfer(cnn, content_img, style_img, input_img)

plt.figure()
imshow(output, title = 'result')

plt.ioff()
plt.show()

# In[ ]:


import torch
import spacy
import string
import numpy as np
import pdb

class WordEmbedding:
  """Manager for vocabulary and word embeddings"""

  def __init__(self):
    self.nlp = spacy.load('en_core_web_md', disable = ['tagger', 'parser', 'ner'])
    with open('coco_words.txt') as f:
      self.vocab_words = f.read().split()

    # Only allow real words
    self.vocab_words = list(filter(lambda w: w.islower() and w in self.nlp.vocab, self.vocab_words))

    # Special vectors
    self.END_MARKER = np.zeros(301)
    self.END_MARKER[-1] = 1
    self.vocab_words.append('.')

  def get_word_embedding(self, word):
    if word == '.':
      return self.END_MARKER
    v = self.nlp.vocab.get_vector(word)
    v = np.append(v, [0])
    return v

  def get_word_from_index(self, ix):
    return self.vocab_words[ix]

  def get_index_from_word(self, word):
    return self.vocab_words.index(word)

  def sentence_to_embedding(self, text, pad):
    """Process natural language sentence into sequence of word vectors"""

    # Convert to lowercase and remove punctuation
    text = text.lower()
    text = ''.join([c for c in text if c not in string.punctuation])

    embeddings = []
    words = []
    for word in text.split():
      if word in self.vocab_words:
        words.append(word)
        embeddings.append(self.get_word_embedding(word))

    # Pad with periods if it's too short
    words = words[:pad]
    embeddings = embeddings[:pad]
    while len(words) < pad:
      words.append('.')
      embeddings.append(self.END_MARKER)

    return words, embeddings

def test():
  manager = WordEmbedding()
  print(manager.sentence_to_embedding('I have a Large Gray wabbit, she is cute'))

#test()


import io
import os
import subprocess

from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk
root = Tk()

#设置窗口大小
form_width = 1024
form_height = 768
#获取屏幕尺寸以计算布局参数，使窗口居屏幕中央
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (form_width, form_height, (screenwidth-form_width)/2, (screenheight-form_height)/2)
root.geometry(alignstr)
#设置窗口是否可变长、宽，True：可变，False：不可变
root.resizable(width=False, height=False)

#设置窗口标题
root.title('Animal Classifier')

#设置窗口图标
#root.iconbitmap('****.ico')

#setting up a tkinter canvas without scrollbars
frame = Frame(root, bd=0, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
canvas = Canvas(frame, bd=0)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
frame.pack(fill=BOTH,expand=1)

text = StringVar()
text.set('')

#对一个pil_image对象进行缩放，让它在一个矩形框内，还能保持比例
def resize(w, h, w_box, h_box, pil_image):
    f1 = 1.0*w_box/w # 1.0 forces float division in Python2
    f2 = 1.0*h_box/h
    factor = min([f1, f2])
    width = int(w*factor)
    height = int(h*factor)
    return pil_image.resize((width, height), Image.ANTIALIAS)

#function to be called when mouse is clicked
def printcoords():
    File = filedialog.askopenfilename(parent=root, initialdir="C:/",title='Choose an image.')

	#=================================================================
    w_box = 1024
    h_box = 700
    #以一个PIL图像对象打开
    pil_image = Image.open(File)
    #获取图像的原始大小
    w, h = pil_image.size
    pil_image_resized = resize(w, h, w_box, h_box, pil_image)
    #=================================================================

    filename = ImageTk.PhotoImage(pil_image_resized)
    canvas.image = filename  # <--- keep reference of your image
    canvas.create_image(0,0,anchor='nw',image=filename)

    #subprocess.getoutput("python classify_image.py --image_file="+ File)
    p = subprocess.Popen("python classify_image.py --image_file="+ File, stdout=subprocess.PIPE, shell=True)
    text.set(p.stdout.read())
    p.kill

lb = Label(root, textvariable=text)
lb.pack()
Button(root,text='Choose an image',command=printcoords).pack()

root.mainloop()


import pandas as pd
import statsmodels.api as sm
import numpy as np

class FeatureSelection(object):
    def __init__(self):
        pass

    @staticmethod
    def forward_selection(data, target, significance_level=0.05): # 9 pts
        forward_list = []
        N, D = data.shape
        x_final = np.ones((N, 1))
        used_feature = []

        for j in range(D):
            p_min = 1e3
            count_p = 0
            for i in range(D):
                if i in used_feature:
                    continue
                x = np.concatenate((x_final, data.values[:, i].reshape(N, 1)), axis=1)
                model = sm.OLS(target.values, x).fit()
                p = model.pvalues[-1]
                if p < significance_level:
                    count_p += 1
                    if p < p_min:
                        p_min = p
                        add_feature = i
            if count_p == 0:
                break
            x_final = np.concatenate((x_final, data.values[:, add_feature].reshape(N, 1)), axis=1)
            forward_list.append(data.axes[1][add_feature])
            used_feature.append(add_feature)

        return forward_list, x_final

    @staticmethod
    def backward_elimination(data, target, significance_level = 0.05): # 9 pts
        backward_list = data.axes[1].tolist()
        N, D = data.shape
        x_final = sm.add_constant(data.values)
        removed_feature = []
        for i in range(D):
            model = sm.OLS(target.values, x_final).fit()
            p_values = model.pvalues[1:]
            pmax_ind = np.argmax(p_values)
            if p_values[pmax_ind] > significance_level:
                removed_feature.append(backward_list[pmax_ind])
                x_final = np.delete(x_final, pmax_ind + 1, axis=1)
                del backward_list[pmax_ind]

            else:
                break

        return backward_list, x_final


"""
Mixins for the EnterpriseApiClient.
"""
import json
import mock

import httpretty
from django.conf import settings
from django.core.cache import cache

class EnterpriseServiceMockMixin(object):
    """
    Mocks for the Enterprise service responses.
    """

    def setUp(self):
        super(EnterpriseServiceMockMixin, self).setUp()
        cache.clear()

    @staticmethod
    def get_enterprise_url(path):
        """Return a URL to the configured Enterprise API. """
        return '{}{}/'.format(settings.ENTERPRISE_API_URL, path)

    def mock_enterprise_course_enrollment_post_api(  # pylint: disable=invalid-name
            self,
            username='test_user',
            course_id='course-v1:edX+DemoX+Demo_Course',
            consent_granted=True
    ):
        """
        Helper method to register the enterprise course enrollment API POST endpoint.
        """
        api_response = {
            username: username,
            course_id: course_id,
            consent_granted: consent_granted,
        }
        api_response_json = json.dumps(api_response)
        httpretty.register_uri(
            method=httpretty.POST,
            uri=self.get_enterprise_url('enterprise-course-enrollment'),
            body=api_response_json,
            content_type='application/json'
        )

    def mock_enterprise_course_enrollment_post_api_failure(self):  # pylint: disable=invalid-name
        """
        Helper method to register the enterprise course enrollment API endpoint for a failure.
        """
        httpretty.register_uri(
            method=httpretty.POST,
            uri=self.get_enterprise_url('enterprise-course-enrollment'),
            body='{}',
            content_type='application/json',
            status=500
        )

    def mock_enterprise_course_enrollment_get_api(self, **kwargs):
        result = {
            'results': [kwargs] if kwargs else []
        }
        httpretty.register_uri(
            method=httpretty.GET,
            uri=self.get_enterprise_url('enterprise-course-enrollment'),
            body=json.dumps(result),
            content_type='application/json',
            status=200
        )

    def mock_enterprise_learner_api(
            self,
            catalog_id=1,
            entitlement_id=1,
            learner_id=1,
            enterprise_customer_uuid='cf246b88-d5f6-4908-a522-fc307e0b0c59',
            enable_audit_enrollment=False,
    ):
        """
        Helper function to register enterprise learner API endpoint.
        """
        enterprise_learner_api_response = {
            'count': 1,
            'num_pages': 1,
            'current_page': 1,
            'results': [
                {
                    'id': learner_id,
                    'enterprise_customer': {
                        'uuid': enterprise_customer_uuid,
                        'name': 'TestShib',
                        'catalog': catalog_id,
                        'active': True,
                        'site': {
                            'domain': 'example.com',
                            'name': 'example.com'
                        },
                        'enable_data_sharing_consent': True,
                        'enforce_data_sharing_consent': 'at_login',
                        'enable_audit_enrollment': enable_audit_enrollment,
                        'enterprise_customer_users': [
                            1
                        ],
                        'branding_configuration': {
                            'enterprise_customer': enterprise_customer_uuid,
                            'logo': 'https://open.edx.org/sites/all/themes/edx_open/logo.png'
                        },
                        'enterprise_customer_entitlements': [
                            {
                                'enterprise_customer': enterprise_customer_uuid,
                                'entitlement_id': entitlement_id
                            }
                        ]
                    },
                    'user_id': 5,
                    'user': {
                        'username': 'verified',
                        'first_name': '',
                        'last_name': '',
                        'email': 'verified@example.com',
                        'is_staff': True,
                        'is_active': True,
                        'date_joined': '2016-09-01T19:18:26.026495Z'
                    },
                    'data_sharing_consent': [
                        {
                            'user': 1,
                            'state': 'enabled',
                            'enabled': True
                        }
                    ]
                }
            ],
            'next': None,
            'start': 0,
            'previous': None
        }
        enterprise_learner_api_response_json = json.dumps(enterprise_learner_api_response)

        httpretty.register_uri(
            method=httpretty.GET,
            uri=self.get_enterprise_url('enterprise-learner'),
            body=enterprise_learner_api_response_json,
            content_type='application/json'
        )

class EnterpriseTestConsentRequired(object):
    """
    Mixin to help test the data_sharing_consent_required decorator.
    """
    def verify_consent_required(self, client, url, status_code=200):
        """
        Verify that the given URL redirects to the consent page when consent is required,
        and doesn't redirect to the consent page when consent is not required.

        Arguments:
        * self: ignored
        * client: the TestClient instance to be used
        * url: URL to test
        * status_code: expected status code of URL when no data sharing consent is required.
        """
        with mock.patch('openedx.features.enterprise_support.api.enterprise_enabled', return_value=True):
            with mock.patch('openedx.features.enterprise_support.api.consent_necessary_for_course') as mock_consent_necessary:  # pylint: disable=line-too-long
                # Ensure that when consent is necessary, the user is redirected to the consent page.
                mock_consent_necessary.return_value = True
                response = client.get(url)
                assert response.status_code == 302
                assert 'grant_data_sharing_permissions' in response.url  # pylint: disable=no-member

                # Ensure that when consent is not necessary, the user continues through to the requested page.
                mock_consent_necessary.return_value = False
                response = client.get(url)
                assert response.status_code == status_code

                # If we were expecting a redirect, ensure it's not to the data sharing permission page
                if status_code == 302:
                    assert 'grant_data_sharing_permissions' not in response.url  # pylint: disable=no-member
                return response


import random
import pygame

from pygame import mixer
from Levels import LevelsGrid
from Levels import CheckpointCoords

pygame.mixer.pre_init(44100, -16, 2, 512)
pygame.init()
mixer.init()

screen_width = 1000
screen_height = 600

player_width = 30
player_height = 60

cubewidth = 40

window = pygame.display.set_mode((screen_width,screen_height))

clock = pygame.time.Clock()
fps = 60

#------------- FONT -------------#

font = pygame.font.SysFont('8bitwondernominal', 40, True)

#---------- BACKGROUND ----------#

BACKGROUND_PNG = pygame.image.load("Images/Background/background.png")

#--------- TEXT SPRITES ---------#

COLLECTALLCOINS_PNG = pygame.image.load("Images/Text/collectallcoins.png")

#--------- GAME SPRITES ---------#

BORDER_PNG = pygame.image.load("Images/Map_Sprites/border.png")
DIRT_PNG = pygame.image.load("Images/Map_Sprites/dirt.png")
GRASS_PNG = pygame.image.load("Images/Map_Sprites/grass.png")
ARROWRIGHT_PNG = pygame.image.load("Images/Map_Sprites/arrowright.png")
ARROWLEFT_PNG = pygame.image.load("Images/Map_Sprites/arrowleft.png")

FULLHEART_PNG = pygame.image.load("Images/Map_Sprites/fullheart.png")
EMPTYHEART_PNG = pygame.image.load("Images/Map_Sprites/emptyheart.png")

CLOSEDDOORBOTTOM_PNG = pygame.image.load("Images/Map_Sprites/closeddoorbottom.png")
CLOSEDDOORTOP_PNG = pygame.image.load("Images/Map_Sprites/closeddoortop.png")

OPENDOORBOTTOM_PNG = pygame.image.load("Images/Map_Sprites/opendoorbottom.png")
OPENDOORTOP_PNG = pygame.image.load("Images/Map_Sprites/opendoortop.png")

COIN_PNG = pygame.image.load("Images/Map_Sprites/coin.png")

LAVA_PNG = pygame.image.load("Images/Map_Sprites/lava.png")
LAVAWHOLE_PNG = pygame.image.load("Images/Map_Sprites/lavawhole.png")

LEVERLEFT_PNG = pygame.image.load("Images/Map_Sprites/leverleft.png")
LEVERRIGHT_PNG = pygame.image.load("Images/Map_Sprites/leverright.png")

#---------- GAME SOUNDS ---------#

LAVA_WAV = pygame.mixer.Sound("Sounds/lava.wav")
OPENDOOR_WAV = pygame.mixer.Sound("Sounds/opendoor.wav")
JUMP_WAV = pygame.mixer.Sound("Sounds/jump.wav")
COIN_WAV = pygame.mixer.Sound("Sounds/coin.wav")
ERROR_WAV = pygame.mixer.Sound("Sounds/error.wav")
NEXTLEVEL_WAV = pygame.mixer.Sound("Sounds/nextlevel.wav")
MENUTICK_WAV = pygame.mixer.Sound("Sounds/menutick.wav")
MENUSELECT_WAV = pygame.mixer.Sound("Sounds/menuselect.wav")

#------------ MUSIC -------------#

pygame.mixer.music.load("Sounds/music.wav")

#---------- GRID CODES ----------#

GRIDECODES = {
    1 : BORDER_PNG,
    2 : DIRT_PNG,
    3 : GRASS_PNG,
    4 : ARROWRIGHT_PNG,
    5 : ARROWLEFT_PNG,
    6 : CLOSEDDOORBOTTOM_PNG,
    7 : CLOSEDDOORTOP_PNG,
    8 : LAVAWHOLE_PNG,
    9 : LAVA_PNG,
    10 : COIN_PNG,
    11 : LEVERLEFT_PNG,
    12 : LEVERRIGHT_PNG
}

#------------ TILES -------------#

TILEBLOCKS = [1,2,3]

tile_list = []

#------------ PLAYER ------------#

class Player():
    def __init__(self, x, y, speed):
        self.images_right = []
        self.images_left = []
        self.index = 0
        self.counter = 0
        for num in range(1,5):
            img_right = pygame.image.load(f'Images/Player_Sprites/guy{num}.png')
            img_right = pygame.transform.scale(img_right, (player_width, player_height))
            img_left = pygame.transform.flip(img_right, True, False)
            self.images_right.append(img_right)
            self.images_left.append(img_left)
        self.image = self.images_right[self.index]
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.speed = speed
        self.vel_y = 0
        self.jumped = False
        self.direction = "R"
        self.landed = True
        self.health = 3

    def atcheckpoint(self,level):

        if CheckpointCoords[level][1]+40 > self.rect.y > CheckpointCoords[level][1]:
            if CheckpointCoords[level][0] < self.rect.x < CheckpointCoords[level][0]+40:
                return True

        return False

    def nearcheckpoint(self,level):

        if CheckpointCoords[level][1]+40 > self.rect.y > CheckpointCoords[level][1]:
            if CheckpointCoords[level][0]-40 < self.rect.x < CheckpointCoords[level][0]+40:
                window.blit(OPENDOORTOP_PNG, (CheckpointCoords[level][0], CheckpointCoords[level][1]))
                window.blit(OPENDOORBOTTOM_PNG, (CheckpointCoords[level][0], CheckpointCoords[level][1] + 40))
                return True

        return False

    def drawhealth(self):

        gap = 10
        first_gap = 50

        first_empty_gap = 146

        for i in range(self.health):
            window.blit(FULLHEART_PNG, (first_gap+ 38*i+gap*i, first_gap))

        for i in range(3-self.health):
            window.blit(EMPTYHEART_PNG, (first_empty_gap-38*i-gap*i, first_gap))

    def update(self,drawhitbox,level):

        key = pygame.key.get_pressed()

        dx = 0
        dy = 0

        walk_cooldown = 10

        if key[pygame.K_0]:
            print (self.rect.x, self.rect.y)
        if key[pygame.K_SPACE] and self.jumped == False and self.landed == True:
            if playsound: JUMP_WAV.play()
            self.vel_y = -15
            self.landed = False
            self.jumped = True
        if not(key[pygame.K_SPACE]):
            self.jumped = False
        if key[pygame.K_a] or key[pygame.K_LEFT]:
            self.direction = "L"
            self.counter += 1
            dx -= self.speed
        if key[pygame.K_d] or key[pygame.K_RIGHT]:
            self.direction = "R"
            self.counter += 1
            dx += self.speed
        if key[pygame.K_a] == False and key[pygame.K_LEFT] == False and key[pygame.K_d] == False and key[pygame.K_RIGHT] == False:
            self.index = 0
            self.counter = 0
            if self.direction == "R":
                self.image = self.images_right[self.index]
            else:
                self.image = self.images_left[self.index]

        if self.counter > walk_cooldown:
            self.counter = 0
            self.index += 1
            if self.index >= len(self.images_right):
                self.index = 0
            if self.direction == "R":
                self.image = self.images_right[self.index]
            else:
                self.image = self.images_left[self.index]

        self.vel_y += 1
        if self.vel_y > 10:
            self.vel_y = 10
        dy += self.vel_y

        for tile in tile_list:
            if tile.colliderect(self.rect.x + dx, self.rect.y, player_width, player_height):
                dx = 0
            if tile.colliderect(self.rect.x, self.rect.y + dy, player_width, player_height):
                if self.vel_y < 0:
                    dy = tile.bottom - self.rect.top
                    self.vel_y = 0
                elif self.vel_y >= 0:
                    self.landed = True
                    dy = tile.top - self.rect.bottom
                    self.vel_y = 0

        for tile in lava_list:
            if tile.colliderect(self.rect.x, self.rect.y + dy-20, player_width, player_height):
                if playsound:
                    LAVA_WAV.play()
                player.takedamage()

        for i in range(len(coin_list)):
            tile = coin_list[i]
            if tile.colliderect(self.rect.x, self.rect.y, player_width, player_height):
                if playsound: COIN_WAV.play()
                LevelsGrid[level][coin_coords[i][0]][coin_coords[i][1]] = 0
                coin_coords.pop(i)
                coin_list.pop(i)
                break

        self.rect.x += dx
        self.rect.y += dy

        window.blit(self.image, self.rect)
        if drawhitbox:
            pygame.draw.rect(window, (255, 255, 255), self.rect, 2)

    def takedamage(self):

        player.health -= 1
        if player.health > 0:
            player.rect.x = 45
            player.rect.y = screen_height - player_height - 80
        else:
            outoflives()

player = Player(45, screen_height-player_height-80, 4)

def fadenextlevel():
    fade = pygame.Surface((screen_width,screen_height))
    fade.fill((0,0,0))
    if playsound: NEXTLEVEL_WAV.play()
    for alpha in range(75):
        fade.set_alpha(alpha)
        window.blit(fade,(0,0))
        pygame.display.update()
        pygame.time.delay(20)

def outoflives():
    main_menu()

def drawgrid(LevelsGrid,level,drawhitbox, newlevel):

    global tile_list
    global lava_list
    global coin_list
    global coin_coords

    if newlevel:
        tile_list = []
        lava_list = []
        coin_list = []
        coin_coords = []

    window.blit(BACKGROUND_PNG, (0,0))

    for row in range(15):
        for coloumn in range(25):
            if LevelsGrid[level][row][coloumn] != 0:
                img = GRIDECODES[LevelsGrid[level][row][coloumn]]
                img_rect = img.get_rect()
                img_rect.x = coloumn*cubewidth
                img_rect.y = row*cubewidth

                window.blit(img,(img_rect.x,img_rect.y))

                if LevelsGrid[level][row][coloumn] in TILEBLOCKS:
                    if newlevel:
                        tile_list.append(img_rect)
                    if drawhitbox:
                        pygame.draw.rect(window,(255,255,255),(coloumn*cubewidth,row*cubewidth,cubewidth,cubewidth),1)

                if LevelsGrid[level][row][coloumn] == 10:
                    if newlevel:
                        coin_coords.append([row,coloumn])
                        coin_list.append(img_rect)
                    if drawhitbox:
                        pygame.draw.rect(window,(255,255,255),(coloumn*cubewidth,row*cubewidth+15,cubewidth,cubewidth),1)

                if LevelsGrid[level][row][coloumn] == 9:
                    if newlevel:
                        lava_list.append(img_rect)
                    if drawhitbox:
                        pygame.draw.rect(window,(255,255,255),(coloumn*cubewidth,row*cubewidth+15,cubewidth,cubewidth),1)
    return False

def pause():

    loop = True
    cursor_index = 1

    while loop:

        pygame.draw.rect(window,(0,0,0),(100,100,800,400))
        pygame.draw.rect(window,(255,255,255),(110,110,780,380),4)
        drawtext("Pause",400,150)
        drawtext("Back",400,350)
        drawtext("*",350,350)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    loop = False
                    if playsound: MENUSELECT_WAV.play()
                if event.key == pygame.K_RETURN:
                    if playsound: MENUSELECT_WAV.play()
                    loop = False

        pygame.display.update()

def drawtext(string,x,y):

    text_surface = font.render(string, True, (255,255,255))
    window.blit(text_surface, (x,y))

def draw_main_menu(cursor_location,cursor_locations):

    window.fill((0,0,0))
    drawtext("Main Menu", 300,200)
    drawtext("Play", 250,350)
    drawtext("Options", 250,400)
    drawtext("Credits", 250,450)
    cursor_y = cursor_locations[cursor_location]
    drawtext("*", 200, cursor_y)
    pygame.display.update()

def options():

    global playsound

    index = 0
    loop = True
    if playsound == True:
        onoff = "on"
    else:
        onoff = "off"

    while loop:

        window.fill((0, 0, 0))
        drawtext("Options", 300, 200)
        drawtext("Main Menu", 250, 450)
        drawtext(f"Sound {onoff}",275, 300)

        if index == 0:
            drawtext("*", 200, 450)
        else:
            drawtext("*", 225, 300)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    if playsound: MENUSELECT_WAV.play()
                    if index == 0:
                        loop = False
                    else:
                        if onoff == "on":
                            onoff = "off"
                            playsound = False
                        else:
                            onoff = "on"
                            playsound = True

                if event.key == pygame.K_w and index != 1:
                    if playsound: MENUSELECT_WAV.play()
                    index += 1
                if event.key == pygame.K_s and index != 0:
                    if playsound: MENUSELECT_WAV.play()
                    index -= 1

        pygame.display.update()

def credits():

    window.fill((0,0,0))
    drawtext("Credits", 300,200)
    drawtext("Me LOL", 300,280)

    drawtext("Main Menu", 250, 450)
    drawtext("*", 200, 450)

    pygame.display.update()

    loop = True
    while loop:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    if playsound: MENUSELECT_WAV.play()
                    loop = False

def main_menu():

    global playsound

    mainmenu = True
    cursor_index = 0
    cursor_locations = [350,400,450]
    playsound = True

    while mainmenu:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_w and cursor_index > 0:
                    if playsound: MENUTICK_WAV.play()
                    cursor_index -= 1
                if event.key == pygame.K_s and cursor_index < 2:
                    if playsound: MENUTICK_WAV.play()
                    cursor_index += 1
                if event.key == pygame.K_RETURN:
                    if playsound: MENUSELECT_WAV.play()
                    if cursor_index == 0:
                        mainmenu = False
                    elif cursor_index == 1:
                        options()
                    elif cursor_index == 2:
                        credits()

        draw_main_menu(cursor_index,cursor_locations)

    main()

def main():
    clock.tick(fps)

    player.health = 3

    run = True
    drawhitbox = False

    if playsound: pygame.mixer.music.play(-1,0)

    level = 0
    newlevel = True

    while run:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pause()

        newlevel = drawgrid(LevelsGrid,level,drawhitbox,newlevel)
        AtDoor = player.nearcheckpoint(level)

        if AtDoor:
            if replay:
                replay = False
                if playsound: OPENDOOR_WAV.play()
            if player.atcheckpoint(level):
                if len(coin_list) == 0:
                    fadenextlevel()
                    level += 1
                    newlevel = True
                    player.rect.x = 45
                    player.rect.y = screen_height-player_height-80
                else:
                    if replay2:
                        if playsound: ERROR_WAV.play()
                        replay2 = False
                    window.blit(COLLECTALLCOINS_PNG,(150,250))
                    pygame.display.update()
            else:
                replay2 = True
        else:
            replay = True

        player.update(drawhitbox, level)
        player.drawhealth()

        pygame.display.update()

main_menu()