# Virtual Ball Toss Game
# version of 'Cyberball' - https://www.ncbi.nlm.nih.gov/pubmed/16817529
# for PsychoPy (using Python2.7)

# developed by for use as an fMRI task by the Communication Neuroscience Lab
# original Matlab implementation by Josh Carp
# PsychoPy Python version by Matt O'Donnell (mbod@asc.upenn.edu)

# Edited for "Mental Attention and Visualization" Exp 1 by: Nomi, Alex, and Megan

from psychopy import visual, core, logging, event, data, gui
import sys
import random
import csv
import serial
import os
import time
from random import shuffle

#################
#  PARAMETERS #
#################

maxTime=75 #length of time that player is allowed to hold ball before round ends (should be 75)
maxTrials=30 #number of throws allowed per round (should be 30)
incRounds=1 #number of inclusive rounds - (should be 1)
exRounds=3 #number of exclusive rounds - (should be 3)

#set variables below
holder=1
round=1
trialCnt=0
rndCnt=0
condition="FBALL"

# create first set of instructions for ball-tossing
instructions1 = '''
For the next part of the experiment, we will test the effects of practicing mental visualization on task performance, so we need you to practice your mental visualization skills. We have found that the best way to do this is to have you play an online ball tossing game with other participants who are logged on to the system at the same time.

In a few moments, you will be playing a ball-tossing game with other participants over our network.
'''

# create second set of instructions for ball-tossing
instructions2 = '''
The game is very simple. If you are right-handed, put your pointer finger on the "2" key and your middle finger on the "3" key. If you are left-handed, put your middle finger on the "2" key and your pointer finger on the "3" key.

When the ball is tossed to you, simply press either the "2" key to throw to the player on your left or the "3" key to throw to the player on your right. When the game is over, the next part of the experiment will begin.

What is important is not your ball tossing performance, but that you MENTALLY VISUALIZE the entire experience. Imagine what the other players look like. What sort of people are they? Where are you playing? Is it warm and sunny or cold and rainy? Create in your mind a complete mental picture of what might be going on if you were playing this game in real life.'''

# create GUI for subject information tracking
subjDlg = gui.Dlg(title="App Task")
subjDlg.addField('Enter Subject ID:')
subjDlg.addField('Player name:')
subjDlg.addField('Room:')
subjDlg.addField('Experiment: ')
subjDlg.show()

# move forward as long as the GUI information is valid
if gui.OK:
    subj_id=subjDlg.data[0]
    player_name=subjDlg.data[1]
    round_number=subjDlg.data[2] #add round input
    exp_cond=int(subjDlg.data[3]) #condition type: 0 (exclusion), 1 (inclusion)
    try:
        room = int(subjDlg.data[2])-1
    except:
        room=0
else:
    sys.exit()

# use gender-neutral names, assigned by room number
players=[["Jesse", "Max"],
         ["Alex", "Robin"],
         ["Kai", "Adrian"]]
player1_name = players[room][0]
player3_name = players[room][1]

################
# Set up images (for players) #
################
paths = [d for d in os.listdir('images') if d[1:3]=='to']
throw={}
for p in paths:
    throw[p]=[f for f in os.listdir('images/%s' % p) if f.endswith('.bmp')]

################
# Set up window #
################

useFullScreen=True #Set to true for full screen
win = visual.Window([2560, 1440], monitor="testMonitor", units="deg", fullscr=useFullScreen, allowGUI=False, color="#FFFFFF") # Size for personal Macs (for testing): [1680, 1050], size for lab Mac (for collection): [2560, 1440]

################
# Set up text #
################

title=visual.TextStim(win,text="Mental Visualization and Attention", height=1, pos=(0,10),color="#000000", alignHoriz="center", alignVert="top")
instrText = visual.TextStim(win, text="",height=1, color="#000000", wrapWidth=25) #empty text, optional to fill
instrKey = visual.TextStim(win, text="", height=1, color="#000000", pos=(0,-10))
instr_p1 = visual.TextStim(win, text="",color="#000000", pos=(-6,3), height=1, alignHoriz="left")
instr_p2 = visual.TextStim(win, text="",color="#000000", pos=(-6, 0), height=1, alignHoriz="left")
instr_p3 = visual.TextStim(win, text="",color="#000000", pos=(-6, -3), height=1, alignHoriz="left")
p1_tick = visual.TextStim(win,text="", color="#000000", pos=(3.5,3), alignHoriz="left")
p3_tick = visual.TextStim(win,text="", color="#000000", pos=(3.5,-3), alignHoriz="left")

# set instructions
instr1 = visual.TextStim(win, text='''Thank you for participating in our experiment!

This experiment is about mental visualization.

First, you'll be asked to answer a series of questions. This scale consists of a number of statements that describe different feelings and emotions.

Read each item and then mark the appropriate answer. Indicate to what extent you agree with each statement right now.

Press any key to continue.''' , color="#000000", alignHoriz="center")
instr2= visual.TextStim(win, text="", height=1, alignHoriz="center", color="#000000")
instr3= visual.TextStim(win, text='''You'll now be asked to answer a series of questions. This scale consists of a number of statements that describe different feelings and emotions.

Read each item and then mark the appropriate answer. Indicate to what extent you agree with each statement right now.

Press any key to continue.''' , height=1, alignHoriz="center", color="#000000")
imagestart= visual.TextStim(win, text="You will now view a series of images. Each image will appear for 20 seconds. Try to visualize yourself actually being in each scene.", height=1, color="#000000", alignHoriz="center")

players = visual.SimpleImageStim(win, image='images/start.bmp')

round_fix = visual.TextStim(win, text="", height=1, color="#000000")

fixation = visual.TextStim(win, text="Please wait...", height=2, color="#000000")

goodbye = visual.TextStim(win,text="",color="#000000")

p1name = visual.TextStim(win,text=player1_name,color="#000000", pos=(-6,2), height=0.5)
p2name = visual.TextStim(win,text=player_name,color="#000000", pos=(0,-5), height=0.5)
p3name = visual.TextStim(win,text=player3_name,color="#000000", pos=(6,2), height=0.5)

ready_screen = visual.TextStim(win, text="Ready.....", height=1.2, color="#000000")

#==============================
# Survey
#==============================
# PANAS
q1="I feel interested."
q2= "I feel distressed."
q3= "I feel excited."
q4= "I feel upset."
q5="I feel strong."
q6="I feel guilty."
q7="I feel scared."
q8="I feel hostile."
q9="I feel enthusiastic."
q10="I feel proud."
q11="I feel irritable."
q12="I feel alert."
q13="I feel ashamed."
q14="I feel inspired."
q15="I feel nervous."
q16="I feel determined."
q17="I feel attentive."
q18="I feel jittery."
q19="I feel active."
q20="I feel afraid."
# BFNE Revised
q21="I worry about what other people will think of me even when I know it doesn't make a difference."
q22="It bothers me when people form an unfavorable impression of me."
q23="I am frequently afraid of other people noticing my shortcomings."
q24="I worry about what kind of impression I make on people."
q25="I am afraid that others will not approve of me."
q26="I am concerned about other people's opinions of me."
q27="When I am talking to someone, I worry about what they may be thinking of me."
q28="I am usually worried about what kind of impression I make."
q29="If I know someone is judging me, it tends to bother me."
q30="Sometimes I think I am too concerned with what other people think of me."
q31="I often worry that I will say or do wrong things."
#create question library
qlibrary = {1:q1, 2:q2, 3:q3, 4:q4, 5:q5, 6:q6, 7:q7, 8:q8, 9:q9, 10:q10, 11:q11, 12:q12, 13:q13, 14:q14, 15:q15, 16:q16, 17:q17, 18:q18, 19:q19, 20:q20, 21:q21, 22:q22, 23:q23, 24:q24, 25:q25, 26:q26, 27:q27, 28:q28, 29:q29, 30:q30, 31:q31}
questions = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] #list of qs

# setting up the stimuli for eye-tracking
piktures = 56 #numbers of pictures in folder
pix = list(range(0, piktures))
shuffle(pix) #randomized order of pictures

# intro survey
def survey_intro():
    shuffle(questions) #randomize order of questions
    event.clearEvents()
    instr1.draw()
    win.flip()
    if 'escape' in event.waitKeys():
        core.quit()
    for i in questions:
        myRatingScale = visual.RatingScale(win, choices=['      1:\nvery slightly/\nnot at all', '    2:\na little', '       3:\nmoderately', '        4:\nquite a bit', '      5:\nextremely'], stretch=2.4, textColor='Black', lineColor='Black', showValue=False, acceptText='continue')
        myItem = visual.TextStim(win, text=qlibrary[i], height=.07, units='norm', color="#000000")
        event.clearEvents()
        while myRatingScale.noResponse:  # show & update until a response has been made
            myItem.draw()
            myRatingScale.draw()
            win.flip()
            if event.getKeys(['escape']):
                core.quit()
        response = myRatingScale.getRating()
        logging.log(level=logging.DATA, msg="Question Number: %i , Response: %s" % (i, response))

# show the stimulus images
def show_images():
    event.clearEvents()
    instr2.draw()
    instrKey.setText('''

    PRESS 2 to continue''')
    instrKey.draw()
    win.flip()
    event.waitKeys(keyList=['2'])
    imagestart.draw()
    win.flip()
    core.wait(9)
    event.clearEvents()
    for k in pix:
        pic = visual.ImageStim(win, image='showpics/%i.png' % (k+1))
        logging.log(level=logging.DATA, msg="PICTURE: %i.png" % (k+1)) # logging picture order ???
        print(k+1)
        pic.size*=(0.7, 0.7) # resize images here (good at 0.7, 0.7 for lab mac)
        pic.draw()
        pic.draw()
        win.flip()
        core.wait(20) #set how long images stay (should be 20)

        # show the blank image between trials
        reset_image =  visual.ImageStim(win, image= 'blank/blank.png')
        logging.log(level=logging.DATA, msg="PICTURE: reset_image") # logging reset img
        print(reset_image)
        reset_image.size*=(0.7, 0.7) # resize images here (good at 0.7, 0.7 for lab mac)
        reset_image.draw()
        reset_image.draw()
        win.flip()
        core.wait(1) # set how long reset image would stay (in sec)
    win.flip()

# ending survey
def survey_outro():
    shuffle(questions) #randomize order of questions
    event.clearEvents()
    instr3.draw()
    win.flip()
    if 'escape' in event.waitKeys():
        core.quit()
    for i in questions:
        myRatingScale = visual.RatingScale(win, choices=['      1:\nvery slightly/\nnot at all', '    2:\na little', '       3:\nmoderately', '        4:\nquite a bit', '      5:\nextremely'], stretch=2.4, textColor='Black', lineColor='Black', showValue=False, acceptText='continue')
        myItem = visual.TextStim(win, text=qlibrary[i], height=.07, units='norm', color="#000000")
        event.clearEvents()
        while myRatingScale.noResponse:  # show & update until a response has been made
            myItem.draw()
            myRatingScale.draw()
            win.flip()
            if event.getKeys(['escape']):
                core.quit()
        response = myRatingScale.getRating()
        logging.log(level=logging.DATA, msg="Question Number: %i , Response: %s" % (i, response))

