'''
The image_operation module provides several operations to process images

@author: Rich Veliz
'''
import math

import logging
import log_config

log = logging.getLogger(__name__)

class ImageOperation:
    '''
    The ImageOperation class provides several operations to process images. A client can call any of the defined methods directly,
    but it is easiest to call the process_image method and let it dispatch to the appropriate operation.
    '''
    def process_image(self, image, process_task, new_file_path):
        '''
        Dispatch to the corresponding image resize method
        '''
        if process_task['operation'] == 'resize_to_width':
            return self.resize_to_width(image, process_task['width'], new_file_path)
        elif process_task['operation'] == 'resize_to_height':
            return self.resize_to_height(image, process_task['height'], new_file_path)
        elif process_task['operation'] == 'resize_to_long_side':
            return self.resize_to_long_side(image, process_task['long_side'], process_task['long_side_min'], new_file_path)
        elif process_task['operation'] == 'resize_and_crop':
            return self.resize_and_crop(image, process_task['width'], process_task['height'], new_file_path)

    def resize_to_width(self, image, width, new_file_path):
        '''
        Resize the image, scaling it to the supplied width. The original aspect ratio of the image will be preserved by this operation.
        '''
        new_size = '{}x'.format(width)

        image.transform(resize=new_size)
        image.save(filename=new_file_path)
        return True

    def resize_to_height(self, image, height, new_file_path):
        '''
        Resize the image, scaling it to the supplied height. The original aspect ratio of the image will be preserved by this operation.
        '''
        new_size = 'x{}'.format(height)

        image.transform(resize=new_size)
        image.save(filename=new_file_path)
        return True

    def resize_to_long_side(self, image, long_side, long_side_min, new_file_path):
        '''
        Resize the image, scaling it to the supplied long_side value. For portrait images, the image will be scaled so that its
        height matches the supplied long_side value. For landscape images, the image will be scaled so that its width matches the
        supplied long_side value. If the long_side dimension of the original image is not greater than or equal to the supplied
        long_side_min value, the image will not be resized. The original aspect ratio of the image will be preserved by this operation.
        '''
        if(image.width >= long_side_min or image.height >= long_side_min):
            if image.width >= long_side or image.height >= long_side:
                new_long_side = long_side
            else:
                new_long_side = max(image.width, image.height)

            if (image.width > image.height):
                new_size = '{}x'.format(new_long_side)
            else:
                new_size = 'x{}'.format(new_long_side)

            image.transform(resize=new_size)
            image.save(filename=new_file_path)
            return True

        return False

    def resize_and_crop(self, image, width, height, new_file_path):
        '''
        Resize the image, and then crop it if necessary to match the supplied height and width. The operation will first attempt to scale
        the image to come as close as possible to the supplied dimensions while maintaining the aspect ratio. Next, any extra width or
        height will be cropped off, equally on both sides. The original aspect ratio of the image will be preserved by this operation.
        '''
        if(image.width < width and image.height < height):
            # the image is already smaller than the supplied crop dimensions
            #    so save it with the new file_name
            image.save(filename=new_file_path)
            return True

        if image.width != width or image.height != height:
            current_aspect_ratio = float(image.width) / image.height
            desired_aspect_ratio = float(width) / height

            if current_aspect_ratio > desired_aspect_ratio:
                # resize to height before crop
                resize_geometry = 'x{height}'.format(height=height)
            else:
                # resize to width before crop
                resize_geometry = '{width}x'.format(width=width)

            # perform the resize operation
            image.transform(resize=resize_geometry)

            if image.width > width:
                # there is extra width on this image, it must be cropped
                x_offset = math.floor(float(image.width - width) / 2)
                crop_geometry = '{width}x{height}+{x_offset}+{y_offset}'.format(width=width, height=height, x_offset=x_offset, y_offset=0)
                image.transform(crop=crop_geometry)
            elif image.height > height:
                # there is extra height on this image, it must be cropped
                y_offset = math.floor(float(image.height - height) / 2)
                crop_geometry = '{width}x{height}+{x_offset}+{y_offset}'.format(width=width, height=height, x_offset=0, y_offset=y_offset)
                image.transform(crop=crop_geometry)

        log.debug('About to save {}'.format(new_file_path))
        image.save(filename=new_file_path)
        log.debug('Saved {}'.format(new_file_path))

        return True


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import unicode_literals

import numpy as np
import matplotlib.pyplot as plt

plt.rc('font', family='Arial')
plt.rcParams.update({'font.size': 18})

def teo_function(d):
    return 1/(d-15)

vecfunc = np.vectorize(teo_function)

d = np.arange(16, 100.0, 0.01)
T = vecfunc(d)
plt.plot (d, T, 'bo', d, T, 'k')
plt.ylabel('T', fontsize=30)
plt.xlabel('μ', fontsize=30)
plt.title('T - μ graph. λ=15', fontsize=30)

plt.show()

BLG 517E - Modelling and Performance Analysis of Networks/hw/2/3.py


import cv2
import os
import numpy as np

def filting_red_by_HSV(image):
    hsv = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)

    lower_red = np.array([170,200,240])
    upper_red = np.array([180,255,255])

    mask_red = cv2.inRange(hsv, lower_red, upper_red)

    red_HSV = cv2.bitwise_and(image, image, mask= mask_red)
    return red_HSV

# base dir
dataset_dir = os.path.abspath("/Users/heetop/Desktop/Dataset")
if os.path.isdir(dataset_dir)==False:
    dataset_dir = os.path.abspath("C:/Users/knyup/OneDrive/SW_Mae/Camcha/Dataset")

video_path=os.path.join(dataset_dir,"videos/white/bright_white_spot_9.mp4")

# video load
cap = cv2.VideoCapture(video_path)

# Set parameters
params = cv2.SimpleBlobDetector_Params()
    # Change thresholds
params.minThreshold = 10
params.maxThreshold = 255
# params.maxThreshold = 200
    # Filter by Area.
params.filterByArea = True
params.minArea = 0.5
params.maxArea = 30
    # Filter by Circularity
params.filterByCircularity = True
params.minCircularity = 0.1
    # Filter by Convexity
params.filterByConvexity = True
params.minConvexity = 0.7
    # Filter by Inertia
params.filterByInertia = True
params.minInertiaRatio = 0.01

    # Filter by Color
params.filterByColor = True
params.blobColor = 255

detector = cv2.SimpleBlobDetector_create(params)