# Showing text and instructions for tossing game
def show_instructions():
    title.setAutoDraw(True)
    instrText.setText(instructions1)
    instrText.setAutoDraw(True)
    win.flip()
    instrKey.setText('''

    PRESS 2 to continue''')
    instrKey.draw()
    win.flip()
    event.waitKeys(keyList=['2'])
    instrText.setText(instructions2)
    win.flip()
    instrKey.setText('''

    PRESS 3 to begin''')
    instrKey.draw()
    win.flip()
    event.waitKeys(keyList=['3'])
    instrText.setAutoDraw(False)

    p1_ticker="."
    p3_ticker="."
    p1_ticker_end=45 #time to load players: make longer for more realistic interactive game
    p3_ticker_end=125

    title.setText('Joining VBT Game Room')
    instr_p1.setText("PLAYER 1: Waiting for player to join") #loading screen
    instr_p2.setText("PLAYER 2: Welcome %s" % player_name)
    instr_p3.setText("PLAYER 3: Waiting for player to join")
    instr_p1.setAutoDraw(True)
    instr_p2.setAutoDraw(True)
    instr_p3.setAutoDraw(True)
    p1_tick.setAutoDraw(True)
    p3_tick.setAutoDraw(True)
    win.flip()
    for tick in range(400):
        if tick == p1_ticker_end:
            instr_p1.setText("PLAYER 1: Welcome %s" % player1_name)
            p1_tick.setAutoDraw(False)
        elif tick == p3_ticker_end:
            instr_p3.setText("PLAYER 3: Welcome %s" % player3_name)
            p3_tick.setAutoDraw(False)
        else:
            if tick % 10 == 0:
                p1_ticker = p1_ticker + "."
                if len(p1_ticker)>6:
                    p1_ticker=""
            if tick % 12 == 0:
                p3_ticker = p3_ticker + "."
                if len(p3_ticker)>6:
                    p3_ticker=""
            if tick < p1_ticker_end:
                p1_tick.setText(p1_ticker)
            if tick < p3_ticker_end:
                p3_tick.setText(p3_ticker)
        win.flip()
    core.wait(2)

    title.setAutoDraw(False)
    instr_p1.setAutoDraw(False)
    instr_p2.setAutoDraw(False)
    instr_p3.setAutoDraw(False)

# setting up the player names
def player_names(state=True):
    p1name.setAutoDraw(state)
    p2name.setAutoDraw(state)
    p3name.setAutoDraw(state)

# log the throw and add counters to roundcount and trialcount
def throw_ball(fromP, toP):
    global trialCnt, holder, rndCnt
    key = "%ito%i" % (fromP,toP)

    # update logs
    logging.log(level=logging.DATA, msg="round %i - trial %i - throw: %s - %s" % (round, trialCnt, key, condition))

    # convert the dict into a sorted list
    sorted_images = []
    for next_image in throw[key]:
        sorted_images.append(next_image)
    sorted_images.sort()

    # create throwing animation
    for s in sorted_images:
        logging.log(level=logging.DATA, msg="current s variable: %s" % (s))
        players.setImage('images/%s/%s' % (key,s))
        players.draw()
        win.flip()
        core.wait(0.15)

    # update trial and round counters
    trialCnt+=1
    rndCnt+=1

    # set the new holder to be the person to whom it was thrown
    holder=toP
    logging.flush()
    select_throw()

# allow the participant to throw the ball
def select_throw(): #runs if subject has ball
    global condition
    if holder==2: #if subject has ball

        # update logs to reflect participant ownership
        logging.log(level=logging.DATA,msg="PLAYER HAS BALL")
        got_ball_time = trialClock.getTime()

        # loop to wait for the participant to choose
        choice=[]
        while len(choice)==0 or choice [0] not in ('2','3'):
            core.wait(0.01)
            if trialCnt > maxTrials or trialClock.getTime() > maxTime: #end round if player takes too long/ there have been too many tosses
                return
            choice = event.getKeys(keyList=['2','3'])

        # once the participant chooses, log it
        if choice[0]=='2':
            throwTo=1
        elif choice[0]=='3':
            throwTo=3

        # log the participant's throw
        logging.log(level=logging.DATA,
                    msg="PLAYER THROWS TO %i - RT %0.4f" % (throwTo, trialClock.getTime()-got_ball_time))
    else:
        core.wait(random.randint(500,2000)/1000) #range for simulation to "decide" where to throw

        # in the exclusionary condition, make it less likely that the participant will get the ball after # of inclusive rounds is exceeded
        if round>incRounds and exp_cond==0:
            condition="UBALL" # exclusive condition
            ft = 0.3

        # if it's not the exclusionary condition or if it hasn't reached the right number of rounds, don't alter probability
        else:
            ft = 0.0

        # change equation so subject is less likely to recieve ball
        throwChoice = random.random() - ft
        if throwChoice < 0.5:
            if holder==1:
                throwTo=3
            else:
                throwTo=1
        else:
            throwTo=2

    # if it's the last trial or if maximum time has elapsed, log and leave
    if trialCnt > maxTrials or trialClock.getTime() > maxTime:
        logging.log(level=logging.DATA,
                    msg="RETURN with %i Trial Count and %i Trial Clock" % (trialCnt, trialClock.getTime()))
        return

    # if we haven't reached the maximum round count or the maximum time, keep throwing
    else:
        throw_ball(holder,throwTo)

# counting # of rounds
def play_round():

    # create roundcount variable
    global rndCnt
    rndCnt=0

    # log current round
    logging.log(level=logging.DATA, msg="Displaying Round %i label" % round)

    # update text and draw the current round
    round_fix.setText("Round %i" % round)
    round_fix.draw()
    win.flip()
    core.wait(2)
    logging.log(level=logging.DATA, msg="Starting Round %i" % round)
    trialClock.reset()
    players.draw()
    player_names(True)
    title.setText('Press "2" to throw to your left           Press "3" to throw to your right')
    title.setAutoDraw(True)
    win.flip()
    core.wait(0.2)
    select_throw()
    player_names(False)
    title.setText("")
    fixation.draw()
    win.flip()
    core.wait(5)

# ================================
# setup logging #
# ================================
log_file = logging.LogFile("logs/%s.log" % (subj_id),  level=logging.DATA, filemode="w")
logging.log(level=logging.DATA, msg="START")

logging.log(level=logging.DATA, msg="Intro Survey")

#starting the INTRO SURVEY
survey_intro()
show_instructions()
ready_screen.setText('''Press Space to start''')
ready_screen.draw()
win.flip()
event.waitKeys(keyList=['space'])

#################
# Trigger scanner # WHAT DOES THIS DO ??
#################
globalClock = core.Clock()
trialClock = core.Clock()
logging.setDefaultClock(globalClock)

# ADD TRIGGER CODE - 255 on serial port - if scanner is expecting to receive a 'start' trigger
# from task
# some scanners may send a trigger code (i.e. a '5' or a 't') on each TR
# in which case code here should be adapted (or above where task waits for a space bar to start)
try:
    ser = serial.Serial('/dev/tty.KeySerial1', 9600, timeout=1)
    ser.write('0')
    time.sleep(0.1)
    ser.write('255')
    ser.close()
except:
    #print ("SCANNER NOT TRIGGERED")
    pass
# end of trigger code

# 8 sec disdaq
title.setText('')
fixation.setText("Please wait...")
fixation.draw()
win.flip()
core.wait(1)

# play all inclusive rounds first
while round<=incRounds:
    play_round()
    holder=1
    trialCnt=0
    round+=1

# play all exclusive rounds next
while (round-incRounds)<=exRounds:
    play_round()
    holder=1
    trialCnt=0
    round+=1

# calling stimuli and final survey
show_images() #show images
survey_outro() #show survey again
goodbye.setText('''You have completed this research study. Thank you for your participation!

Please remove the eyetracker and get the experimenter. The experimenter will then give you more information about the purpose of this study and give you the opportunity to ask questions.''')
goodbye.draw()
win.flip()
core.wait(15)
logging.log(level=logging.DATA, msg="END")


# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from config.template_middleware import TemplateResponse
from tekton import router
from gaecookie.decorator import no_csrf
from comment_app import comment_facade
from routes.comments import new, edit
from tekton.gae.middleware.redirect import RedirectResponse
from gaepermission.decorator import login_required

@login_required
@no_csrf
def index():
    cmd = comment_facade.list_comments_cmd()
    comments = cmd()
    edit_path = router.to_path(edit)
    delete_path = router.to_path(delete)
    comment_form = comment_facade.comment_form()

    def localize_comment(comment):
        comment_dct = comment_form.fill_with_model(comment)
        comment_dct['edit_path'] = router.to_path(edit_path, comment_dct['id'])
        comment_dct['delete_path'] = router.to_path(delete_path, comment_dct['id'])
        return comment_dct

    localized_comments = [localize_comment(comment) for comment in comments]
    context = {'comments': localized_comments,
               'new_path': router.to_path(new)}
    return TemplateResponse(context, 'comments/comment_home.html')

@login_required
def delete(comment_id):
    comment_facade.delete_comment_cmd(comment_id)()
    return RedirectResponse(router.to_path(index))


import math

print("===SISTEM PENDUKUNG KEPUTUSAN UNTUK TRANSAKSI PEMBELIAN MOBIL===")
# INPUTSPEK
print(" ")
print("Masukkan spesifikasi mobil ke-1 :")
M1 = {
    'M1id': input('Masukkan merk mobil '),
    'M1C1': int(input('Berapa harga mobil yang ditawarkan? ')),
    'M1C2': int(input('Berapa jumlah penumpang maksimum? ')),
    'M1C3': int(input('Berapa jumlah konsumsi bahan bakar? ')),
    'M1C4': int(input('Berapa tenaga yang dihasilkan oleh mesin? '))
}

print('')
print("Masukkan spesifikasi mobil ke-2 :")
M2 = {
    'M2id': input('Masukkan merk mobil '),
    'M2C1': int(input('Berapa harga mobil yang ditawarkan? ')),
    'M2C2': int(input('Berapa jumlah penumpang maksimum? ')),
    'M2C3': int(input('Berapa jumlah konsumsi bahan bakar? ')),
    'M2C4': int(input('Berapa tenaga yang dihasilkan oleh mesin? '))
}
print('')

print("Masukkan spesifikasi mobil ke-3 :")
M3 = {
    'M3id': input('Masukkan merk mobil '),
    'M3C1': int(input('Berapa harga mobil yang ditawarkan? ')),
    'M3C2': int(input('Berapa jumlah penumpang maksimum? ')),
    'M3C3': int(input('Berapa jumlah konsumsi bahan bakar? ')),
    'M3C4': int(input('Berapa tenaga yang dihasilkan oleh mesin? '))
}
print('')
print("Masukkan spesifikasi mobil ke-4 :")
M4 = {
    'M4id': input('Masukkan merk mobil '),
    'M4C1': int(input('Berapa harga mobil yang ditawarkan? ')),
    'M4C2': int(input('Berapa jumlah penumpang maksimum? ')),
    'M4C3': int(input('Berapa jumlah konsumsi bahan bakar? ')),
    'M4C4': int(input('Berapa tenaga yang dihasilkan oleh mesin? '))
}
print('')
print("Masukkan spesifikasi mobil ke-5 :")
M5 = {
    'M5id': input('Masukkan merk mobil '),
    'M5C1': int(input('Berapa harga mobil yang ditawarkan? ')),
    'M5C2': int(input('Berapa jumlah penumpang maksimum? ')),
    'M5C3': int(input('Berapa jumlah konsumsi bahan bakar? ')),
    'M5C4': int(input('Berapa tenaga yang dihasilkan oleh mesin? '))
}

# PEMBOBOTAN
print(" ")
print("===BOBOT PERTIMBANGAN===")
W1 = 0
while not int(W1) in range(1, 5):
    W1 = input('Dari angka 1-5, seberapa pentingkah harga mobil? ')
    if W1.isdigit() and 1 <= int(W1) <= 5:
        break
    print("Input tidak diterima")

W2 = 0
while not int(W2) in range(1, 5):
    W2 = input('Dari angka 1-5, seberapa pentingkah kapasitas penumpang? ')
    if W2.isdigit() and 1 <= int(W2) <= 5:
        break
    print("Input tidak diterima")

W3 = 0
while not int(W3) in range(1, 5):
    W3 = input('Dari angka 1-5, seberapa pentingkah konsumsi BBM? ')
    if W3.isdigit() and 1 <= int(W3) <= 5:
        break
    print("Input tidak diterima")

W4 = 0
while not int(W4) in range(1, 5):
    W4 = input('Dari angka 1-5, seberapa pentingkah tenaga mesin? ')
    if W4.isdigit() and 1 <= int(W4) <= 5:
        break
    print("Input tidak diterima")

W1 = float(W1)
W2 = float(W2)
W3 = float(W3)
W4 = float(W4)

a = [W1, W2, W3, W4]
b = math.fsum(a)
#print(b)

w1 = W1 / b
w1 = w1 * -1
#print("W1 :", w1)
w2 = W2 / b
#print("W2 :", w2)
w3 = W3 / b
#print("W3 :", w3)
w4 = W4 / b
#print("W4 :", w4)

# RANKING
S1 = pow(M1['M1C1'], w1) * pow(M1['M1C2'], w2) * pow(M1['M1C3'], w3) * pow(M1['M1C4'], w4)
#print("Nilai S1 adalah :", S1)
S2 = pow(M2['M2C1'], w1) * pow(M2['M2C2'], w2) * pow(M2['M2C3'], w3) * pow(M2['M2C4'], w4)
#print("Nilai S2 adalah :", S2)
S3 = pow(M3['M3C1'], w1) * pow(M3['M3C2'], w2) * pow(M3['M3C3'], w3) * pow(M3['M3C4'], w4)
#print("Nilai S3 adalah :", S3)
S4 = pow(M4['M4C1'], w1) * pow(M4['M4C2'], w2) * pow(M4['M4C3'], w3) * pow(M4['M4C4'], w4)
#print("Nilai S4 adalah :", S4)
S5 = pow(M5['M5C1'], w1) * pow(M5['M5C2'], w2) * pow(M5['M5C3'], w3) * pow(M5['M5C4'], w4)
#print("Nilai S5 adalah :", S5)

c = [S1, S2, S3, S4, S5]
d = math.fsum(c)
#print(d)

V1 = S1 / d
V2 = S2 / d
V3 = S3 / d
V4 = S4 / d
V5 = S5 / d

e = {
    'V1':V1,
    'V2':V2,
    'V3':V3,
    'V4':V4,
    'V5':V5
    }
f = max(e, key=e.get)

if f == "V1":
    print("Mobil",M1['M1id'],"dapat dipertimbangkan untuk dipilih")
elif f == "V2":
    print("Mobil",M2['M2id'],"dapat dipertimbangkan untuk dipilih")
elif f == "V3":
    print("Mobil",M3['M3id'],"dapat dipertimbangkan untuk dipilih")
elif f== "V4":
    print("Mobil",M4['M4id'],"dapat dipertimbangkan untuk dipilih")
elif f == "V5":
    print("Mobil",M5['M5id'],"dapat dipertimbangkan untuk dipilih")


import logging
import datetime

from pylons import request, response, session, tmpl_context as c, url
from pylons.controllers.util import abort, redirect
from pylons.decorators import jsonify

from porick.lib.auth import authorize
from porick.lib.base import BaseController, render
import porick.lib.helpers as h
from porick.model import (db, QSTATUS, Quote, VoteToUser,
                          ReportedQuotes, DeletedQuotes, now)

log = logging.getLogger(__name__)

class ApiV1Controller(BaseController):

    @jsonify
    def approve(self, quote_id):
        authorize()
        if not h.is_admin():
            abort(401)
        if request.environ['REQUEST_METHOD'] == 'POST':
            quote = db.query(Quote).filter(Quote.id == quote_id).first()
            if not quote:
                return {'msg': 'Invalid quote ID.',
                        'status': 'error'}
            quote.status = QSTATUS['approved']
            db.commit()
            return {'msg': 'Quote approved.',
                    'status': 'success'}
        else:
            abort(405)

    @jsonify
    def delete(self, quote_id):
        if request.environ['REQUEST_METHOD'] == 'DELETE':
            delete_check = self._is_deleteable_or_disapprovable(quote_id)
            if delete_check['status'] == 'error':
                return delete_check
            else:
                quote = delete_check['quote']
            quote.status = QSTATUS['deleted']
            msg = 'Quote deleted.'
            db.commit()
            return {'msg': msg,
                    'status': 'success'}
        else:
            abort(405)

    @jsonify
    def disapprove(self, quote_id):
        if request.environ['REQUEST_METHOD'] == 'POST':
            delete_check = self._is_deleteable_or_disapprovable(quote_id)
            if delete_check['status'] == 'error':
                return delete_check
            else:
                quote = delete_check['quote']
            quote.status = QSTATUS['disapproved']
            msg = 'Quote disapproved.'
            db.commit()
            return {'msg': msg,
                    'status': 'success'}
        else:
            abort(405)

    @jsonify
    def favourite(self, quote_id):
        authorize()
        quote = db.query(Quote).filter(Quote.id == quote_id).first()
        if not quote:
            return {'msg': 'Invalid quote ID.',
                    'status': 'error'}
        if request.environ['REQUEST_METHOD'] == 'POST':
            c.user.favourites.append(quote)
            db.commit()
            return {'msg': 'Quote favourited.',
                    'status': 'success'}
        elif request.environ['REQUEST_METHOD'] == 'DELETE':
            if not quote in c.user.favourites:
                return {'msg': "Can't remove: This quote isn't in your favourites.",
                        'status': 'error'}
            c.user.favourites.remove(quote)
            db.commit()
            return {'msg': 'Removed favourite.',
                    'status': 'success'}
        else:
            abort(405)

    @jsonify
    def report(self, quote_id):
        authorize()
        quote = db.query(Quote).filter(Quote.id == quote_id).first()
        if not quote:
            return {'msg': 'Invalid quote ID.',
                    'status': 'error'}
        if request.environ['REQUEST_METHOD'] == 'POST':
            if self._has_made_too_many_reports():
                # TODO: This should return a HTTP 429! But pylons.controllers.util.abort()
                #       doesn't seem to support it :/
                return {'msg': 'You are reporting quotes too fast. Slow down!',
                        'status': 'error'}
            if db.query(ReportedQuotes).filter_by(user_id=c.user.id).\
                filter_by(quote_id=quote.id).first():
                return {'msg': 'You already reported this quote in the past. Ignored.',
                        'status': 'error'}
            if not quote.status == QSTATUS['approved']:
                return {'msg': 'Quote is not approved, therefore cannot be reported.',
                        'status': 'error'}
            if db.query(ReportedQuotes).filter_by(user_id=c.user.id).\
                filter_by(quote_id=quote.id).first():
                return {'msg': 'You already reported this quote in the past. Ignored.',
                        'status': 'error'}
            c.user.reported_quotes.append(quote)
            quote.status = QSTATUS['reported']
            db.commit()

            return {'msg': 'Quote reported.',
                    'status': 'success'}
        else:
            abort(405)

    @jsonify
    def vote(self, quote_id, direction):
        authorize()
        quote = db.query(Quote).filter(Quote.id == quote_id).first()
        if request.environ['REQUEST_METHOD'] == 'POST':
            if not quote:
                return {'msg': 'Invalid quote ID.',
                        'status': 'error'}

            already_voted = ''
            for assoc in quote.voters:
                if assoc.user == c.user:
                    already_voted = True
                    # cancel the last vote:
                    if assoc.direction == 'up':
                        quote.rating -= 1
                    elif assoc.direction == 'down':
                        quote.rating += 1
                    db.delete(assoc)

            assoc = VoteToUser(direction=direction)
            assoc.user = c.user
            quote.voters.append(assoc)

            if direction == 'up':
                quote.rating += 1
            elif direction == 'down':
                quote.rating -= 1
            else:
                return {'msg': 'Invalid vote direction.',
                        'status': 'error'}

            if not already_voted:
                quote.votes += 1
            db.commit()
            return {'status': 'success',
                    'msg': 'Vote cast!'}
        elif request.environ['REQUEST_METHOD'] == 'DELETE':
            for assoc in quote.voters:
                if assoc.user == c.user:
                    db.delete(assoc)
            if direction == 'up':
                quote.rating -= 1
            elif direction == 'down':
                quote.rating += 1
            else:
                return {'msg': 'Invalid vote direction.',
                        'status': 'error'}

            quote.votes -= 1
            db.commit()
            return {'status': 'success',
                    'msg': 'Vote annulled!'}
        else:
            abort(405)

    def _has_made_too_many_reports(self):
        # TODO:
        # This filtering / counting should be done by SQLAlchemy.
        #
        # This is a quick hack to get around problems with between() and filter/filter_by,
        # possibly caused by the fact that ReportedQuotes is a Table() obj and not a class
        #
        reports = db.query(ReportedQuotes).filter_by(user_id=c.user.id).all()
        limit = 5
        limit_time = now() - datetime.timedelta(hours=1)
        i = 0
        found = []
        for report in reports:
            if limit_time < report.time:
                found.append(report)
            if i == limit:
                break
            i += 1
        return len(found) >= limit

    def _is_deleteable_or_disapprovable(self, quote_id):
        authorize()
        quote = db.query(Quote).filter(Quote.id == quote_id).first()
        if not quote:
            return {'msg': 'Invalid quote ID.',
                    'status': 'error'}
        if not h.quote_is_deleteable(quote):
            return {'msg': 'You do not have permission to delete this quote.',
                    'status': 'error'}
        c.user.deleted_quotes.append(quote)
        return {'status': 'success', 'quote': quote}


#Import required modules
import cv2
import dlib
import numpy as np
import os
import csv
import statistics

#Set up some required objects

#video_capture = cv2.VideoCapture(0) #Webcam object
#video_capture = cv2.VideoCapture('SourceShort4.mp4')
fourcc = cv2.VideoWriter_fourcc(*'XVID')
video_capture = cv2.VideoCapture('0001-0483.avi')
video_output = cv2.VideoWriter('output.avi', fourcc, 60.0, (1920,1080))
detector = dlib.get_frontal_face_detector() #Face detector
predictor = dlib.shape_predictor("Dataset/shape_predictor_68_face_landmarks.dat") #Landmark identifier. Set the filename to whatever you named the downloaded file
cv2.useOptimized()
#---------------------------------------------------
#Parameters:

frame_interval = 3
pitch_normalisation_value = 0.01
yaw_normalisation_value = 0.005
pupil_threshold = 30
EAR_blink_threshold = 0.16

#---------------------------------------------------

# POSE ESTIMATION:
# 3D model points for head tracking.
model_points = np.array([
    (0.0, 0.0, 0),  # Nose tip
    (0.0, -210.0, -100.0),  # Chin
    (-130.0, 90.0, -110.0),  # Left eye left corner
    (0, 90.0, -70.0),  # Nose Bridge
    (130.0, 90.0, -110.0),  # Right eye right corner
    (-180.0, -100.0, -280.0),  # Left Jaw
    (180.0, -100.0, -280.0)  # Right Jaw

])

# Camera internals for head tracking:

focal_length = video_capture.get(3)
center = (video_capture.get(3) / 2, video_capture.get(4))
camera_matrix = np.array(
    [[focal_length, 0, center[0]],
     [0, focal_length, center[1]],
     [0, 0, 1]], dtype="double"
)