while(cap.isOpened()):

    ret, white_image = cap.read()
    white_image = cv2.resize(white_image,(960,540))

    #1. HSV - Finding Red Color
    red_HSV = filting_red_by_HSV(white_image)

    #2-Heetop. Dilate - make spot be larger
    dilate = cv2.dilate(red_HSV,None,iterations=1)

    #3. Blob - Finding circle
    keypoints_dilate = detector.detect(dilate)
    for i in range(len(keypoints_dilate)):
        x = int(keypoints_dilate[i].pt[0]) # x axis
        y = int(keypoints_dilate[i].pt[1]) # y axis

        cv2.circle(white_image, (x,y), 10, (0, 255, 0), 2)

    im_wit_keypoints_dilate = cv2.drawKeypoints(white_image,keypoints_dilate,np.array([]),(255,0,0),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

    # Output Part
    cv2.imshow("dilate",dilate)
    cv2.imshow("im_wit_keypoints_dilate",im_wit_keypoints_dilate)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()


from flask import Flask, render_template, redirect, url_for

from flask_sqlalchemy import SQLAlchemy
from wtforms import StringField, IntegerField
from wtforms.validators import Length, NumberRange
from flask_wtf import FlaskForm

app = Flask(__name__)

app.config['SECRET_KEY'] = 'secret!'  # Best generated using a cryptographic random generator, and to be kept secret!
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://Laurent@localhost/Laurent'  # Replace with your DB URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # SQLAlchemy's event system, which we don't need hogging memory

db = SQLAlchemy(app)  # SQLAlchemy's Flask wrapper

# Our implementation of a Flask-WTF login form
class InvestmentForm(FlaskForm):
    name = StringField('Username', validators=[Length(min=4, max=50)])
    investment_amount = IntegerField('Amount')  # TODO: validate with NumberRange using the numbers in Company model
    account_number = IntegerField('Account Number')  # TODO: validate with standard USA account number length
    routing_number = IntegerField('Routing Number')  # TODO: validate with standard USA routing number length

# SQLAlchemy Company model for companies who are seeking investments
class Company(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True)
    min_investment = db.Column(db.Integer)  # TODO: use NUMERIC to handle cents
    max_investment = db.Column(db.Integer)  # TODO: use NUMERIC to handle cents
    current_investment = db.Column(db.Integer)  # TODO: use NUMERIC to handle cents
    funding_goal = db.Column(db.Integer)  # TODO: use NUMERIC to handle cents
    investments = db.relationship('Investment', backref='company', lazy='dynamic')

# SQLAlchemy Investor model for investors who are seeking to invest
class Investor(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True)
    investments = db.relationship('Investment', backref='investor', lazy='dynamic')
    bank_accounts = db.relationship('BankAccount', backref='investor', lazy='dynamic')

# SQLAlchemy Investor model for investor bank accounts
class BankAccount(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    number = db.Column(db.Integer, unique=True)
    routing = db.Column(db.Integer)
    investor_id = db.Column(db.Integer, db.ForeignKey('investor.id'))

# SQLAlchemy Investment model for investments deals
class Investment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    amount = db.Column(db.Integer)
    investor_id = db.Column(db.Integer, db.ForeignKey('investor.id'))
    company_id = db.Column(db.Integer, db.ForeignKey('company.id'))

@app.route('/', methods=['GET', 'POST'])
def index():
    # Company lookup
    # TODO: Have proper company lookup before passing on appropriate info to template
    company = Company.query.filter_by(name='Ellison Eyewear').first()
    # If the mock company doesn't exist, we create an entry for it in the DB
    if company is None:
        db_company = Company(name='Ellison Eyewear', min_investment=5, max_investment=20, current_investment=0,
                             funding_goal=50000)
        db.session.add(db_company)
        db.session.commit()
        company = Company.query.filter_by(name='Ellison Eyewear').first()

    # Then we initialize our Flask-WTF form
    form = InvestmentForm()
    # If the POST request is valid, we proceed with the investment
    if form.validate_on_submit():
        name = form.name.data.lower()
        investment_amount = form.investment_amount.data
        account_number = form.account_number.data
        routing_number = form.routing_number.data

        # We look the investor up in the DB
        investor = Investor.query.filter_by(name=name).first()
        # If the investor doesn't exist, we create an entry in the DB for them
        if investor is None:
            db_investor = Investor(name=name)
            db.session.add(db_investor)
            db.session.commit()
            investor = Investor.query.filter_by(name=name).first()

        # We then look for the bank account number in the DB
        bank_account = BankAccount.query.filter_by(number=account_number).first()
        # If the bank account doesn't exist, we create an entry in the DB for it
        if bank_account is None:
            db_bank_account = BankAccount(number=account_number, routing=routing_number, investor_id=investor.id)
            db.session.add(db_bank_account)

        # We then log the transaction
        db_investment = Investment(amount=investment_amount, investor_id=investor.id, company_id=company.id)
        db.session.add(db_investment)

        # And then increment the current funding status
        company.current_investment += investment_amount
        db.session.commit()

        # Time to redirect the user to some well-earned congratulations!
        return redirect(url_for('thanks'))

    # Otherwise if it's a GET request, we show the investment template passing in the form
    return render_template('investment.html', form=form, company=company)

@app.route('/thanks')
def thanks():
    return render_template('thanks.html')

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


import sys
from mako.template import Template

def lstripLines(str):
    return '\n'.join([line.lstrip() for line in str.splitlines()])

def train_controller():
    input_filename = "train_controller.mako"
    config = {"N_Trains": 2,
              "N_Controllers": 1}
    output_filename = f"train_controller_{config['N_Trains']}t_{config['N_Controllers']}c.txt"

    return input_filename, output_filename, config

def train_controller_synchronous():
    input_filename = "train_controller_synchronous.mako"
    config = {"N_Trains": 2,
              "N_Controllers": 1}
    output_filename = f"train_controller_synchronous_{config['N_Trains']}t_{config['N_Controllers']}c.txt"

    return input_filename, output_filename, config

def simple_voting():
    input_filename = "simple_voting.mako"
    config = {"N_Voters": 1,
              "N_Candidates": 2}
    output_filename = f"simple_voting_{config['N_Voters']}v_{config['N_Candidates']}c.txt"

    return input_filename, output_filename, config

def selene():
    input_filename = "selene.mako"
    config = {"N_Voters": 1,
              "N_CVoters": 1,
              "N_Candidates": 2}
    output_filename = f"selene_{config['N_Voters']}v_{config['N_CVoters']}cv_{config['N_Candidates']}c.txt"

    return input_filename, output_filename, config

if __name__ == "__main__":
    input_path = "specs/templates/"
    output_path = "specs/generated/"

    input_filename, output_filename, config = selene()

    template = Template(filename=input_path + input_filename)

    out = lstripLines(template.render(**config))

    with open(output_path + output_filename, 'w') as file:
        file.write(out)


# isis_cutscenes.py
import pygame, array
pygame.init()
from isis_draw import *
from isis_zip import *
from isis_font import *
from isis_constants import *

# Loads Cut-Scenes into a 2D array of (320x200) surfaces
# If there are N levels:
#   CutScene[0  ][0...m] = Intro
#   CutScene[i  ][0...m] = Level i
#   CutScene[N+1][0...m] = Ending

srfcCheckPoints = gfnLoad_Splice(16, 16, gfn_Zip("checkpoints.png"), 1, 1)

def gfn_LoadCutscenes():
    tempCutScenes = []
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene-intro.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene1.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene2.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene3.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene4.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene5.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene6.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene7.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene8.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene9.png"), 0, 0))
    tempCutScenes.append(gfnLoad_Splice(320, 200, gfn_Zip("cutscene-ending.png"), 0, 0))
    return tempCutScenes

def gfn_LoadCutSceneNames():
    tempCSNames = []
    tempCSNames.append("cutscene-intro.png")
    tempCSNames.append("cutscene1.png")
    tempCSNames.append("cutscene2.png")
    tempCSNames.append("cutscene3.png")
    tempCSNames.append("cutscene4.png")
    tempCSNames.append("cutscene5.png")
    tempCSNames.append("cutscene6.png")
    tempCSNames.append("cutscene7.png")
    tempCSNames.append("cutscene8.png")
    tempCSNames.append("cutscene9.png")
    tempCSNames.append("cutscene-ending.png")
    tempCSNames.append("cutscene5.png")
    tempCSNames.append("cutscene5.png")
    tempCSNames.append("cutscene5.png")
    tempCSNames.append("cutscene5.png")
    tempCSNames.append("cutscene5.png")
    tempCSNames.append("cutscene5.png")
    tempCSNames.append("cutscene-ending.png")
    return tempCSNames

# Load Level list - should match # of cut-scenes
def gfn_LoadLevels():
    tempLevels = []

    #tempLevels.append("dummy1.tmx")
    #tempLevels.append("dummy2.tmx")
    #tempLevels.append("dummy3.tmx")
    #tempLevels.append("dummy4.tmx")
    #tempLevels.append("dummy5.tmx")
    #tempLevels.append("doortest.tmx")
    #tempLevels.append("clock.tmx")
    #tempLevels.append("level1-test.tmx")
    tempLevels.append("level1-jungle.tmx")
    tempLevels.append("level2-jungle.tmx")
    tempLevels.append("level3-mountain.tmx")
    tempLevels.append("level4-cave.tmx")
    tempLevels.append("level5-minefield.tmx")
    tempLevels.append("level6-artillery.tmx")
    tempLevels.append("level7-hangar.tmx")
    tempLevels.append("level8-central_command.tmx")
    tempLevels.append("level9-dungeon.tmx")

    return tempLevels

def gfn_LoadLevelNames():
    tempNames = []
    tempNames.append("Jungle")
    tempNames.append("Jungle Nights")
    tempNames.append("Mountain")
    tempNames.append("Cave")
    tempNames.append("Minefield")
    tempNames.append("Artillery Division")
    tempNames.append("Hangar")
    tempNames.append("Central Command")
    tempNames.append("Dungeon")
    tempNames.append("Barracks")
    tempNames.append("Missile Tower")
    tempNames.append("Ocean Moat")
    tempNames.append("Secret Island")
    tempNames.append("Castle Garden")
    tempNames.append("Imperial Castle")
    tempNames.append("Rooftop Showdown")
    return tempNames

# Background List
def gfn_LoadBackgrounds():
    tempBGs = []
    tempBGs.append("bg0.png")
    tempBGs.append("bg1.png")
    tempBGs.append("bg2.png")
    tempBGs.append("bg3.png")
    tempBGs.append("bg4.png")
    tempBGs.append("bg5.png")
    tempBGs.append("bg6.png")
    tempBGs.append("bg7.png")
    return tempBGs

class gcls_CheckPoint(pygame.sprite.Sprite):
    def __init__(self, inX, inY):
        pygame.sprite.Sprite.__init__(self)
        self.x = inX * TILESIZE
        self.y = inY * TILESIZE
        self.image = srfcCheckPoints[0]
        self.active = True
        self.rect = pygame.Rect(round(self.x), round(self.y), TILESIZE, TILESIZE)

    def update(self, inLevel):
        self.rect = pygame.Rect(round(self.x - inLevel.mapX) + inLevel.playX, round(self.y - inLevel.mapY) + inLevel.playY, TILESIZE, TILESIZE)

# Game State
STATE_MENU = 0
STATE_LEVEL = 1
STATE_CUTSCENE = 2
STATE_FADEOUT_NEXTLEVEL = 3
STATE_FADEOUT_KILL = 4
STATE_FADEOUT_GAMEOVER = 5

# Progress Screen Surfaces
srfcStarOutline = pygame.image.load(gfn_Zip("progress_star-outline.png")).convert_alpha()
srfcStarFilled = pygame.image.load(gfn_Zip("progress_star-filled.png")).convert_alpha()
srfcStarShadow = pygame.image.load(gfn_Zip("progress_star-shadow.png")).convert_alpha()
srfcBoxRed = pygame.image.load(gfn_Zip("progress_box-red.png")).convert_alpha()
srfcBoxGreen = pygame.image.load(gfn_Zip("progress_box-green.png")).convert_alpha()
srfcBoxGrey = pygame.image.load(gfn_Zip("progress_box-grey.png")).convert_alpha()
srfcInventory = gfnLoad_Splice(16, 16, gfn_Zip("progress_inventory.png"), 1, 1)

class gcls_Game():
    def __init__(self):
        self.level = gfn_LoadLevels()
        self.level_names = gfn_LoadLevelNames()
        self.level_ID = 0
        self.CSNames = gfn_LoadCutSceneNames()
        self.srfcCutScenes = gfnLoad_Splice(320, 200, gfn_Zip(self.CSNames[0]), 0, 0)
        self.cutScene_ID = 0
        self.state = STATE_CUTSCENE
        self.displayWidth = 320
        self.displayHeight = 200
        self.backgrounds = gfn_LoadBackgrounds()
        self.srfcNight = pygame.image.load(gfn_Zip("night.png")).convert(16)
        self.srfcNight.set_alpha(0.40 * 255)
        self.fadeIn = True
        self.fadeOut = False
        self.fadeTime = 0.5
        self.fadeTimer = self.fadeTime

        self.sound = True
        self.music = True

        # Availability of Levels (if they've been completed before), as well as lives & points to start from
        #self.level_rankings, self.level_lives, self.level_points, self.level_weapons, self.level_inventory = gfn_LoadSavedData()

        # LOAD SAVEGAME.IS2 (if exists) OTHERWISE FILL WITH DEFAULTS
        self.SAVED_DATA = gfn_LoadSaveDataNew()

        # Debug
        self.debug = gcls_Debug()

        # Custom level
        self.custom = False
        self.customLevel = None

    def reset(self):
        self.level_ID = 1
        self.cutScene_ID = 0
        self.custom = False
        self.customLevel = None

    def drawStats(self, inLevel, inKeen, inOldLevel, inNextLevel):

        # Calculations
        if inLevel.stats_NumItems_Tot != 0: tempItemsPercent = round((inLevel.stats_NumItems / inLevel.stats_NumItems_Tot) * 100.0, 1)
        else: tempItemsPercent = 100

        if inLevel.stats_NumPoints_Tot != 0: tempPointsPercent = round((inLevel.stats_NumPoints / inLevel.stats_NumPoints_Tot) * 100.0, 1)
        else: tempPointsPercent = 100

        if inLevel.stats_NumEnemies_Tot != 0: tempEnemiesPercent = round((inLevel.stats_NumEnemies / inLevel.stats_NumEnemies_Tot) * 100.0, 1)
        else: tempEnemiesPercent = 100

        """
        # Star calc here - OLD RATING
        # Stars (Level Rating)
        # 10 - 100% points, items, enemies
        #  9 - 100% points, items
        #  8 - 100% points
        #  7 - points <= 90%
        #  6 - points <= 70%
        #  5 - points <= 50%
        #  4 - points <= 30%
        #  3 - points <= 20%
        #  2 - points > 0%
        #  1 - all 0%

        if tempPointsPercent == 100 and tempItemsPercent == 100 and tempEnemiesPercent == 100: tempRating = 10
        elif tempPointsPercent == 100 and tempItemsPercent == 100:  tempRating = 9
        elif tempPointsPercent == 100 : tempRating = 8
        elif tempPointsPercent >= 90: tempRating = 7
        elif tempPointsPercent >= 70: tempRating = 6
        elif tempPointsPercent >= 50: tempRating = 5
        elif tempPointsPercent >= 30: tempRating = 4
        elif tempPointsPercent >= 10: tempRating = 3
        elif tempPointsPercent > 0: tempRating = 2
        else: tempRating = 1
        """

        # NEW RATING
        # 10 - 100% items, enemies
        #  9 - 100% items
        #  8 - items >= 90%
        #  7 - items >= 75%
        #  6 - items >= 60%
        #  5 - items >= 45%
        #  4 - items >= 30%
        #  3 - items >= 15%
        #  2 - items > 0%
        #  1 - all 0%

        """
        # OLD RATING
        if tempItemsPercent == 100 and tempEnemiesPercent == 100: tempRating = 10
        elif tempItemsPercent == 100:  tempRating = 9
        elif tempItemsPercent >= 90 : tempRating = 8
        elif tempItemsPercent >= 75: tempRating = 7
        elif tempItemsPercent >= 60: tempRating = 6
        elif tempItemsPercent >= 45: tempRating = 5
        elif tempItemsPercent >= 30: tempRating = 4
        elif tempItemsPercent >= 15: tempRating = 3
        elif tempItemsPercent > 0: tempRating = 2
        else: tempRating = 1
        """

        if tempItemsPercent == 100:  tempRating = 10
        elif tempItemsPercent >= 90: tempRating = 9
        elif tempItemsPercent >= 80: tempRating = 8
        elif tempItemsPercent >= 70: tempRating = 7
        elif tempItemsPercent >= 60: tempRating = 6
        elif tempItemsPercent >= 50: tempRating = 5
        elif tempItemsPercent >= 40: tempRating = 4
        elif tempItemsPercent >= 30: tempRating = 3
        elif tempItemsPercent >= 20: tempRating = 2
        else: tempRating = 1

        # Set points, lives, stars, weapons, inventory
        #if inKeen.score > self.level_points[self.level_ID - 1]: self.level_points[self.level_ID - 1] = inKeen.score
        #if inKeen.lives > self.level_lives[self.level_ID - 1]: self.level_lives[self.level_ID - 1] = inKeen.lives
        #if tempRating > self.level_rankings[self.level_ID - 1]: self.level_rankings[self.level_ID - 1] = tempRating
        #if self.level_rankings[inNextLevel - 1] == -1: self.level_rankings[inNextLevel - 1] = 0

        # Write new file
        #gfn_WriteSavedData(self.level_rankings, self.level_lives, self.level_points)

        # UPDATE SAVED_DATA and SAVE NEW FILE
        self.SAVED_DATA[inOldLevel - 1].ranking = tempRating
        self.SAVED_DATA[inOldLevel - 1].lives = inKeen.lives
        self.SAVED_DATA[inOldLevel - 1].health = inKeen.health
        self.SAVED_DATA[inOldLevel - 1].points = inKeen.score
        self.SAVED_DATA[inOldLevel - 1].ammo = [inKeen.weapon[i].ammo for i in range(9)]
        self.SAVED_DATA[inOldLevel - 1].inventory = [inKeen.inventory[i].power for i in range(4)]
        self.SAVED_DATA[inOldLevel - 1].inventory.append(inKeen.invMaxPower)
        if self.SAVED_DATA[inNextLevel - 1].ranking == -1: self.SAVED_DATA[inNextLevel - 1].ranking = 0
        gfn_WriteSaveDataNew(self.SAVED_DATA)

        # Text
        txt_Heading1 = "Commander Keen in..."
        txt_Heading2 = "The Mystery of Isis IIa"
        txt_Heading3 = "Level " + str(inOldLevel) + " - '" + self.level_names[inOldLevel - 1] + "' - Complete!"
        txt_Item1 = "- Items Collected: " + str(inLevel.stats_NumItems) + "/" + str(int(inLevel.stats_NumItems_Tot)) + " (" + str(tempItemsPercent) + "%)"
        txt_Item2 = "- Points Scored: " + str(inLevel.stats_NumPoints) + "/" + str(int(inLevel.stats_NumPoints_Tot)) + " (" + str(tempPointsPercent) + "%)"
        txt_Item3 = "- Enemies Killed: " + str(inLevel.stats_NumEnemies) + "/" + str(int(inLevel.stats_NumEnemies_Tot)) + " (" + str(tempEnemiesPercent) + "%)"
        txt_LevelRating = "Your rating:"
        txt_GameProgress = "Overall Game Progress:"
        #txt_GameRatings = self.level_rankings
        txt_Battery = "17/20"
        txt_Code = "KEEN"

        # Sizes
        STAR_SPACING = 3
        width_h2, height_h2 = fontGREMLINS.size(txt_Heading2)
        width_h3, height_h3 = fontCK_MEDIUM.size(txt_Heading3)
        width_item1, height_item1 = fontCK_MEDIUM.size(txt_Item1)
        width_star, height_star = srfcStarOutline.get_width(), srfcStarOutline.get_height()
        width_stars = (width_star * 10) + (STAR_SPACING * 9)
        width_box, height_box = srfcBoxRed.get_width(), srfcBoxRed.get_height()
        width_boxes = width_box * 16
        width_inventory, height_inventory = srfcInventory[0].get_width(), srfcInventory[0].get_height()
        width_battery, height_battery = fontCK_SMALL.size(txt_Battery)
        width_code, height_code = fontSGA_ROUND.size(txt_Code)

        # Positions
        POS_HEAD1 = [10, 10]
        POS_HEAD2 = [(self.displayWidth - width_h2) / 2.0, 20]
        POS_HEAD3 = [(self.displayWidth - width_h3) / 2.0, 50]
        POS_INDENT = [40, 70]
        POS_EXTRA = 3
        POS_ITEM1 = [POS_INDENT[0], POS_INDENT[1] + ((height_item1 + POS_EXTRA) * 0)]
        POS_ITEM2 = [POS_INDENT[0], POS_INDENT[1] + ((height_item1 + POS_EXTRA) * 1)]
        POS_ITEM3 = [POS_INDENT[0], POS_INDENT[1] + ((height_item1 + POS_EXTRA) * 2)]
        POS_LEVEL_RATING = [POS_INDENT[0], POS_INDENT[1] +((height_item1 + POS_EXTRA) * 3.6)]
        POS_STAR = [(self.displayWidth - width_stars) / 2.0, POS_LEVEL_RATING[1] + 14]
        POS_GAME_PROGRESS = [POS_HEAD1[0], POS_STAR[1] + height_star + 10]
        POS_BOXES = [(self.displayWidth - width_boxes) / 2.0, POS_GAME_PROGRESS[1] + 11]
        POS_INVENTORY = [270, 55]
        POS_CODE = [self.displayWidth - width_code - 5, 5]

        # Headings
        txtr_Heading1 = fontCK_SMALL.render(txt_Heading1, 1, (255, 255, 255))
        txtr_Heading2 = fontGREMLINS.render(txt_Heading2, 1, (255, 255, 255))
        txtr_Heading2s = fontGREMLINS.render(txt_Heading2, 1, (100, 100, 100))
        txtr_Heading3 = fontCK_MEDIUM.render(txt_Heading3, 1, (100, 100, 255))
        txtr_Item1 = fontCK_MEDIUM.render(txt_Item1, 1, (255, 255, 255))
        txtr_Item2 = fontCK_MEDIUM.render(txt_Item2, 1, (255, 255, 255))
        txtr_Item3 = fontCK_MEDIUM.render(txt_Item3, 1, (255, 255, 255))
        txtr_LevelRating = fontCK_MEDIUM.render(txt_LevelRating, 1, (255, 255, 255))
        txtr_GameProgress = fontCK_SMALL.render(txt_GameProgress, 1, (255, 255, 255))
        txtr_Battery = fontCK_SMALL.render(txt_Battery, 1, (129, 255, 44))
        txtr_Code = fontSGA_ROUND.render(txt_Code, 1, (255, 75, 75))

        # Display
        self.srfcCutScenes[0].fill((0, 0, 0))
        self.srfcCutScenes[0].blit(txtr_Heading1, (POS_HEAD1[0], POS_HEAD1[1]))
        self.srfcCutScenes[0].blit(txtr_Heading2s, (POS_HEAD2[0]+1, POS_HEAD2[1]+1))
        self.srfcCutScenes[0].blit(txtr_Heading2, (POS_HEAD2[0], POS_HEAD2[1]))
        self.srfcCutScenes[0].blit(txtr_Heading3, (POS_HEAD3[0], POS_HEAD3[1]))
        self.srfcCutScenes[0].blit(txtr_Item1, (POS_ITEM1[0], POS_ITEM1[1]))
        self.srfcCutScenes[0].blit(txtr_Item2, (POS_ITEM2[0], POS_ITEM2[1]))
        self.srfcCutScenes[0].blit(txtr_Item3, (POS_ITEM3[0], POS_ITEM3[1]))
        self.srfcCutScenes[0].blit(txtr_LevelRating, (POS_LEVEL_RATING[0], POS_LEVEL_RATING[1]))
        self.srfcCutScenes[0].blit(txtr_GameProgress, (POS_GAME_PROGRESS[0], POS_GAME_PROGRESS[1]))

        for i in range(10):
            posX = POS_STAR[0] + ((width_star + STAR_SPACING) * i)
            posY = POS_STAR[1]
            self.srfcCutScenes[0].blit(srfcStarShadow, (posX + 1, posY + 1))
            if i < tempRating: self.srfcCutScenes[0].blit(srfcStarFilled, (posX, posY))
            else: self.srfcCutScenes[0].blit(srfcStarOutline, (posX, posY))

        # Boxes (Game Progress)
        for i in range(16):
            posX = POS_BOXES[0] + (width_box * i)
            posY = POS_BOXES[1]

            #tempTextRating = str(txt_GameRatings[i])
            tempTextRating = str(self.SAVED_DATA[i].ranking)
            txtr_tempTextRating = fontCK_SMALL.render(tempTextRating, 1, (255, 255, 255))
            width_tempTextRating, height_tempTextRating = fontCK_SMALL.size(tempTextRating)
            posX2 = posX + ((width_box - width_tempTextRating) / 2.0)
            posY2 = posY + ((height_box - height_tempTextRating) / 2.0)

            if self.SAVED_DATA[i].ranking > 0:
                self.srfcCutScenes[0].blit(srfcBoxGreen, (posX, posY))
                self.srfcCutScenes[0].blit(txtr_tempTextRating, (posX2, posY2))
            elif i < len(self.level):
                self.srfcCutScenes[0].blit(srfcBoxRed, (posX, posY))
                if self.SAVED_DATA[i].ranking > 0: self.srfcCutScenes[0].blit(txtr_tempTextRating, (posX2, posY2))
            else:
                self.srfcCutScenes[0].blit(srfcBoxGrey, (posX, posY))

DEBUG_NIL = 0
DEBUG_HELLO = 1
DEBUG_STATS = 2

# Debug class
class gcls_Debug():
    def __init__(self):
        self.COLS = [(255, 255, 255), (128, 128, 128), (0, 0, 0)]
        self.on = False
        self.hidden = False
        self.message = DEBUG_NIL
        self.messageCol = 0
        self.jump = False


import base64
import linecache
import random
from datetime import datetime, timedelta
from io import BytesIO

from PIL import Image
from captcha.image import ImageCaptcha
from flask import Flask, render_template, request
from flask_cors import CORS

import captcha_sets
import config
import const
import oauth
import security
from models import User, AccessToken, Answer, Captcha

app = Flask(__name__)
CORS(app)

@app.route('/')
@app.route('/ru')
@app.route('/en')
def index():
    return render_template('index.html', lang=detect_lang(), site_host=config.site_host)

@app.route('/privacy')
def privacy():
    return render_template('privacy.html')

@app.route('/facebook/delete')
def delete_facebook_data():
    return render_template('deletion.html')

@app.route('/auth/<provider>')
def auth(provider):
    if provider not in ['facebook', 'vk', 'google']:
        return f"Unknown auth provider: {provider}", 403

    if security.user() is not None:
        return render_template('auth_failed.html', err="Already authorized", provider=provider,
                               lang=security.user().lang), 403

    code = request.args.get('code', None)

    try:
        if provider == 'vk':
            user_id, token = oauth.vk_token(code)
        elif provider == 'facebook':
            user_id, token = oauth.fb_token(code)
        elif provider == 'google':
            user_id, token = oauth.google_token(code)
        else:
            raise RuntimeError('Unknown provider')
    except RuntimeError:
        return render_template('auth_failed.html', err="Cannot get token", provider=provider,
                               lang=detect_lang()), 400

    user = User.get_or_none(User.source == provider, User.source_id == user_id)
    if not user:
        try:
            name = oauth.get_user_name(provider, user_id, token)
            user = User.create(source=provider, source_id=user_id, lang=detect_lang(), name=name)
        except:
            user = None

    if not user:
        return render_template('auth_failed.html', err="Cannot create user", provider=provider, lang=detect_lang()), 500

    token = AccessToken.create(user, expire_in_days=7)
    return render_template('auth_success.html', token=token.token, user=user)

@app.route('/user', methods=['GET'])
@security.protected
def user_info():
    user = security.user()
    if not user:
        return {}, 401
    user_answer = user.get_answer()

    return {
        "name": user.name,
        "lang": user.lang,
        "step": None if user_answer is None else user_answer.step
    }

@app.route('/user', methods=['PATCH'])
@security.protected
def update_lang():
    user = security.user()
    if not user:
        return {}, 401

    lang = request.json.get('lang')
    if lang not in ['ru', 'en']:
        return {}, 400

    user.lang = lang
    user.save()

    return {}

@app.route('/stats', methods=['GET'])
@security.protected
def stats():
    user = security.user()
    if not user:
        return {}, 401
    user_answer = user.get_answer()
    if user_answer is None or user_answer.step != const.STEP_CAPTCHA_SOLVED:
        return {}, 403

    humans = Answer.select().where(Answer.step == const.STEP_CAPTCHA_SOLVED, Answer.value == 0).count()
    robots = Answer.select().where(Answer.step == const.STEP_CAPTCHA_SOLVED, Answer.value == 1).count()

    return {"answer": user_answer.value, "humans": humans, "robots": robots}

@app.route('/captcha', methods=['GET'])
@security.protected
def captcha():
    user = security.user()
    if not user:
        return {}, 401
    user_answer = user.get_answer()
    if user_answer is None or user_answer.step == const.STEP_CAPTCHA_SOLVED:
        return {}, 403

    step = user_answer.step
    code = Captcha.generate_code()
    random.seed(code)

    if step == 0:
        answer = random.randint(1000, 9999)
        Captcha.create(code=code, value=answer, expire_at=datetime.utcnow() + timedelta(minutes=5))

        return {
            'code': code,
            'question': answer
        }
    elif step == 1:
        answer = linecache.getline('captcha/words.txt', random.randint(0, 825)).strip()
        image_captcha = ImageCaptcha(fonts=['captcha/font.ttf'], width=320, height=120)
        image = image_captcha.generate(answer)
        Captcha.create(code=code, value=answer, expire_at=datetime.utcnow() + timedelta(minutes=5))

        return {
            'code': code,
            'image': base64.b64encode(image.read()).decode('utf-8')
        }
    elif step == 2:
        group = random.randint(0, 5)
        answers_length = random.randint(3, 5)

        answers = []
        while len(answers) < answers_length:
            while True:
                ans = random.choice(captcha_sets.GROUPS[group])
                if ans not in answers:
                    break
            answers.append(ans)

        rest_images = [x for x in captcha_sets.ALL if x not in captcha_sets.GROUPS[group]]
        images = [
            *answers,
        ]
        while len(images) < 9:
            while True:
                img = random.choice(rest_images)
                if img not in images:
                    break
            images.append(img)
        random.shuffle(images)

        answer = "".join([str(i) for i in range(0, 9) if images[i] in captcha_sets.GROUPS[group]])
        Captcha.create(code=code, value=answer, question=group, expire_at=datetime.utcnow() + timedelta(minutes=5))

        images_b64 = []
        for image in images:
            img = Image.open(f'captcha/sets/{image}')
            img.thumbnail((64, 64))

            out = BytesIO()
            img.save(out, "JPEG", quality=85)
            out.seek(0)

            images_b64.append(base64.b64encode(out.read()).decode('utf-8'))

        return {
            'code': code,
            'images': images_b64,
            'question': captcha_sets.NAMES[group]
        }

@app.route('/captcha', methods=['POST'])
@security.protected
def check_captcha():
    user = security.user()
    if not user:
        return {}, 401

    user_answer = user.get_answer()
    if user_answer is None or user_answer.step == const.STEP_CAPTCHA_SOLVED:
        return {}, 403

    code = request.json.get('code')
    answer = request.json.get('answer')

    captcha = Captcha.get_or_none(Captcha.code == code)
    if captcha.expire_at <= datetime.utcnow():
        return {'error': 'Captcha expired'}, 400

    if captcha.value != answer:
        return {'error': 'Invalid captcha'}, 400

    captcha.expire_at = datetime.utcnow()
    captcha.save()

    user_answer.step += 1
    user_answer.save()

    if user_answer.step != const.STEP_CAPTCHA_SOLVED:
        return {"step": user_answer.step}, 418

    return {}, 200

@app.route('/answer', methods=['POST'])
@security.protected
def answer():
    user = security.user()
    if not user:
        return {}, 401
    user_answer = user.get_answer()
    if user_answer is not None and user_answer.step == const.STEP_CAPTCHA_SOLVED:
        return {}, 403

    option = int(request.json.get('option'))

    if option not in [0, 1]:
        return {'error': f'Unknown option: {option}'}, 400

    step = const.STEP_SIMPLE_CAPTCHA
    if option == 1:
        step = const.STEP_CAPTCHA_SOLVED

    created = False
    ans = Answer.get_or_none(Answer.user == user)
    if not ans:
        created = True
        ans = Answer.create(user=user, value=option, step=step)
    if not ans:
        return {'error': 'Cannot save answer'}, 500

    if not created:
        ans.value = option
        ans.step = max(step, ans.step)
        ans.save()

    if step == const.STEP_CAPTCHA_SOLVED:
        return {}, 200
    else:
        return {"step": ans.step}, 418

def detect_lang():
    return 'ru'

def open_db_connection():
    if config.db.is_closed():
        config.db.connect(reuse_if_open=True)

def close_db_connection(response):
    if not config.db.is_closed():
        config.db.close()
    return response

app.before_request(open_db_connection)
app.after_request(close_db_connection)

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


#!/usr/bin/env python3

import geopandas as gpd
import re

def getLabels(wardNumber, orientation, roadsWard, wards, names, types, positions):

    '''Choose just one road label location
    from the many possible road labeling locations
    based on the provided road names, types, and positions
    for each road

    '''

    # Calculate bounding values for the ward
    b = wards[wardNumber-1:wardNumber].bounds
    xmin = b.minx.values[0]
    xmax = b.maxx.values[0]
    ymin = b.miny.values[0]
    ymax = b.maxy.values[0]

    # Calculate a central point for the ward (a point borrowed from when we plotted the wards earlier)
    xc = wards.loc[wardNumber-1, 'coords'][0]
    yc = wards.loc[wardNumber-1, 'coords'][1]

    # Calculate characteristic spatial values for every possible road label
    labels = gpd.GeoDataFrame(columns=roadsWard.columns)
    roadsWard['coords'] = roadsWard['geometry'].apply(lambda x: x.representative_point().coords[:])
    roadsWard['coords'] = [coords[0] for coords in roadsWard['coords']]
    roadsWard['long'] = roadsWard['coords'].apply(lambda x: x[0])
    roadsWard['lat'] = roadsWard['coords'].apply(lambda x: x[1])
    roadsWard['dist_from_yc'] = roadsWard['lat'].apply(lambda x: abs(x-yc))
    roadsWard['dist_from_xc'] = roadsWard['long'].apply(lambda x: abs(x-xc))

    # POSITION PARAMETER BREAKDOWN:
    # 'hcenter' places the label as close as it can to the horizontal center of the map
    # 'vcenter' places the label as close as it can to the vertical center of the map
    # 'left' places the label as close as it can to the left side of the map
    # 'right places the label as close as it can to the right side of the map
    # 'top' places the label as close as it can to the top of the map
    # 'bottom' places the label as close as it can to the bottom of the map

    for idx, r in enumerate(names.loc[wardNumber-1, orientation]):
        labelsRoad = roadsWard[roadsWard['name_left']==r]

        if types.loc[wardNumber-1, orientation][idx]!='any':
            labelsRoad = labelsRoad[labelsRoad['type']==types.loc[wardNumber-1, orientation][idx]]

        if positions.loc[wardNumber-1, orientation][idx]=='hcenter':
            label = labelsRoad[labelsRoad['dist_from_xc']==min(labelsRoad['dist_from_xc'])]
            if label.shape[0] > 1:
                label = label[label['dist_from_yc']==min(label['dist_from_yc'])]
        elif positions.loc[wardNumber-1, orientation][idx]=='vcenter':
            label = labelsRoad[labelsRoad['dist_from_yc']==min(labelsRoad['dist_from_yc'])]
            if label.shape[0] > 1:
                label = label[label['dist_from_xc']==min(label['dist_from_xc'])]
        elif positions.loc[wardNumber-1, orientation][idx]=='left':
            label = labelsRoad[labelsRoad['long']==min(labelsRoad['long'])]
            if label.shape[0] > 1:
                label = label[label['dist_from_yc']==min(label['dist_from_yc'])]
        elif positions.loc[wardNumber-1, orientation][idx]=='right':
            label = labelsRoad[labelsRoad['long']==max(labelsRoad['long'])]
            if label.shape[0] > 1:
                label = label[label['dist_from_yc']==min(label['dist_from_yc'])]
        elif positions.loc[wardNumber-1, orientation][idx]=='top':
            label = labelsRoad[labelsRoad['lat']==max(labelsRoad['lat'])]
            if label.shape[0] > 1:
                label = label[label['dist_from_xc']==min(label['dist_from_xc'])]
        elif positions.loc[wardNumber-1, orientation][idx]=='bottom':
            label = labelsRoad[labelsRoad['lat']==min(labelsRoad['lat'])]
            if label.shape[0] > 1:
                label = label[label['dist_from_xc']==min(label['dist_from_xc'])]

        labels = labels.append(label)

    # Abbreviate!
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('NW', '', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('North West', '', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('Avenue', 'Ave', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('Street', 'St', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('Road', 'Rd', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('Drive', 'Dr', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('Trail', 'Tr', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('Bridge', 'Brg', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('Boulevard', 'Blvd', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('West', 'W', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('South', 'S', x))
    labels['name_left'] = labels['name_left'].apply(lambda x: re.sub('Ogilvie Place', 'Ogilvie Blvd', x))

    return labels


from django.conf.urls import url
from django.views.generic import TemplateView
from . import views

urlpatterns = [
    url(r'login', views.loginUser, name="login"),
    url(r'api', views.apiView.as_view()),
    url(r'player/(?P<pk>\d+)', views.PlayerApi.as_view()),
    url(r'logout', views.logoutUser, name="logout"),
    url(r'update', views.putRequest),
    url(r'question.html', TemplateView.as_view(template_name="question.html")),
    url(r'finish.html', TemplateView.as_view(template_name="finish.html")),
    url(r'add.html', TemplateView.as_view(template_name="add.html")),
    url(r"", views.index, name="index"),

]


from app.models.composite import GameTeam

__author__ = 'changsuyouk'

import unittest

from app import db

class SimpleTest(unittest.TestCase):

    def setUp(self):
        pass

    def test_app(self):
        print("================")
        print("start testing test_gameid.py")
        db.drop_all()
        db.create_all()
        self.test_check_session()
        self.test_create_ids()

    def test_check_session(self):
        session = GameTeam.current_game_session()
        assert session == 1

    def test_create_ids(self):
        import datetime
        now = datetime.datetime.now()
        date_token = now.strftime("%y%m%d")

        date = int(date_token)
        job = "curator"
        count = 100
        session = 1

        print("Date {0}, Job {1}, count {2}".format(date, job, count))
        GameTeam.create_one(job, count)
        ids = GameTeam.search_ids_by_date_and_session(date, session)

        assert len(ids) == 100


from mathutils import Quaternion
from bpy.props import EnumProperty
from ..LiveEditingBaseNode import LiveEditingBaseNode

class QuaternionOperationNode(LiveEditingBaseNode):
    """Quaternion Operation Node"""
    bl_idname = 'QuaternionOperationNode'
    bl_label = 'Quaternion Operation Node'
    bl_icon = 'PLUS'

    op = EnumProperty(
        name="Operation",
        description="Quaternion Operation",
        default="ADD",
        items=[
            ("ADD", "A + B", "A plus B", 1),
            ("SUB", "A - B", "A minus B", 2),
            ("MUL", "A * B", "A multiplied by B", 3),
            ("CROSS", "Cross", "Cross product of A and B", 4),
            ("DOT", "Dot", "Dot product of A and B", 5),
            ("NORM", "Normalize", "Normalize A", 6),
            ("INVERT", "Invert", "Invert A", 7),
            ("ROTATE", "Rotate", "Rotate A by B", 8),
            ("ROTATION_DIFFERENCE", "Rotation Difference", "Difference of rotation between A and B", 9)
        ]
    )

    def init(self, context):
        super().init(context)

        self.inputs.new('NodeSocketQuaternion', "Quaternion A")
        self.inputs.new('NodeSocketQuaternion', "Quaternion B")

        self.outputs.new('NodeSocketQuaternion', "Quaternion")

    def draw_buttons(self, context, layout):
        layout.prop(self, "op")

    def run(self):
        out = None

        # A-Only Operations
        a = self.getInputValue("Quaternion A")

        if self.op == "NORM":
            out = a.normalized()
        elif self.op == "INVERT":
            out = a.inverted()
        else:
            # A - B Operations
            b = self.getInputValue("Quaternion B")

            if self.op == "ADD":
                out = a + b
            elif self.op == "SUB":
                out = a - b
            elif self.op == "MUL":
                out = a * b
            elif self.op == "CROSS":
                out = a.cross(b)
            elif self.op == "DOT":
                out = a.dot(b)
            elif self.op == "ROTATE":
                out = a.copy().rotate(b)
            elif self.op == "ROTATION_DIFFERENCE":
                out = a.rotation_difference(b)

        self.outputs["Quaternion"].default_value = out if out is not None else Quaternion((1.0, 0.0, 0.0, 0.0))


from __future__ import division, absolute_import

import six
import readline

# Use numpy if available for fast decoding
try:
    import numpy as np
    _numpy = True
except ImportError:  # pragma: no cover
    _numpy = False

def evaluate_ising(linear, quad, state):
    """Calculate the energy of a state given the Hamiltonian.

    Args:
        linear: Linear Hamiltonian terms.
        quad: Quadratic Hamiltonian terms.
        state: Vector of spins describing the system state.

    Returns:
        Energy of the state evaluated by the given energy function.
    """
    # If we were given a numpy array cast to list
    if _numpy and isinstance(state, np.ndarray):
        return evaluate_ising(linear, quad, state.tolist())

    # Accumulate the linear and quadratic values
    energy = 0.0
    for index, value in uniform_iterator(linear):
        energy += state[index] * value
    for (index_a, index_b), value in six.iteritems(quad):
        energy += value * state[index_a] * state[index_b]
    return energy

def uniform_iterator(sequence):
    """Uniform (key, value) iteration on a `dict`,
    or (idx, value) on a `list`."""

    if isinstance(sequence, dict):
        return six.iteritems(sequence)
    else:
        return enumerate(sequence)

def uniform_get(sequence, index, default=None):
    """Uniform `dict`/`list` item getter, where `index` is interpreted as a key
    for maps and as numeric index for lists."""

    if isinstance(sequence, dict):
        return sequence.get(index, default)
    else:
        return sequence[index] if index < len(sequence) else default

def readline_input(prompt, prefill=''):
    """Provide an editable default for ``input()``."""
    # see: https://stackoverflow.com/q/2533120/
    readline.set_startup_hook(lambda: readline.insert_text(prefill))
    try:
        return six.moves.input(prompt)
    finally:
        readline.set_startup_hook()


import os, sys
sys.path.insert(0, os.path.join(os.getenv('CITY_PATH'), 'src'))
import random
import logging
import sqlite3
import unittest
import shutil
from helperTesting        import TestMicroDbBase
from learning.helperImg   import ProcessorRandom
from learning.dbNegatives import *
from learning.dbNegatives import _generateNoiseMask_, _grayCircle_
from learning.dbNegatives import _grayMasked_, _getBboxesFromImage_

class TestMicroDb (TestMicroDbBase):

    def setUp (self):
        super(TestMicroDb, self).setUp()
        self.imageProcessor = ProcessorRandom({'dims': (100,100)})
        self.params_negativeGrayspots = {'image_processor': self.imageProcessor,
                                         'blur_sigma': 2, 'noise_level': 1, 'pixelation': 20}

    # _generateNoiseMask_

    def test_generateNoiseMask__0x0 (self):
        noise = _generateNoiseMask_ ((100, 100, 3), level = 0, avg_pixelation = 0)
        self.assertIsNotNone (noise)
        self.assertEqual (noise.shape, (100, 100, 3))
        self.assertEqual (noise.dtype, float)
        self.assertEqual (np.mean(noise), 128)  # image is exactly gray

    def test_generateNoiseMask__2x0 (self):
        noise = _generateNoiseMask_ ((100, 100, 3), 2, 0)
        self.assertIsNotNone (noise)
        self.assertEqual (noise.shape, (100, 100, 3))
        self.assertEqual (noise.dtype, float)
        self.assertAlmostEqual (np.mean(noise), 128, 0)  # image is almost gray

    def test_generateNoiseMask__0x2 (self):
        noise = _generateNoiseMask_ ((100, 100, 3), 0, 2)
        self.assertIsNotNone (noise)
        self.assertEqual (noise.shape, (100, 100, 3))
        self.assertEqual (noise.dtype, float)
        self.assertAlmostEqual (np.mean(noise), 128, 0)  # image is almost gray

    def test_generateNoiseMask__2x2 (self):
        noise = _generateNoiseMask_ ((100, 100, 3), 2, 10)
        self.assertIsNotNone (noise)
        self.assertEqual (noise.shape, (100, 100, 3))
        self.assertEqual (noise.dtype, float)
        self.assertAlmostEqual (np.mean(noise), 128, 0)  # image is almost gray

    # grayspots methods

    def test_grayCircle__ (self):
        params = self.params_negativeGrayspots
        _grayCircle_ (self.conn.cursor(), 'img1', 'testdata/test', params)

    def test_grayMasked__sizemap (self):
        params = self.params_negativeGrayspots
        params['size_map_path'] = 'testdata/mapSize.tiff'
        params['relpath'] = '.'
        _grayMasked_ (self.conn.cursor(), 'img1', 'testdata/test', params)

    def test_grayMasked__width (self):
        params = self.params_negativeGrayspots
        params['width'] = 40  # cars are assumed all to be of this width
        _grayMasked_ (self.conn.cursor(), 'img1', 'testdata/test', params)

    def test_negativeGrayspots_mask_sizemap (self):
        ' Check output database after default parameters '
        c = self.conn.cursor()
        params = self.params_negativeGrayspots
        params['size_map_path'] = 'testdata/mapSize.tiff'
        params['relpath'] = '.'
        negativeGrayspots (c, 'testdata/test', params)
        shutil.rmtree('testdata/test')
        # check output db
        c.execute ('SELECT COUNT(*) FROM cars')
        self.assertEqual (c.fetchone()[0], 0)
        c.execute ('SELECT COUNT(*) FROM matches')
        self.assertEqual (c.fetchone()[0], 0)
        c.execute ('SELECT COUNT(*) FROM images')
        self.assertEqual (c.fetchone()[0], 3)
        c.execute ('SELECT imagefile FROM images')
        imagefiles = c.fetchall()
        self.assertEqual (imagefiles[0][0], 'testdata/test/img1')
        self.assertEqual (imagefiles[1][0], 'testdata/test/img2')
        self.assertEqual (imagefiles[2][0], 'testdata/test/img3')

    def test_negativeGrayspots_circle (self):
        params = self.params_negativeGrayspots
        params['method'] = 'circle'
        params['relpath'] = '.'
        negativeGrayspots (self.conn.cursor(), 'testdata/test', params)
        shutil.rmtree('testdata/test')

    def test_negativeGrayspots_badmethod (self):
        params = self.params_negativeGrayspots
        params['method'] = 'bad_method'
        params['relpath'] = '.'
        with self.assertRaises(Exception):
            negativeGrayspots (self.conn.cursor(), 'testdata/test', params)
        shutil.rmtree('testdata/test')

    # _getBboxesFromImage_

    def test_getBboxesFromImage__ (self):
        image = np.random.random ((100, 100, 3))
        bboxes = _getBboxesFromImage_ (image, 50, {})
        self.assertIsInstance (bboxes, list)
        self.assertEqual (len(bboxes), 50)
        self.assertIsInstance (bboxes[0], tuple)
        self.assertEqual (len(bboxes[0]), 4)

    def test_getBboxesFromImage__mask (self):
        # generate a 2x2 checkerboard
        mask = np.zeros ((100, 100), dtype=np.uint8)
        mask[0:50, 0:50] = 255
        mask[50:100, 50:100] = 255
        # run _getBboxesFromImage_
        image = np.random.random ((100, 100, 3))
        bboxes = _getBboxesFromImage_ (image, 50, {'mask': mask})
        self.assertIsInstance (bboxes, list)
        self.assertEqual (len(bboxes), 50)
        self.assertIsInstance (bboxes[0], tuple)
        self.assertEqual (len(bboxes[0]), 4)

    def test_getBboxesFromImage__nobboxes (self):
        ''' check that function return empty list when it's impossible to collect bboxes '''
        image = np.random.random ((100, 100, 3))
        bboxes = _getBboxesFromImage_ (image, 50, {'max_masked_perc': -0.1})
        self.assertIsInstance (bboxes, list)
        self.assertEqual (len(bboxes), 0)

    # fillNegativeDbWithBboxes

    def test_fillNegativeDbWithBboxes (self):
        c = self.conn.cursor()
        params = {'image_processor': self.imageProcessor, 'number': 50}
        fillNegativeDbWithBboxes (c, params)
        # check output db
        c.execute ('SELECT COUNT(*) FROM matches')
        self.assertEqual (c.fetchone()[0], 0)
        c.execute ('SELECT COUNT(*) FROM images')
        self.assertEqual (c.fetchone()[0], 3)
        c.execute ('SELECT COUNT(*) FROM cars')
        self.assertEqual (c.fetchone()[0], 50)
        c.execute ('SELECT COUNT(*) FROM cars WHERE imagefile == "img1"')
        self.assertGreater (c.fetchone()[0], 15)
        c.execute ('SELECT COUNT(*) FROM cars WHERE imagefile == "img2"')
        self.assertGreater (c.fetchone()[0], 15)
        c.execute ('SELECT COUNT(*) FROM cars WHERE imagefile == "img3"')
        self.assertGreater (c.fetchone()[0], 15)

    def test_fillNegativeDbWithBboxes_sizemap (self):
        c = self.conn.cursor()
        params = {'image_processor': self.imageProcessor, 'number': 50,
                  'size_map_path': 'testdata/mapSize.tiff', 'relpath': '.'}
        fillNegativeDbWithBboxes (c, params)
        c.execute ('SELECT COUNT(*) FROM cars')
        self.assertEqual (c.fetchone()[0], 50)

if __name__ == '__main__':
    logging.basicConfig (level=logging.ERROR)
    unittest.main()


#!/usr/bin/env python
from osgeo import ogr
from osgeo import osr
import os
import os.path
import shutil
from constants import EPSG_CODE

shutil.rmtree('cutlines', True)
os.mkdir('cutlines')

t_srs = osr.SpatialReference()
t_srs.ImportFromEPSG(EPSG_CODE)

features = {}
ds = ogr.Open('cutline-map.shp')
layer = ds.GetLayerByIndex(0)

t_driver = ogr.GetDriverByName('GeoJSON')

for feature in layer:
    trsid  = feature.GetField('imagefn')
    if trsid:
        features[trsid] = features.get(trsid, []) + [feature]

for trsid, feats in features.iteritems():
    t_ds = t_driver.CreateDataSource("cutlines/{0}.geojson".format(trsid))
    t_layer = t_ds.CreateLayer('tiles', t_srs, ogr.wkbMultiPolygon)

    t_feature = ogr.Feature(t_layer.GetLayerDefn())

    oldgeoms = [feature.GetGeometryRef() for feature in feats]
    geom = reduce(lambda x, y: x.Union(y), oldgeoms, ogr.Geometry(ogr.wkbMultiPolygon))

    t_feature.SetGeometry(geom)

    t_layer.CreateFeature(t_feature)

    t_ds.Destroy()


################################################################################
# Copyright (c) 2015-2019 Skymind, Inc.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License, Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
################################################################################

import pytest
from pydl4j import *

def test_get_artifacts():
    artifacts = get_artifacts('datavec')
    expected = ['datavec-api', 'datavec-local', 'datavec-parent']
    for e in expected:
        assert e in artifacts

def test_get_versions():
    versions = get_versions('datavec', 'datavec-api')
    assert len(versions) >= 12

def test_get_latest_version():
    v = get_latest_version('datavec', 'datavec-api')
    assert len(v) > 0

def test_install():
    set_context('test')
    clear_context()
    mvn_install('datavec', 'datavec-api')
    mvn_install('datavec', 'datavec-local')
    assert len(get_jars()) == 2
    for jar in get_jars():
        uninstall(jar)
    assert len(get_jars()) == 0
    clear_context()

if __name__ == '__main__':
    pytest.main([__file__])