pitch =[]
yaw = []
roll = []
NER_L = []
NER_R = []
EAR_L = []
EAR_R = []
EX = []
EY = []
IMAR = []
OMAR = []
N2MAR_L = []
N2MAR_R = []
blink = []

head_output_buffer = [pitch,yaw,roll, NER_L, NER_R, EAR_L, EAR_R, EX, EY, IMAR, OMAR, blink, N2MAR_R, N2MAR_L]
final_output = []

while(video_capture.isOpened()):
    ret, frame = video_capture.read()
    if ret:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) #Histogram Equalisation
        clahe_image = clahe.apply(gray)
        detections = detector(clahe_image, 1) #Detect the faces in the image

        if (detections):
            shape = predictor(clahe_image, detections[0]) #Get coordinates

        for i in range(0,68): #There are 69 landmark points on each face
            cv2.circle(frame, (shape.part(i).x, shape.part(i).y), 2, (0,0,0), thickness=1) #For each point, draw a red circle with thickness2 on the original frame

        for i in range(0,16):
            cv2.line(frame, (shape.part(i).x, shape.part(i).y), (shape.part(i+1).x, shape.part(i+1).y), (0,0,0),thickness=1,lineType = 8) #Line on Jaw

        for i in range(17,21):
            cv2.line(frame, (shape.part(i).x, shape.part(i).y), (shape.part(i+1).x, shape.part(i+1).y), (0,0,0),thickness=1,lineType = 8) #Line on Eyebrow

        for i in range(22,26):
            cv2.line(frame, (shape.part(i).x, shape.part(i).y), (shape.part(i+1).x, shape.part(i+1).y), (0,0,0),thickness=1,lineType = 8) #Line on Eyebrow

        for i in range(27,35):
            cv2.line(frame, (shape.part(i).x, shape.part(i).y), (shape.part(i+1).x, shape.part(i+1).y), (0,0,0),thickness=1,lineType = 8) #Line on Nose

        cv2.line(frame, (shape.part(35).x, shape.part(35).y), (shape.part(30).x, shape.part(30).y), (0, 0, 0), thickness=1, lineType=8)  #Line on Nose
        cv2.line(frame, (shape.part(27).x, shape.part(27).y), (shape.part(31).x, shape.part(31).y), (0, 0, 0), thickness=1, lineType=8)  # Last line on Nose
        cv2.line(frame, (shape.part(27).x, shape.part(27).y), (shape.part(35).x, shape.part(35).y), (0, 0, 0), thickness=1, lineType=8)  # Last line on Nose

        for i in range(48,59):
            cv2.line(frame, (shape.part(i).x, shape.part(i).y), (shape.part(i+1).x, shape.part(i+1).y), (0,0,0),thickness=1,lineType = 8) #Line on Mouth
        cv2.line(frame, (shape.part(59).x, shape.part(59).y), (shape.part(48).x, shape.part(48).y), (0, 0, 0), thickness=1, lineType=8)  # Line on Mouth

        for i in range(60,67):
            cv2.line(frame, (shape.part(i).x, shape.part(i).y), (shape.part(i+1).x, shape.part(i+1).y), (0,0,0),thickness=1,lineType = 8) #Line on inner Mouth
        cv2.line(frame, (shape.part(67).x, shape.part(67).y), (shape.part(60).x, shape.part(60).y), (0, 0, 0), thickness=1, lineType=8)  # Line on inner Mouth

        for i in range(36,41):
            cv2.line(frame, (shape.part(i).x, shape.part(i).y), (shape.part(i+1).x, shape.part(i+1).y), (0,0,0),thickness=1,lineType = 8) #Line on eye
        cv2.line(frame, (shape.part(41).x, shape.part(41).y), (shape.part(36).x, shape.part(36).y), (0, 0, 0), thickness=1, lineType=8)  # Line on eye

        for i in range(42,47):
            cv2.line(frame, (shape.part(i).x, shape.part(i).y), (shape.part(i+1).x, shape.part(i+1).y), (0,0,0),thickness=1,lineType = 8) #Line on eye
        cv2.line(frame, (shape.part(47).x, shape.part(47).y), (shape.part(42).x, shape.part(42).y), (0, 0, 0), thickness=1, lineType=8)  # Line on eye

#------------------------------------------------------------------------------------
        #Head Tracking:

        # 2D points for Head Tracking
        image_points = np.array([
            (shape.part(30).x, shape.part(30).y),  # Nose tip
            (shape.part(8).x, shape.part(8).y),  # Chin
            (shape.part(45).x, shape.part(45).y),  # Left eye left corner
            (shape.part(27).x, shape.part(27).y),  # Nose Bridge
            (shape.part(36).x, shape.part(36).y),  # Right eye right corner
            (shape.part(12).x, shape.part(12).y),  # Left Jaw
            (shape.part(4).x, shape.part(4).y)  # Right Jaw
        ], dtype="double")

        dist_coeffs = np.zeros((4, 1))  # Assuming no lens distortion
        (success, rotation_vector, translation_vector) = cv2.solvePnP(model_points, image_points, camera_matrix,
                                                                          dist_coeffs)

        # Project a 3D point (0, 0, 1000.0) onto the image plane.
        # We use this to draw a line sticking out of the nose

        (nose_end_point2D, jacobian) = cv2.projectPoints(np.array([(0.0, 0.0, 1000.0)]), rotation_vector,
                                                             translation_vector, camera_matrix, dist_coeffs)

        for p in image_points:
            cv2.circle(frame, (int(p[0]), int(p[1])), 2, (255, 0, 0), -1)

        nose_tip = (int(image_points[0][0]), int(image_points[0][1]))
        nose_target = (int(nose_end_point2D[0][0][0]), int(nose_end_point2D[0][0][1]))

        cv2.arrowedLine(frame, nose_tip, nose_target, (255, 0, 0), 1)

        rotation_matrix = np.zeros((3, 3))
        cv2.Rodrigues(rotation_vector,rotation_matrix,jacobian)

        projection_matrix = np.array(
            [[rotation_matrix[0][0], rotation_matrix[0][1], rotation_matrix[0][2] , translation_vector[0]],
            [rotation_matrix[1][0], rotation_matrix[1][1], rotation_matrix[1][2], translation_vector[1]],
            [rotation_matrix[2][0], rotation_matrix[2][1], rotation_matrix[2][2], translation_vector[2]]], dtype="double"
        )

        euler_angles = cv2.decomposeProjectionMatrix(projection_matrix)
        euler_angles = euler_angles[6]

        nose_bridge = np.array([shape.part(27).x, shape.part(27).y])

        yaw = -euler_angles[1][0]
        pitch = -(nose_tip[1] - nose_target[1]) * 0.05

        if abs(euler_angles[2][0] % 180) <= abs(180 - (euler_angles[2][0] % 180)):
            roll = (euler_angles[2][0] % 180)
        else:
            roll = -1*(180 - (euler_angles[2][0] % 180))

        roll = - roll

        cv2.putText(frame,
                    'yaw = '+ str(yaw), (32, 32), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)
        cv2.putText(frame,
                    'pitch = ' + str(pitch), (32, 64), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)
        cv2.putText(frame,
                    'roll = ' + str(roll), (32, 96), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)

#--------------------------------------------------------------------------------------------
#   NER - normalized eyebrow ratios for eyebrow movement

        cv2.line(frame, (shape.part(17).x, shape.part(17).y), (shape.part(27).x, shape.part(27).y), (0, 255, 0),
                 thickness=1, lineType=8)  # Line between outer eyebrow and nose bridge
        cv2.line(frame, (shape.part(27).x, shape.part(27).y), (shape.part(26).x, shape.part(26).y), (0, 255, 0),
                 thickness=1, lineType=8)  # Line between outer eyebrow and nose bridge

        outer_brow1 = np.array([shape.part(17).x, shape.part(17).y])
        outer_brow2 = np.array([shape.part(26).x, shape.part(26).y])
        nose_bridge = np.array([shape.part(27).x, shape.part(27).y])

        p3 = np.array([shape.part(18).x, shape.part(18).y])
        d1 = np.linalg.norm(np.cross(outer_brow1 - nose_bridge, nose_bridge - p3)) / np.linalg.norm(outer_brow1 - nose_bridge)

        p3 = np.array([shape.part(19).x, shape.part(19).y])
        d2 = np.linalg.norm(np.cross(outer_brow1 - nose_bridge, nose_bridge - p3)) / np.linalg.norm(outer_brow1 - nose_bridge)

        p3 = np.array([shape.part(20).x, shape.part(20).y])
        d3 = np.linalg.norm(np.cross(outer_brow1 - nose_bridge, nose_bridge - p3)) / np.linalg.norm(outer_brow1 - nose_bridge)

        p3 = np.array([shape.part(21).x, shape.part(21).y])
        d4 = np.linalg.norm(np.cross(outer_brow1 - nose_bridge, nose_bridge - p3)) / np.linalg.norm(outer_brow1 - nose_bridge)

        ner_r =(d1 + d2 + d3 + d4) / (4 * np.linalg.norm(outer_brow1 - nose_bridge))
        ner_r = ner_r * (1 + (pitch * pitch_normalisation_value))

        p3 = np.array([shape.part(25).x, shape.part(25).y])
        d1 = np.linalg.norm(np.cross(outer_brow2 - nose_bridge, nose_bridge - p3)) / np.linalg.norm(outer_brow2 - nose_bridge)

        p3 = np.array([shape.part(24).x, shape.part(24).y])
        d2 = np.linalg.norm(np.cross(outer_brow2 - nose_bridge, nose_bridge - p3)) / np.linalg.norm(outer_brow2 - nose_bridge)

        p3 = np.array([shape.part(23).x, shape.part(23).y])
        d3 = np.linalg.norm(np.cross(outer_brow2 - nose_bridge, nose_bridge - p3)) / np.linalg.norm(outer_brow2 - nose_bridge)

        p3 = np.array([shape.part(22).x, shape.part(22).y])
        d4 = np.linalg.norm(np.cross(outer_brow2 - nose_bridge, nose_bridge - p3)) / np.linalg.norm(outer_brow2 - nose_bridge)

        ner_l = (d1 + d2 + d3 + d4) / (4 * np.linalg.norm(outer_brow2 - nose_bridge))
        ner_l = ner_l * (1 + (pitch * pitch_normalisation_value))

        cv2.putText(frame,
                    'NER_L = ' + str(ner_l), (32, 128), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)
        cv2.putText(frame,
                    'NER_R = ' + str(ner_r), (32, 160), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)

#--------------------------------------------------------------------------------------------
# EAR -Eye Aspect Ratio for eyes closing

        p1 = np.array([shape.part(36).x, shape.part(36).y])
        p2 = np.array([shape.part(37).x, shape.part(37).y])
        p3 = np.array([shape.part(38).x, shape.part(38).y])
        p4 = np.array([shape.part(39).x, shape.part(39).y])
        p5 = np.array([shape.part(40).x, shape.part(40).y])
        p6 = np.array([shape.part(41).x, shape.part(41).y])

        ear_l = (np.linalg.norm(p2 - p6) + np.linalg.norm(p3 - p5)) / (2 * np.linalg.norm(p1 - p4))
        ear_l = ear_l * (1 - (np.abs(yaw)*yaw_normalisation_value))

        p1 = np.array([shape.part(42).x, shape.part(42).y])
        p2 = np.array([shape.part(43).x, shape.part(43).y])
        p3 = np.array([shape.part(44).x, shape.part(44).y])
        p4 = np.array([shape.part(45).x, shape.part(45).y])
        p5 = np.array([shape.part(46).x, shape.part(46).y])
        p6 = np.array([shape.part(47).x, shape.part(47).y])

        ear_r = (np.linalg.norm(p2 - p6) + np.linalg.norm(p3 - p5)) / (2 * np.linalg.norm(p1 - p4))
        ear_r = ear_r * (1 - (np.abs(yaw) * yaw_normalisation_value))

        blink = 0

        # and (final_output[-1][11] == 0) ?
        if (final_output and ((ear_r + ear_l )/ 2) < EAR_blink_threshold):
            blink = 1

        cv2.putText(frame,
                    'EAR_L = ' + str(ear_l), (32, 192), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)
        cv2.putText(frame,
                    'EAR_R = ' + str(ear_r), (32, 224), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)

        # -------------------------------------------
        # Eye Tracking
        left_eye_region = np.array([(shape.part(42).x, shape.part(42).y),
                                    (shape.part(43).x, shape.part(43).y),
                                    (shape.part(44).x, shape.part(44).y),
                                    (shape.part(45).x, shape.part(45).y),
                                    (shape.part(46).x, shape.part(46).y),
                                    (shape.part(47).x, shape.part(47).y)], np.int32)

        height, width, _ = frame.shape
        mask = np.ones((height, width), np.uint8)
        cv2.polylines(mask, [left_eye_region], True, 255, 2)
        cv2.fillPoly(mask, [left_eye_region], 255)
        left_eye = cv2.bitwise_and(gray, gray, mask=mask)

        min_x = np.min(left_eye_region[:, 0])
        max_x = np.max(left_eye_region[:, 0])
        min_y = np.min(left_eye_region[:, 1])
        max_y = np.max(left_eye_region[:, 1])
        gray_eye = left_eye[min_y: max_y, min_x: max_x]
        gray_eye = cv2.GaussianBlur(gray_eye, (3,3), 0)

        _, threshold_eye = cv2.threshold(gray_eye, pupil_threshold, 255, cv2.THRESH_BINARY_INV)
        M = cv2.moments(threshold_eye)

        if (M["m10"] != 0):
            cX_la = M["m10"] / M["m00"]
            cY_la = M["m01"] / M["m00"]
            cX_l = cX_la / (max_x - min_x)
            cY_l = cY_la / (max_y - min_y)
        else:
            cX_l = 0.5
            cY_l = 0.5
            cX_la = (max_x - min_x) / 2
            cY_la = (max_y - min_y) / 2

        cv2.circle(frame, (min_x + int(cX_la), min_y + int(cY_la)), 2, (0, 0, 255), thickness=1)

        right_eye_region = np.array([(shape.part(36).x, shape.part(36).y),
                                    (shape.part(37).x, shape.part(37).y),
                                    (shape.part(38).x, shape.part(38).y),
                                    (shape.part(39).x, shape.part(39).y),
                                    (shape.part(40).x, shape.part(40).y),
                                    (shape.part(41).x, shape.part(41).y)], np.int32)

        cv2.polylines(mask, [right_eye_region], True, 255, 2)
        cv2.fillPoly(mask, [right_eye_region], 255)
        right_eye = cv2.bitwise_and(gray, gray, mask=mask)

        min_x = np.min(right_eye_region[:, 0])
        max_x = np.max(right_eye_region[:, 0])
        min_y = np.min(right_eye_region[:, 1])
        max_y = np.max(right_eye_region[:, 1])
        gray_eye = right_eye[min_y: max_y, min_x: max_x]
        gray_eye = cv2.GaussianBlur(gray_eye, (3, 3), 0)

        _, threshold_eye = cv2.threshold(gray_eye, pupil_threshold, 255, cv2.THRESH_BINARY_INV)
        M = cv2.moments(threshold_eye)

        if (M["m10"] != 0):
            cX_ra = M["m10"] / M["m00"]
            cY_ra = M["m01"] / M["m00"]
            cX_r = cX_ra / (max_x - min_x)
            cY_r = cY_ra / (max_y - min_y)
        else:
            cX_r = 0.5
            cY_r = 0.5
            cX_ra = (max_x - min_x) / 2
            cY_ra = (max_y - min_y) / 2

        cv2.circle(frame, (min_x + int(cX_ra), min_y + int(cY_ra)), 2, (0, 0, 255), thickness=1)

        eX = (cX_l + cX_r) / 2
        eY = min((cY_l + cY_r) / 2, 1)

        cv2.putText(frame,
                    'EX = ' + str(eX), (32, 256), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)
        cv2.putText(frame,
                    'EY = ' + str(eY), (32, 288), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)

        if final_output and final_output[-1][11] == 1.0:
            cv2.putText(frame,
                        'BLINK', (32, 384), cv2.FONT_HERSHEY_SIMPLEX,
                        0.75, (0, 0, 255), 1, cv2.LINE_AA)

# --------------------------------------------------------------------------------------------
# OMAR - Outer Mouth Aspect Ratio for mouth stretching, smiling

        p1 = np.array([shape.part(48).x, shape.part(48).y])
        p2 = np.array([shape.part(49).x, shape.part(49).y])
        p3 = np.array([shape.part(50).x, shape.part(50).y])
        p4 = np.array([shape.part(51).x, shape.part(51).y])
        p5 = np.array([shape.part(52).x, shape.part(52).y])
        p6 = np.array([shape.part(53).x, shape.part(53).y])
        p7 = np.array([shape.part(54).x, shape.part(54).y])
        p8 = np.array([shape.part(55).x, shape.part(55).y])
        p9 = np.array([shape.part(56).x, shape.part(56).y])
        p10 = np.array([shape.part(57).x, shape.part(57).y])
        p11 = np.array([shape.part(58).x, shape.part(58).y])
        p12 = np.array([shape.part(59).x, shape.part(59).y])
        p13 = np.array([shape.part(61).x, shape.part(61).y])
        p14 = np.array([shape.part(62).x, shape.part(62).y])
        p15 = np.array([shape.part(63).x, shape.part(63).y])
        p16 = np.array([shape.part(65).x, shape.part(65).y])
        p17 = np.array([shape.part(66).x, shape.part(66).y])
        p18 = np.array([shape.part(67).x, shape.part(67).y])

        omar = (np.linalg.norm(p2 - p12) + np.linalg.norm(p3 - p13) + np.linalg.norm(p4 - p14) +
                np.linalg.norm(p5 - p15) + np.linalg.norm(p6 - p8) + np.linalg.norm(p16 - p9) +
                np.linalg.norm(p16 - p9) + np.linalg.norm(p17 - p10) + np.linalg.norm(p18 - p11)) /\
                (5* + np.linalg.norm(p1 - p7))

        omar = omar * (1 - (np.abs(yaw) * yaw_normalisation_value))

        cv2.putText(frame,
                    'OMAR = ' + str(omar), (32, 320), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)

# --------------------------------------------------------------------------------------------
# IMAR - Inner Mouth Aspect Ratio for showing teeth

        imar = (5 * (np.linalg.norm(p13 - p18) + np.linalg.norm(p14 - p17) + np.linalg.norm(p15 - p16))) /\
               (3 * (np.linalg.norm(p2 - p12) + np.linalg.norm(p3 - p11) + np.linalg.norm(p4 - p10) +
                np.linalg.norm(p5 - p9) + np.linalg.norm(p6 - p8)))

        cv2.putText(frame,
                    'IMAR = ' + str(imar), (32, 352), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (255, 0, 0), 1, cv2.LINE_AA)

# --------------------------------------------------------------------------------------------
# N2MAR - Nose to Mouth Ratios
        p1 = np.array([shape.part(27).x, shape.part(27).y]) #nose bridge
        p2 = np.array([shape.part(31).x, shape.part(31).y]) #right nose wing
        p3 = np.array([shape.part(35).x, shape.part(35).y]) #left nose wing
        p4 = np.array([shape.part(32).x, shape.part(32).y]) #right nostril
        p5 = np.array([shape.part(34).x, shape.part(34).y]) #left nostril
        p6 = np.array([shape.part(33).x, shape.part(33).y]) #nose bottom
        p7 = np.array([shape.part(48).x, shape.part(48).y]) # right lip corner
        p8 = np.array([shape.part(49).x, shape.part(49).y]) # right lip 1
        p9 = np.array([shape.part(50).x, shape.part(50).y]) # right lip 2
        p10 = np.array([shape.part(51).x, shape.part(51).y]) # lip center
        p11 = np.array([shape.part(52).x, shape.part(52).y]) # left lip 2
        p12 = np.array([shape.part(53).x, shape.part(53).y]) # left lip 1
        p13= np.array([shape.part(54).x, shape.part(54).y]) # left lip corner

        d1 = np.linalg.norm(np.cross(p2 - p3, p3 - p7)) / np.linalg.norm(
            p2 - p3)

        d2 = np.linalg.norm(np.cross(p2 - p3, p3 - p8)) / np.linalg.norm(
            p2 - p3)

        d3 = np.linalg.norm(np.cross(p2 - p3, p3 - p9)) / np.linalg.norm(
            p2 - p3)

        d4 = np.linalg.norm(np.cross(p2 - p3, p3 - p10)) / np.linalg.norm(
            p2 - p3)

        n2mar_r = (d1 + d2) / (d3 + d4)

        d1 = np.linalg.norm(np.cross(p2 - p3, p3 - p13)) / np.linalg.norm(
            p2 - p3)

        d2 = np.linalg.norm(np.cross(p2 - p3, p3 - p12)) / np.linalg.norm(
            p2 - p3)

        d3 = np.linalg.norm(np.cross(p2 - p3, p3 - p11)) / np.linalg.norm(
            p2 - p3)

        d4 = np.linalg.norm(np.cross(p2 - p3, p3 - p10)) / np.linalg.norm(
            p2 - p3)

        n2mar_l = (d1 + d2) / (d3 + d4)

        n2mar_l = n2mar_l * (1 + (pitch * pitch_normalisation_value * 2))
        n2mar_r = n2mar_r * (1 + (pitch * pitch_normalisation_value * 2))

        cv2.putText(frame,
                    'N2MAR_R = ' + str(n2mar_r), (32, 416), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (0, 255, 0), 1, cv2.LINE_AA)

        cv2.putText(frame,
                    'N2MAR_L = ' + str(n2mar_l), (32, 448), cv2.FONT_HERSHEY_SIMPLEX,
                    0.75, (0, 255, 0), 1, cv2.LINE_AA)

# --------------------------------------------------------------------------------------------

        cv2.imshow("image", frame) #Display the frame
        video_output.write(frame)

        head_output_buffer[0].append(yaw)
        head_output_buffer[1].append(pitch)
        head_output_buffer[2].append(roll)
        head_output_buffer[3].append(ner_l)
        head_output_buffer[4].append(ner_r)
        head_output_buffer[5].append(ear_l)
        head_output_buffer[6].append(ear_r)
        head_output_buffer[7].append(eX)
        head_output_buffer[8].append(eY)
        head_output_buffer[9].append(omar)
        head_output_buffer[10].append(imar)
        head_output_buffer[11].append(((ear_r + ear_l )/ 2))
        head_output_buffer[12].append(n2mar_r)
        head_output_buffer[13].append(n2mar_l)

        if (len(head_output_buffer[0]) >= frame_interval):
            print(str(statistics.median(head_output_buffer[0])) + ', ' + str(statistics.median(head_output_buffer[1])) + ', ' + str(statistics.median(head_output_buffer[2])) + ', ' + str(statistics.median(head_output_buffer[3])) + ', ' + str(statistics.median(head_output_buffer[4])))
            final_output.append([statistics.median(head_output_buffer[0]),
                                 statistics.median(head_output_buffer[1]),
                                 statistics.median(head_output_buffer[2]),
                                 statistics.median(head_output_buffer[3]),
                                 statistics.median(head_output_buffer[4]),
                                 statistics.median(head_output_buffer[5]),
                                 statistics.median(head_output_buffer[6]),
                                 statistics.median(head_output_buffer[7]),
                                 statistics.median(head_output_buffer[8]),
                                 statistics.median(head_output_buffer[9]),
                                 statistics.median(head_output_buffer[10]),
                                 np.min(head_output_buffer[11]),
                                 statistics.median(head_output_buffer[12]),
                                 statistics.median(head_output_buffer[13])])

            for datum in head_output_buffer:
                datum.clear()

        if cv2.waitKey(1) & 0xFF == ord('q'):  # Exit program when the user presses 'q'
            break
    else:
        if (len(head_output_buffer[0]) > 0):
            final_output.append([statistics.median(head_output_buffer[0]),
                                 statistics.median(head_output_buffer[1]),
                                 statistics.median(head_output_buffer[2]),
                                 statistics.median(head_output_buffer[3]),
                                 statistics.median(head_output_buffer[4]),
                                 statistics.median(head_output_buffer[5]),
                                 statistics.median(head_output_buffer[6]),
                                 statistics.median(head_output_buffer[7]),
                                 statistics.median(head_output_buffer[8]),
                                 statistics.median(head_output_buffer[9]),
                                 statistics.median(head_output_buffer[10]),
                                 np.max(head_output_buffer[11]),
                                 statistics.median(head_output_buffer[12]),
                                 statistics.median(head_output_buffer[13])])

        video_capture.release()
        video_output.release()
        cv2.destroyAllWindows()

with open('output.csv', mode='w') as employee_file:
    writer = csv.writer(employee_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)

    writer.writerow(['yaw', 'pitch', 'roll', 'NER_L', 'NER_R', 'EAR_L', 'EAR_R', 'E_X', 'E_Y', 'OMAR', 'IMAR'])
    for row in final_output:
        writer.writerow(row)


#!/usr/bin/env python
# -*- coding:utf-8 -*-
import uuid
import datetime
import itertools
from celery import shared_task
from apps.api import models
from utils.encrypt import md5
from utils.tencent.pay import refund

@shared_task
def to_preview_status_task(auction_id):
    models.Auction.objects.filter(id=auction_id).update(status=2)
    models.AuctionItem.objects.filter(auction_id=auction_id).update(status=2)

@shared_task
def to_auction_status_task(auction_id):
    models.Auction.objects.filter(id=auction_id).update(status=3)
    models.AuctionItem.objects.filter(auction_id=auction_id).update(status=3)

@shared_task
def end_auction_task(auction_id):
    # ########## 状态更新 ###########
    models.Auction.objects.filter(id=auction_id).update(status=4)
    # models.AuctionItem.objects.filter(auction_id=auction_id).update(status=4)

    total = 0
    total_unfortunate_list = []
    lucky_auction_deposit_id = set()

    auction_object = models.Auction.objects.filter(id=auction_id).first()
    item_object_list = models.AuctionItem.objects.filter(auction=auction_object)

    # 循环所有的拍品
    for item_object in item_object_list:

        # 获取当前拍品出价最高者
        lucky_object = models.BidRecord.objects.filter(item=item_object).order_by('-price').first()

        # 无出价，则流派
        if not lucky_object:
            item_object.status = 5
            item_object.save()
            continue
        else:
            item_object.status = 4
            item_object.save()

        lucky_object.status = 2
        lucky_object.save()

        # 拍品：设置成交价
        item_object.deal_price = lucky_object.price
        item_object.save()

        # 专场：总成交额
        total += lucky_object.price

        # 获取当前用户为此 拍品/专场 支付的保证金对象
        deposit_object = models.DepositRecord.objects.filter(
            user=lucky_object.user,
            item=item_object,
            deposit_type=1).first()

        if not deposit_object:
            deposit_object = models.DepositRecord.objects.filter(user=lucky_object.user, auction=auction_object,
                                                                 deposit_type=2, item__isnull=True).first()
            # 所有已经拍到商品的人缴纳的保证金id
            lucky_auction_deposit_id.add(deposit_object.id)

        # 生成订单（待支付）
        order_object = models.Order.objects.create(
            status=1,  # bug1：没有写默认状态
            uid=md5(str(uuid.uuid4())),  # bug2：订单号生成有问题
            user=lucky_object.user,
            item=item_object,
            deposit=deposit_object,  # （单品、专场）
            price=lucky_object.price,
        )

        # 单品保证金：所有没有拍到商品 & 缴纳的是单品保证金记录。
        item_unfortunate_list = models.DepositRecord.objects.filter(item=item_object, deposit_type=1).exclude(
            user=lucky_object.user)
        total_unfortunate_list.extend(item_unfortunate_list)

        # 调用定时任务：24小时内要支付，否则流拍扣除保证金。
        date = datetime.datetime.utcnow() + datetime.timedelta(hours=24)
        # date = datetime.datetime.utcnow() + datetime.timedelta(minutes=1)
        task_id = twenty_four_hour.apply_async(args=[order_object.id], eta=date).id
        order_object.twenty_four_task_id = task_id
        order_object.save()

    # 专场：更新成交额
    auction_object.total_price = total
    auction_object.save()

    # 未拍到任何商品的用户的全场保证金
    auction_unfortunate_list = models.DepositRecord.objects.filter(
        deposit_type=2,
        auction=auction_object,
        item__isnull=True).exclude(id__in=lucky_auction_deposit_id)

    # 退保证金（原路退还）
    for deposit in itertools.chain(total_unfortunate_list, auction_unfortunate_list):
        # uid = md5(uuid.uuid4()) # 错误
        uid = md5(str(uuid.uuid4()))  # 正确，
        if deposit.pay_type == 1:  # 微信
            # res = refund(uid, deposit.uid, deposit.amount, deposit.amount)
            res = True
            models.DepositRefundRecord.objects.create(
                uid=uid,
                status=2 if res else 1,
                amount=deposit.amount,
                deposit=deposit
            )
            if res:
                deposit.balance = 0
                deposit.save()
        else:  # 余额
            deposit.user.balance += deposit.amount
            deposit.user.save()
            models.DepositRefundRecord.objects.create(
                uid=uid,
                status=2,
                amount=deposit.amount,
                deposit=deposit
            )
            deposit.balance = 0
            deposit.save()

    # 拍卖结束之后，将在之后的第24小时将所有 未使用 的用户优惠券主动过期
    date = datetime.datetime.utcnow() + datetime.timedelta(hours=24)
    user_coupon_to_expired.apply_async(args=[auction_id], eta=date)

@shared_task
def twenty_four_hour(order_id):
    """ 24小时不支付订单，则直接扣除保证金 """
    order_object = models.Order.objects.filter(id=order_id).first()

    # 订单已支付
    if order_object.status != 1:
        return

    # 订单状态为 预期未支付
    order_object.status = 4
    order_object.save()

    # 拍品状态为 预期未支付
    order_object.item.status = 6
    order_object.item.save()

    # 单品保证金，直接扣除
    if order_object.deposit.deposit_type == 1:
        order_object.deposit.balance = 0
        order_object.deposit.save()
        models.DepositDeduct.objects.create(order=order_object, amount=order_object.deposit.amount)
        return

    # 全场保证金，扣除部分保证金（如果有剩余，则检查是否还有其他订单了，没了则剩余保证金直接退回到原账户）
    """
        情景一：
            全场保证金：1000
                A  9000  200     扣除200 退还800

            全场保证金：1000
                A  9000  200     扣除200
                B  800   400     扣除400 退还400

            全场保证金：1000
                A  9000  200     扣除200
                B  9000  900     扣除800 退还0

    """
    if order_object.deposit.balance <= order_object.item.deposit:
        models.DepositDeduct.objects.create(order=order_object, amount=order_object.deposit.balance)

        order_object.deposit.balance = 0
        order_object.deposit.save()

        return

    order_object.deposit.balance -= order_object.item.deposit
    order_object.deposit.save()
    models.DepositDeduct.objects.create(order=order_object, amount=order_object.item.deposit)

    # 检查此专场保证金下是否还有其他订单未支付
    exists = models.Order.objects.filter(user=order_object.user,
                                         status=1,
                                         item__auction_id=order_object.deposit.auction).exclude(id=order_id).exists()
    if exists:
        return

    uid = md5(str(uuid.uuid4()))
    if order_object.deposit.pay_type == 1:  # 微信
        # res = refund(uid, deposit.uid, deposit.amount, deposit.amount)
        res = True
        models.DepositRefundRecord.objects.create(
            uid=uid,
            status=2 if res else 1,
            amount=order_object.deposit.balance,
            deposit=order_object.deposit
        )
        if res:
            order_object.deposit.balance = 0
            order_object.deposit.save()
    else:  # 余额
        order_object.deposit.user.balance += order_object.deposit.balance
        order_object.deposit.user.save()
        models.DepositRefundRecord.objects.create(
            uid=uid,
            status=2,
            amount=order_object.deposit.balance,
            deposit=order_object.deposit
        )
        order_object.deposit.balance = 0
        order_object.deposit.save()

@shared_task
def coupon_start_apply(coupon_id):
    models.Coupon.objects.filter(id=coupon_id, status=1).update(status=2)

@shared_task
def coupon_stop_apply(coupon_id):
    models.Coupon.objects.filter(id=coupon_id, status=2).update(status=3)

@shared_task
def user_coupon_to_expired(auction_id):
    models.UserCoupon.objects.filter(coupon__auction_id=auction_id, status=1).update(status=3)


import socket
import sys
import time

connect = 1
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
timeout = time.time() + 60

server_address = ('localhost', 10000)
print('starting server on {} port {}'.format(*server_address))

sock.bind(server_address)
sock.listen(1)

while connect > 0:
	print('waiting for a connection')
	connection, client_address = sock.accept()

	try:
		print('connection from', client_address)
		while True:
			if time.time() > timeout:
				connect-=1
				raise StopIteration
			data = connection.recv(16)
			print('received {!r}'.format(data))
			if data:
				print('sending data back to the client')
				connection.sendall(data)
			else:
				print('no data from', client_address)
				break

	except StopIteration: pass

print("Goodbye")
connection.close()


#! /usr/bin/env python3
import sqlite3
from sqlite3 import Error
import datetime
import time

from configparser import ConfigParser

#Linux database location is /users/rsg/jkb/Documents/Monocle/sensordata
#Pi database location is /home/pi/Documents/Sensors.db

parser = ConfigParser()

#parser.read('/home/pi/sensor_recorder/Config.ini')
parser.read('Config.ini')

def Sensors_Select():
    """
    Select all sensors in the database and return the data
    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        cur=conn.cursor()
        cur.execute("SELECT * FROM Sensors")
        rows = cur.fetchall()
        conn.close()
        if(rows == None):
            rows=[]
        return rows
    except Error as e:
        print("Did not connect, error: {}".format(e))

def Sensors_Update(port, sensorID):
    """
    Select all sensors in the database and return the data
    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        cur=conn.cursor()
        data = (port, sensorID)
        cur.execute("UPDATE Sensors SET port = (?) WHERE id = (?)", data)
        conn.commit()
        conn.close()
    except Error as e:
        print("Did not connect, error: {}".format(e))

def Sensors_insert(sensorType, sensorPort, uniqueName):
    """
    Insert a new sensor into the Sensors table.
    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        conn.execute("INSERT INTO Sensors(sensorType, port, uniqueName) VALUES((?),(?),(?))", (sensorType,sensorPort,uniqueName,))
        conn.commit()
        conn.close()
    except Error as e:
        print("Did not connect to database so couldn't insert new sensor, error: {}".format(e))

def Sensors_select_type():
    """
    Select all sensors in the database and return their type
    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        cur=conn.cursor()
        cur.execute("SELECT sensorType FROM Sensors")
        rows = cur.fetchall()
        conn.close()
        return rows
    except Error as e:
        print("Did not connect, error: {}".format(e))

def Sensors_select_id():
    """
    Select all sensors in the database and return their ID
    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        cur=conn.cursor()
        cur.execute("SELECT id FROM Sensors")
        rows = cur.fetchall()
        conn.close()
        return rows
    except Error as e:
        print("Did not connect, error: {}".format(e))

def Sensors_select_port():
    """
    Select all sensors in the database and return their associated port
    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        cur=conn.cursor()
        cur.execute("SELECT port FROM Sensors")
        rows = cur.fetchall()
        conn.close()
        return rows
    except Error as e:
        print("Did not connect, error: {}".format(e))

def BB3_select():
    """
    Select all the data from the BB3 table in the database.
    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        cur=conn.cursor()
        cur.execute("SELECT currentdate, currenttime, value1, value2, value3, temperature FROM BB3")
        rows = cur.fetchall()
        conn.close()
        return rows
    except Error as e:
        print("Did not connect, error: {}".format(e))

def BB3_insert(Line, sensorID):
    """
    Parameters: date, time, 3 values of readings, temperature
    Inserts the passed data into the database.
    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        conn.execute("INSERT INTO BB3(sensor_ID, currentdate, currenttime, value1, value2, value3, temperature) VALUES((?),(?),(?),(?),(?),(?),(?))", (sensorID, Line[0], Line[1], Line[3], Line[5], Line[7], Line[8]))
        conn.commit()
        conn.close()
    except Error as e:
        print("Did not connect, error: {}".format(e))

def BB9_insert(Line, sensorID):
    """
    Parameters: date, time, 3 values of readings, temperature

    Inserts the passed data into the database.

    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        conn.execute("INSERT INTO BB9(sensor_ID, Header, Meter_Type_and_SN, Number_Of_Columns, Packet_Version, Record_Counter, Reference_1, Signal_1, Reference_2, Signal_2, Reference_3, Signal_3, Reference_4, Signal_4, Reference_5, Signal_5, Reference_6, Signal_6, Reference_7, Signal_7, Reference_8, Signal_8, Reference_9, Signal_9, CheckSum) VALUES((?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?))", (sensorID, Line[0], Line[1], Line[2], Line[3], Line[4], Line[5], Line[6], Line[7], Line[8], Line[9], Line[10], Line[11], Line[12], Line[13], Line[14], Line[15], Line[16], Line[17], Line[18], Line[19], Line[20], Line[21], Line[22], Line[23]))
        conn.commit()
        conn.close()
    except Error as e:
        print("Did not connect, error: {}".format(e))

def BB9_select():
    """
    Select all the data from the BB9 table in the database.

    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        cur=conn.cursor()
        cur.execute("SELECT * FROM BB9")
        rows = cur.fetchall()
        for row in rows:
            print(row)
        conn.close()
    except Error as e:
        print("Did not connect, error: {}".format(e))

def BB_select():
    """
    Select all the data from the BB table in the database.

    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        cur=conn.cursor()
        conn.execute("SELECT * FROM BB")
        rows = cur.fetchall()
        for row in rows:
            print(row)
        conn.close()
    except Error as e:
        print("Did not connect, error: {}".format(e))

def BB_insert(Line, sensorID):
    """
    Parameters: date, time, scattering reference, scattering signal, thermistor

    Inserts the passed data into the database.

    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        conn.execute("INSERT INTO BB(sensor_ID, currentdate, currenttime, scattering_reference, scattering_signal, thermistor) VALUES((?),(?),(?),(?),(?),(?))", (sensorID, Line[0], Line[1], Line[2], Line[3], Line[4]))
        conn.commit()
        conn.close()
    except Error as e:
        print("Did not connect, error: {}".format(e))

def NTU_insert(Line, sensorID):
    """
    Parameters: date, time, NTU signal, thermistor

    Inserts the passed data into the database.

    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        conn.execute("INSERT INTO NTU(sensor_ID, date, time, lambda, NTU_Signal, Thermistor) VALUES((?),(?),(?),(?),(?),(?))", (sensorID, Line[0], Line[1], Line[2], Line[4], Line[5]))
        conn.commit()
        conn.close()
    except Error as e:
        print("Did not connect, error: {}".format(e))

def NTU_select(Line):
    """
    Select all the data from the NTU table in the database.

    """
    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        cur=conn.cursor()
        cur.execute("SELECT * FROM NTU")
        rows = cur.fetchall()
        for row in rows:
            print(row)
        conn.close()
    except Error as e:
        print("Did not connect, error: {}".format(e))

def GPS_insert(Line, sensorID):
    """
    Parameters: date, time, NTU signal, thermistor

    Inserts the passed data into the database.

    """

    try:
        conn=sqlite3.connect(parser.get('database','connection'))
        conn.execute("INSERT INTO GPS(sensor_ID, TIME, Date, Latitude_Value, Latitude_Direction, Longitude_Value, Longitude_Direction, Number_Of_Satelites, GPRMC, GPVTG, GPGGA, GPGSA, GPGSV, GPGLL) VALUES((?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?))", (sensorID, Line[0], Line[1], Line[2], Line[3], Line[4], Line[5], Line[6], Line[7], Line[8], Line[9], Line[10], Line[11], Line[12]))
        conn.commit()
        conn.close()
    except Error as e:
        print("Did not connect, error: {}".format(e))

def SchemaLooper():
    for schema in SQLSchema:
        try:
            conn=sqlite3.connect(parser.get('database','connection'))
            conn.execute(schema[1])
            conn.commit()
            conn.close()
            print(schema[0] + " made")
        except Error as e:
            print("Did not connect, error: {}".format(e))

# use a switch factory hybrid so the sensor manager knows which insert statement to use for each sensor.
SQLInsertQueries = [
    ["BB3",BB3_insert],
    ["BB9",BB9_insert],
    ["BB",BB_insert],
    ["NTU",NTU_insert],
    ["GPS_UBLOX7",GPS_insert]
]

SQLSelectQueries = [
    ["BB3",BB3_select]
]

# Another switch factory hybrid to create a table when it doesn't exist, feature still needs to be added to sensor manager.
SQLSchema = [
    ["BB3", "CREATE TABLE BB3(id INTEGER PRIMARY KEY AUTOINCREMENT, sensor_ID NUMERIC, currentdate DATE, currenttime TIME, value1 NUMERIC, value2 NUMERIC, value3 NUMERIC, temperature NUMERIC, FOREIGN KEY (sensor_ID) REFERENCES Sensors(id));"],
    ["BB9", "CREATE TABLE BB9(id INTEGER PRIMARY KEY AUTOINCREMENT, sensor_ID NUMERIC, Header TEXT, Meter_Type_and_SN TEXT, Number_Of_Columns NUMERIC, Packet_Version NUMERIC, Record_Counter NUMERIC, Reference_1 NUMERIC, Signal_1 NUMERIC, Reference_2 NUMERIC, Signal_2 NUMERIC, Reference_3 NUMERIC, Signal_3 NUMERIC, Reference_4 NUMERIC, Signal_4 NUMERIC, Reference_5 NUMERIC, Signal_5 NUMERIC, Reference_6 NUMERIC, Signal_6 NUMERIC, Reference_7 NUMERIC, Signal_7 NUMERIC, Reference_8 NUMERIC, Signal_8 NUMERIC, Reference_9 NUMERIC, Signal_9 NUMERIC, CheckSum TEXT, FOREIGN KEY (sensor_ID) REFERENCES Sensors(id));"],
    ["BB", "CREATE TABLE BB(id INTEGER PRIMARY KEY AUTOINCREMENT, sensor_ID NUMERIC, currentdate DATE, currenttime TIME, scattering_reference NUMERIC, scattering_signal NUMERIC, thermistor NUMERIC, FOREIGN KEY (sensor_ID) REFERENCES Sensors(id));"],
    ["NTU", "CREATE TABLE NTU(id INTEGER PRIMARY KEY AUTOINCREMENT, sensor_ID NUMERIC, currentdate DATE, currenttime TIME, lambda NUMERIC, NTU_Signal NUMERIC, Thermistor NUMERIC, FOREIGN KEY (sensor_ID) REFERENCES Sensors(id));"],
    ["Sensors", "CREATE TABLE Sensors(id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, sensorType TEXT, port TEXT, uniqueName TEXT);"],
    ["GPS", "CREATE TABLE GPS(EntryID INTEGER PRIMARY KEY AUTOINCREMENT, sensor_ID NUMERIC, Time TIME, Date DATE, Latitude_Value, Latitude_Direction, Longitude_Value, Longitude_Direction, Number_Of_Satelites, GPRMC, GPVTG, GPGGA, GPGSA, GPGSV, GPGLL, FOREIGN KEY (sensor_ID) REFERENCES Sensors(id));"]
]


""" Examples to demonstrate how to write an image file to a TFRecord,
and how to read a TFRecord file using TFRecordReader.
Author: Chip Huyen
Prepared for the class CS 20SI: "TensorFlow for Deep Learning Research"
cs20si.stanford.edu
"""
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

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

from tqdm import tqdm #Progress bar

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

# image supposed to have shape: 480 x 640 x 3 = 921600
IMAGE_PATH = 'data_val'
TFR_PATH = 'data_TFrecord'
TFR_FILE = 'val_TFrecord.tf'
IMG_W = 150
IMG_H = 60
char_set = ('_0123456789'
            'abcdefghijklmnopqrstuvwxyz'
            'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
char_map = {char:idx for idx, char in enumerate(char_set)}
#char_map['_'] = 0 #Padding character

def _int64_feature(value):
  return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))

def _bytes_feature(value):
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

def get_image_binary(filename):
    """ You can read in the image using tensorflow too, but it's a drag
        since you have to create graphs. It's much easier using Pillow and NumPy
    """
    image = (Image.open(filename)
                .resize((IMG_W, IMG_H), resample=Image.BILINEAR))
    image = np.asarray(image, np.uint8)
    shape = np.array(image.shape, np.int32)
    #plt.imshow(image)
    #plt.show()
    #print(shape)
    return shape.tobytes(), image.tobytes() # convert image to raw data bytes in the array.

#def write_to_tfrecord(label, shape, binary_image, tfrecord_file):
#    """ This example is to write a sample to TFRecord file. If you want to write
#    more samples, just use a loop.
#    """
#    writer = tf.python_io.TFRecordWriter(tfrecord_file)
#    # write label, shape, and image content to the TFRecord file
#    example = tf.train.Example(features=tf.train.Features(feature={
#                'label': _int64_feature(label),
#                'shape': _bytes_feature(shape),
#                'image': _bytes_feature(binary_image)
#                }))
#    writer.write(example.SerializeToString())
#    writer.close()

def write_to_tfrecord(label, label_string, length, binary_image, writer):
    """ This example is to write a sample to TFRecord file. If you want to write
    more samples, just use a loop.
    """
    # write label, shape, and image content to the TFRecord file
    example = tf.train.Example(features=tf.train.Features(feature={
                'label': _bytes_feature(label),
                #'label_string': _bytes_feature(label_string),
                #'length': _int64_feature(length),
                #'shape': _bytes_feature(shape),
                'image': _bytes_feature(binary_image)
                }))
    writer.write(example.SerializeToString())

#def write_tfrecord(label, image_file, tfrecord_file):
#    shape, binary_image = get_image_binary(image_file)
#    write_to_tfrecord(label, shape, binary_image, tfrecord_file)

def read_file_format(tfrecord_file_queue):
    """Read and decode file format here
    Input: string_input_produce from tf
    Output: Tensor for example"""
    reader = tf.TFRecordReader()
    _, tfrecord_serialized = reader.read(tfrecord_file_queue)

    # label and image are stored as bytes but could be stored as
    # int64 or float64 values in a serialized tf.Example protobuf.
    tfrecord_features = tf.parse_single_example(tfrecord_serialized,
                        features={
                            'label': tf.FixedLenFeature([], tf.string),
                            #'label_string': tf.FixedLenFeature([], tf.string),
                            #'length': tf.FixedLenFeature([], tf.int64),
                            #'shape': tf.FixedLenFeature([], tf.string),
                            'image': tf.FixedLenFeature([], tf.string),
                        }, name='features')
    # image was saved as uint8, so we have to decode as uint8.
    image = tf.decode_raw(tfrecord_features['image'], tf.uint8)
    label = tf.decode_raw(tfrecord_features['label'], tf.int32)
    #label_string = tfrecord_features['label_string']
    #length = tfrecord_features['length']

    #shape = tf.decode_raw(tfrecord_features['shape'], tf.int32)
    # the image tensor is flattened out, so we have to reconstruct the shape
    image = tf.reshape(image, (IMG_H, IMG_W, 3))
    label = tf.reshape(label, (7,)) #To force size specification
    return image, label

def write_tfrecord(label, label_string, length, image_file, writer):
    shape, binary_image = get_image_binary(image_file)
    write_to_tfrecord(label, label_string, length, binary_image, writer)

def read_from_tfrecord(filenames, batch_size=None, shuffle=True):
    tfrecord_file_queue = tf.train.string_input_producer(filenames,
                                                         name='queue',
                                                         shuffle=shuffle)
    #label = tfrecord_features['label']
    image, label = read_file_format(tfrecord_file_queue)
    if batch_size: #Return multiple samples
        image, label = read_file_format(tfrecord_file_queue)
        #example_list = [read_file_format(fil)]

        # See recommendations in http://web.stanford.edu/class/cs20si/lectures/notes_09.pdf
        min_after_dequeue = 10 * batch_size
        capacity = 20 * batch_size
        images, labels = tf.train.shuffle_batch([image, label],
                                                batch_size=batch_size,
                                                capacity=capacity,
                                                min_after_dequeue=min_after_dequeue,)
                                                #num_threads=4)
        return images, labels
    else:
        image, label = read_file_format(tfrecord_file_queue)
        return image, label #, label_string, length

def read_batch_tfrecords(tfrecord_files, batch_size=32):
    images, labels = read_from_tfrecord(tfrecord_files, batch_size=32)
    with tf.Session() as sess:
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(coord=coord)

        for j in range(5):
            images_np, labels_np = sess.run([images, labels])
            #FOR DEBUGGING
            for i in range(batch_size):
                print(labels_np[i])
                print(''.join(char_set[idx] for idx in labels_np[i]).rstrip('_'))
                plt.imshow(images_np[i])
                plt.show()
        coord.request_stop()
        coord.join(threads)

def read_tfrecord(tfrecord_file):
    image, label = read_from_tfrecord([tfrecord_file])

    with tf.Session() as sess:
        coord = tf.train.Coordinator()
        threads = tf.train.start_queue_runners(coord=coord)
        image, label = sess.run([image, label])
        #Reverse the label to string
        label_string = ''.join(char_set[idx] for idx in label).rstrip('_')
        length = len(label_string)
        #label_string = label_string.decode('utf-8')
        coord.request_stop()
        coord.join(threads)
    print(label)
    print(label_string)
    print(length)
    plt.imshow(image)
    plt.show()

def main():
    #Grab files here
    image_files = list(os.walk(IMAGE_PATH))[1:]

    TFR_FILEPATH = os.path.join(TFR_PATH, TFR_FILE)
    writer = tf.python_io.TFRecordWriter(TFR_FILEPATH)
    for path, _, files in tqdm(image_files, desc='Folder loop'):
        #folder_number = os.path.split(path)[-1]
        #TFR_FILE_PATH = os.path.join(TFR_PATH, TFR_FILE + folder_number)
        #writer = tf.python_io.TFRecordWriter(TFR_FILE_PATH)
        for f in tqdm(files, desc='File loop', leave=False):
            #Insert transformation here - Convert label to DATA
            label_string = f[:-4]
            #label = 1
            length = len(label_string)
            label = np.array([char_map[char] for char in label_string.ljust(7, '_')]).astype(np.int32)
            write_tfrecord(label.tobytes(),
                           label_string.encode('utf-8'),
                           length,
                           os.path.join(path, f),
                           writer)
            #break
        #break
        #writer.close()
    writer.close()

if __name__ == '__main__':

    #main()

    #Now try reading in batches
    file_names = [os.path.join(TFR_PATH, f) for f in os.listdir(TFR_PATH) if f.startswith('train')]
    file_names = ['data_TFrecord/val_TFrecord.tf']
    #Batch reading - TEST
    read_batch_tfrecords(file_names, batch_size=16)


# This test suite *does* require trial, for sane conditional test skipping.
from twisted.trial import unittest

import bravo.blocks
import bravo.ibravo
import bravo.plugin
import bravo.protocols.beta

class CommandsMockFactory(object):

    def __init__(self):
        class CommandsMockProtocol(object):

            def __init__(self):
                self.player = bravo.entity.Player(bravo.location.Location(),
                    eid=0)

        self.protocols = {
            "unittest": CommandsMockProtocol(),
        }

class TestGetpos(unittest.TestCase):

    def setUp(self):
        self.p = bravo.plugin.retrieve_plugins(bravo.ibravo.IChatCommand)

        if "getpos" not in self.p:
            raise unittest.SkipTest("Plugin not present")

        self.hook = self.p["getpos"]

    def test_trivial(self):
        pass

    def test_return_value(self):
        factory = CommandsMockFactory()
        retval = self.hook.chat_command(factory, "unittest", [])
        self.assertTrue(retval)
        l = list(retval)
        self.assertEqual(len(l), 1)


import os

def get_UDID_list():

    UDID_list=[]
    cmd = "adb devices"
    get_cmd = os.popen(cmd).readlines()
    device_number=str(get_cmd).count('device')
    if device_number >1:
        devices_list=get_cmd[1:-1]
        for item in devices_list:
            UDID=item.strip('\tdevice\n')
            UDID_list.append(UDID)
        return (UDID_list)
    else:
        return False

import os
import subprocess

# 得到手机信息
def get_phone_info(devices):
    cmd = "adb -s "+ devices +" shell cat /system/build.prop "
    phone_info =subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines()
    print(phone_info)
    l_list = {}
    release = "ro.build.version.release=" # 版本
    model = "ro.product.model=" #型号
    brand = "ro.product.brand=" # 品牌
    device = "ro.product.device=" # 设备名
    for line in phone_info:
         for i in line.split():
            temp = i.decode()
            if temp.find(release) >= 0:
                l_list["release"] = temp[len(release):]
                break
            if temp.find(model) >= 0:
                l_list["model"] = temp[len(model):]
                break
            if temp.find(brand) >= 0:
                l_list["brand"] = temp[len(brand):]
                break
            if temp.find(device) >= 0:
                l_list["device"] = temp[len(device) :]
                break
    print('F_get_phone_info: %s' %l_list)
    return l_list

def call_adb(command):
    command_result = ''
    command_text = 'adb %s' % command
    results = os.popen(command_text, "r")
    while 1:
        line = results.readline()
        if not line: break
        command_result += line
    results.close()
    return command_result

    # 检查设备
def attached_devices():
    result = call_adb("devices")
    devices = result.partition('\n')[2].replace('\n', '').split('\tdevice')
    flag = [device for device in devices if len(device) > 2]
    if flag:
        return True
    else:
        return False


# https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/
#
# algorithms
# Medium (43.48%)
# Total Accepted:    83,141
# Total Submissions: 191,230
# beats 100.0% of python submissions

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        notown = 0
        own, cool = float('-inf'), float('-inf')

        for p in prices:
            notown, own, cool = max(notown, cool), max(
                own, notown - p), own + p

        return max(notown, cool)


#Copyright (c) 2013 Nathaniel "CageInfamous" Wilson, cageinfamous@redemptionsoft.com

#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
#(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
#publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
#so, subject to the following conditions:
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
#FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
#WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

def DivBackgroundImage(image, w, h):
    if isinstance(w, int) or isinstance(w, float):
        W = str(w) + 'px'
    else:
        W = w
    if isinstance(h, int) or isinstance(h, float):
        H = str(h) + 'px'
    else:
        H = h
    return dict(style='background-image: url(' + image + '); width: ' + W + '; height: ' + H + ';')

def Merge(attrs):
    am = len(attrs)
    aa = attrs[0]
    for EA in range(1, am):
        aa.update(attrs[EA])
    return aa

def toCssStyle(style):
    text = ''
    for EK in style:
        text += EK + ':' + style[EK] + ';'
    return text


import numpy as np
from scipy.sparse import *

### Helper function of construct_Z function
# X: array of dimension N x p
# player_id: 1D array of length N

# Z = coo matrix of size N x np (number of unique players)

def construct_Zp(X, player_id):
	if len(player_id.shape)>1:
		player_id = player_id.reshape(len(player_id),)
	temp = np.sort(np.unique(player_id))
	#print (temp)
	c = X.shape[1]*(np.searchsorted(temp,player_id))
	#print (c)
	Z = lil_matrix((X.shape[0], X.shape[1]*len(temp)))
	for iters in range(X.shape[1]):
		#print (c+iters)
		Z[(np.arange(X.shape[0]), c+iters)] = X[:,iters]
	return(Z)


"""
Script that functionally sorts through all
possible stock tickers in the world-wide stock market.
Writes tickers to a file if they exist in the database specified (Robinhood).
"""

from imports import *

path = 'C:/Users/david/Documents/tickers.xlsx'
tickers = []
working_tickers = []
etf = []
etf_working = []

df = pd.read_excel(path)
list = df['Ticker'].tolist()

xlsx = pd.ExcelFile(path)
df_xlsx = pd.read_excel(xlsx, 'ETF')
etf_list = df_xlsx['Ticker'].tolist()

for i in list:
	tickers.append(str(i))
for i in etf_list:
	etf.append(str(i))
print("# of Tickers:", len(tickers))
print("# of ETF's:", len(etf))

def get_ticker(tickers):
	for i in tickers:
		try:
			x = web.DataReader(i, 'robinhood')
			del x['session']
			x = x.astype(float)
			print(x)
			x['close_price'].plot()
			# plt.show()
			summary = x.describe()
			print(summary)
			working_tickers.append(i)
			print(working_tickers)
			new_df = pd.DataFrame({'col': working_tickers})
			new_df.to_csv('workingtickers.csv')
		except:
			print("Failed")
			pass

def get_etf(etf):
	for i in etf:
		try:
			y = web.DataReader(i, 'robinhood')
			del y['session']
			y = y.astype(float)
			print(y)
			summary = y.describe()
			print(summary)
			etf_working.append(i)
			print(etf_working)
			new_df2 = pd.DataFrame({'col': etf_working})
			new_df2.to_csv('etfworking.csv')
		except:
			print("Failed")
			pass

# ticker_data = get_ticker(tickers)
# etf_data = get_etf(etf)
# print(ticker_data)
# print(etf_data)